windows-nt/Source/XPSP1/NT/base/win32/verifier/verifier.c
2020-09-26 16:20:57 +08:00

489 lines
12 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
verifier.c
Abstract:
This module implements the standard application verifier provider.
Author:
Silviu Calinoiu (SilviuC) 2-Feb-2001
Revision History:
--*/
//
// IMPORTANT NOTE.
//
// This dll cannot contain non-ntdll dependencies. This way it allows
// verifier to be run system wide including for processes like smss and csrss.
//
// SilviuC: we might decide in the future that it is not worth enforcing this
// restriction and we loose smss/csrss verification but we can do more stuff
// in the verifier dll.
//
#include "pch.h"
#include "verifier.h"
#include "support.h"
#include "settings.h"
//
// ntdll.dll thunks
//
RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpNtdllThunks [] =
{
{"NtAllocateVirtualMemory", NULL, AVrfpNtAllocateVirtualMemory},
{"NtFreeVirtualMemory", NULL, AVrfpNtFreeVirtualMemory},
{"NtMapViewOfSection", NULL, AVrfpNtMapViewOfSection},
{"NtUnmapViewOfSection", NULL, AVrfpNtUnmapViewOfSection},
{"NtCreateSection", NULL, AVrfpNtCreateSection},
{"NtOpenSection", NULL, AVrfpNtOpenSection},
{"NtCreateFile", NULL, AVrfpNtCreateFile},
{"NtOpenFile", NULL, AVrfpNtOpenFile},
{"RtlTryEnterCriticalSection", NULL, AVrfpRtlTryEnterCriticalSection},
{"RtlEnterCriticalSection", NULL, AVrfpRtlEnterCriticalSection},
{"RtlLeaveCriticalSection", NULL, AVrfpRtlLeaveCriticalSection},
{"RtlInitializeCriticalSection", NULL, AVrfpRtlInitializeCriticalSection},
{"RtlInitializeCriticalSectionAndSpinCount", NULL, AVrfpRtlInitializeCriticalSectionAndSpinCount},
{"RtlDeleteCriticalSection", NULL, AVrfpRtlDeleteCriticalSection},
{"NtCreateEvent", NULL, AVrfpNtCreateEvent },
{"NtClose", NULL, AVrfpNtClose},
{"RtlAllocateHeap", NULL, AVrfpRtlAllocateHeap },
{"RtlReAllocateHeap", NULL, AVrfpRtlReAllocateHeap },
{"RtlFreeHeap", NULL, AVrfpRtlFreeHeap },
// {"RtlQueueWorkItem", NULL, AVrfpRtlQueueWorkItem },
// ISSUE: silviuc: these two are tricky (callback can be called several times)
// {"RtlRegisterWait", NULL, AVrfpRtlRegisterWait },
// {"RtlCreateTimer", NULL, AVrfpRtlCreateTimer },
{NULL, NULL, NULL}
};
//
// kernel32.dll thunks
//
RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpKernel32Thunks [] =
{
{"HeapCreate", NULL, AVrfpHeapCreate},
{"HeapDestroy", NULL, AVrfpHeapDestroy},
{"CloseHandle", NULL, AVrfpCloseHandle},
{"ExitThread", NULL, AVrfpExitThread},
{"TerminateThread", NULL, AVrfpTerminateThread},
{"SuspendThread", NULL, AVrfpSuspendThread},
{"TlsAlloc", NULL, AVrfpTlsAlloc},
{"TlsFree", NULL, AVrfpTlsFree},
{"TlsGetValue", NULL, AVrfpTlsGetValue},
{"TlsSetValue", NULL, AVrfpTlsSetValue},
#if 0
{"CreateThread", NULL, AVrfpCreateThread},
#endif
{NULL, NULL, NULL}
};
//
// advapi32.dll thunks
//
RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpAdvapi32Thunks [] =
{
{"RegCreateKeyExW", NULL, AVrfpRegCreateKeyExW},
{NULL, NULL, NULL}
};
//
// msvcrt.dll thunks
//
RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpMsvcrtThunks [] =
{
{"malloc", NULL, AVrfp_malloc},
{"calloc", NULL, AVrfp_calloc},
{"realloc", NULL, AVrfp_realloc},
{"free", NULL, AVrfp_free},
{"??2@YAPAXI@Z", NULL, AVrfp_new},
{"??3@YAXPAX@Z", NULL, AVrfp_delete},
{"??_U@YAPAXI@Z", NULL, AVrfp_newarray},
{"??_V@YAXPAX@Z", NULL, AVrfp_deletearray},
{NULL, NULL, NULL}
};
//
// dll's providing thunks verified.
//
RTL_VERIFIER_DLL_DESCRIPTOR AVrfpExportDlls [] =
{
{L"ntdll.dll", 0, NULL, AVrfpNtdllThunks},
{L"kernel32.dll", 0, NULL, AVrfpKernel32Thunks},
{L"advapi32.dll", 0, NULL, AVrfpAdvapi32Thunks},
{L"msvcrt.dll", 0, NULL, AVrfpMsvcrtThunks},
{NULL, 0, NULL, NULL}
};
RTL_VERIFIER_PROVIDER_DESCRIPTOR AVrfpProvider =
{
sizeof (RTL_VERIFIER_PROVIDER_DESCRIPTOR),
AVrfpExportDlls,
NULL, // not interested in Dll load notifications
NULL, // not interested in Dll unload notifications
NULL, // image name (filled by verifier engine)
0, // verifier flags (filled by verifier engine)
0, // debug flags (filled by verifier engine)
};
//
// Mark if we have been called with PROCESS_ATTACH once.
// In some cases the fusion code loads dynamically kernel32.dll and enforces
// the run of all initialization routines and causes us to get called
// twice.
//
BOOL AVrfpProcessAttachCalled;
BOOL
WINAPI
DllMain(
HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
switch (fdwReason) {
case DLL_PROCESS_VERIFIER:
//
// DllMain gets called with this special reason by the verifier engine.
// No code should execute here except passing back the provider
// descriptor.
//
if (lpvReserved) {
*((PRTL_VERIFIER_PROVIDER_DESCRIPTOR *)lpvReserved) = &AVrfpProvider;
}
break;
case DLL_PROCESS_ATTACH:
//
// Execute only minimal code here and avoid too many DLL dependencies.
//
if (! AVrfpProcessAttachCalled) {
AVrfpProcessAttachCalled = TRUE;
if (AVrfpProvider.VerifierImage) {
try {
HandleInitialize();
}
except (EXCEPTION_EXECUTE_HANDLER) {
return FALSE;
}
DbgPrint ("AVRF: verifier.dll provider initialized for %ws with flags 0x%X \n",
AVrfpProvider.VerifierImage,
AVrfpProvider.VerifierFlags);
}
}
break;
default:
break;
}
return TRUE;
}
PRTL_VERIFIER_THUNK_DESCRIPTOR
AVrfpGetThunkDescriptor (
PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks,
ULONG Index)
{
PRTL_VERIFIER_THUNK_DESCRIPTOR Thunk = NULL;
Thunk = &(DllThunks[Index]);
if (Thunk->ThunkNewAddress == NULL) {
// silviuc: delete
DbgPrint ("AVRF: we do not have a replace for %s !!! \n",
Thunk->ThunkName);
DbgBreakPoint ();
}
return Thunk;
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////// msvcrt.dll verified exports
/////////////////////////////////////////////////////////////////////
LONG AVrfpKernel32Count[8];
//WINBASEAPI
HANDLE
WINAPI
AVrfpHeapCreate(
IN DWORD flOptions,
IN SIZE_T dwInitialSize,
IN SIZE_T dwMaximumSize
)
{
typedef HANDLE (WINAPI * FUNCTION_TYPE) (DWORD, SIZE_T, SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_HEAPCREATE);
InterlockedIncrement (&(AVrfpKernel32Count[0]));
return (* Function)(flOptions, dwInitialSize, dwMaximumSize);
}
//WINBASEAPI
BOOL
WINAPI
AVrfpHeapDestroy(
IN OUT HANDLE hHeap
)
{
typedef BOOL (WINAPI * FUNCTION_TYPE) (HANDLE);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_HEAPDESTROY);
InterlockedIncrement (&(AVrfpKernel32Count[1]));
return (* Function)(hHeap);
}
//WINBASEAPI
BOOL
WINAPI
AVrfpCloseHandle(
IN OUT HANDLE hObject
)
{
typedef BOOL (WINAPI * FUNCTION_TYPE) (HANDLE);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_CLOSEHANDLE);
InterlockedIncrement (&(AVrfpKernel32Count[2]));
return (* Function)(hObject);
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////// msvcrt.dll verified exports
/////////////////////////////////////////////////////////////////////
LONG AVrfpAdvapi32Count[8];
//WINADVAPI
LONG
APIENTRY
AVrfpRegCreateKeyExW (
IN HKEY hKey,
IN LPCWSTR lpSubKey,
IN DWORD Reserved,
IN LPWSTR lpClass,
IN DWORD dwOptions,
IN REGSAM samDesired,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
OUT PHKEY phkResult,
OUT LPDWORD lpdwDisposition
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD,
REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGCREATEKEYEXW);
InterlockedIncrement (&(AVrfpAdvapi32Count[0]));
return (* Function) (hKey,
lpSubKey,
Reserved,
lpClass,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////// msvcrt.dll verified exports
/////////////////////////////////////////////////////////////////////
LONG AVrfpMsvcrtCount[8];
PVOID __cdecl
AVrfp_malloc (
IN SIZE_T Size
)
{
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_MALLOC);
InterlockedIncrement (&(AVrfpMsvcrtCount[0]));
return (* Function)(Size);
}
PVOID __cdecl
AVrfp_calloc (
IN SIZE_T Number,
IN SIZE_T Size
)
{
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T, SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_CALLOC);
InterlockedIncrement (&(AVrfpMsvcrtCount[1]));
return (* Function)(Number, Size);
}
PVOID __cdecl
AVrfp_realloc (
IN PVOID Address,
IN SIZE_T Size
)
{
typedef PVOID (__cdecl * FUNCTION_TYPE) (PVOID, SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_REALLOC);
InterlockedIncrement (&(AVrfpMsvcrtCount[2]));
return (* Function)(Address, Size);
}
VOID __cdecl
AVrfp_free (
IN PVOID Address
)
{
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_FREE);
InterlockedIncrement (&(AVrfpMsvcrtCount[3]));
(* Function)(Address);
}
PVOID __cdecl
AVrfp_new (
IN SIZE_T Size
)
{
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_NEW);
InterlockedIncrement (&(AVrfpMsvcrtCount[4]));
return (* Function)(Size);
}
VOID __cdecl
AVrfp_delete (
IN PVOID Address
)
{
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_DELETE);
InterlockedIncrement (&(AVrfpMsvcrtCount[5]));
(* Function)(Address);
}
PVOID __cdecl
AVrfp_newarray (
IN SIZE_T Size
)
{
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_NEWARRAY);
InterlockedIncrement (&(AVrfpMsvcrtCount[6]));
return (* Function)(Size);
}
VOID __cdecl
AVrfp_deletearray (
IN PVOID Address
)
{
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
AVRF_INDEX_MSVCRT_DELETEARRAY);
InterlockedIncrement (&(AVrfpMsvcrtCount[7]));
(* Function)(Address);
}