|
|
/*++
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); }
|