/* VerifierDll example: * https://docs.microsoft.com/en-us/archive/blogs/reiley/a-debugging-approach-to-application-verifier * * Hooking example: * https://github.com/ionescu007/HookingNirvana/blob/master/verif.dll/verif.c * * * To use: * New subkey: HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\whatever.exe * GlobalGlag REG_DWORD 256 (0x00000100) * VerifierDlls REG_SZ whatever.dll * * "whatever.dll" must be placed into System32 folder * running "whatever.exe" will now import this DLL whenever it is run. * * This works on XP -> 10 */ #include #include "verifier.h" typedef BOOL (WINAPI* PCLOSE_HANDLE)(HANDLE); BOOL WINAPI CloseHandleHook(HANDLE hObject); /* Thunks https://en.wikipedia.org/wiki/Thunk */ /* Hook functions here. */ static RTL_VERIFIER_THUNK_DESCRIPTOR aThunks[] = { { "CloseHandle", NULL, (PVOID)(ULONG_PTR)CloseHandleHook}, {NULL, NULL, NULL} }; static RTL_VERIFIER_DLL_DESCRIPTOR atDLLs[] = { { L"kernel32.dll", 0, NULL, aThunks}, // CloseHandle() {NULL, 0, NULL, NULL} }; static RTL_VERIFIER_PROVIDER_DESCRIPTOR tVpd = { sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR), atDLLs }; /* CloseHandle() hook. This creates a file for demonstration purposes. */ BOOL WINAPI CloseHandleHook(HANDLE hObject) { HANDLE h; BOOL fRetVal = ((PCLOSE_HANDLE)(ULONG_PTR)(aThunks[0].ThunkOldAddress))(hObject); h = CreateFile("C:\\users\\dmfr\\foo\\hooked.txt", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(h); return fRetVal; } /* This will run calc.exe when this verifierdll is loaded for demonstration purposes. */ void ModuleLoaded(void) { STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; CreateProcess("c:\\windows\\system32\\calc.exe", "", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo); } BOOL ProcessVerifier(IN PVOID lpReserved) { *((PRTL_VERIFIER_PROVIDER_DESCRIPTOR *)lpReserved) = &tVpd; CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ModuleLoaded, 0, 0, 0); return TRUE; } /* DllMain() - Entry point. */ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved) { HANDLE h; UNREFERENCED_PARAMETER(hModule); switch (fdwReason) { case DLL_PROCESS_VERIFIER: /* Create a file to demonstrate that the DLL has loaded. */ h = CreateFile("C:\\users\\dmfr\\foo\\opened.txt", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(h); return ProcessVerifier(lpReserved); case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }