1 /* 2 * PROJECT: Application verifier 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Main entrypoint 5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <ndk/rtlfuncs.h> 9 #include <reactos/verifier.h> 10 11 #if 0 12 #define PROVIDER_PREFIX "AVRF" 13 #else 14 #define PROVIDER_PREFIX "RVRF" 15 #endif 16 17 18 VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved); 19 VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved); 20 VOID NTAPI AVrfpNtdllHeapFreeCallback(PVOID AllocationBase, SIZE_T AllocationSize); 21 22 // DPFLTR_VERIFIER_ID 23 24 25 NTSTATUS NTAPI AVrfpLdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress); 26 27 static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpNtdllThunks[] = 28 { 29 { "LdrGetProcedureAddress", NULL, AVrfpLdrGetProcedureAddress }, 30 { NULL } 31 }; 32 33 FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName); 34 35 static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpKernel32Thunks[] = 36 { 37 { "GetProcAddress", NULL, AVrfpGetProcAddress }, 38 { NULL } 39 }; 40 41 static RTL_VERIFIER_DLL_DESCRIPTOR AVrfpDllDescriptors[] = 42 { 43 { L"ntdll.dll", 0, NULL, AVrfpNtdllThunks }, 44 { L"kernel32.dll", 0, NULL, AVrfpKernel32Thunks }, 45 { NULL } 46 }; 47 48 RTL_VERIFIER_PROVIDER_DESCRIPTOR AVrfpProvider = 49 { 50 /*.Length =*/ sizeof(AVrfpProvider), 51 /*.ProviderDlls =*/ AVrfpDllDescriptors, 52 /*.ProviderDllLoadCallback =*/ AVrfpDllLoadCallback, 53 /*.ProviderDllUnloadCallback =*/ AVrfpDllUnloadCallback, 54 /*.VerifierImage =*/ NULL, 55 /*.VerifierFlags =*/ 0, 56 /*.VerifierDebug =*/ 0, 57 /*.RtlpGetStackTraceAddress =*/ NULL, 58 /*.RtlpDebugPageHeapCreate =*/ NULL, 59 /*.RtlpDebugPageHeapDestroy =*/ NULL, 60 /*.ProviderNtdllHeapFreeCallback =*/ AVrfpNtdllHeapFreeCallback 61 }; 62 63 64 65 BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved) 66 { 67 switch (dwReason) 68 { 69 case DLL_PROCESS_ATTACH: 70 case DLL_PROCESS_DETACH: 71 case DLL_THREAD_ATTACH: 72 case DLL_THREAD_DETACH: 73 break; 74 case DLL_PROCESS_VERIFIER: 75 *(PRTL_VERIFIER_PROVIDER_DESCRIPTOR*)lpReserved = &AVrfpProvider; 76 break; 77 } 78 return TRUE; 79 } 80 81 VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved) 82 { 83 PLDR_DATA_TABLE_ENTRY LdrEntry = (PLDR_DATA_TABLE_ENTRY)Reserved; 84 DbgPrint(PROVIDER_PREFIX ": %ws @ %p: ep: %p\n", DllName, DllBase, LdrEntry->EntryPoint); 85 /* TODO: Hook entrypoint */ 86 } 87 88 89 VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved) 90 { 91 DbgPrint(PROVIDER_PREFIX ": unloading %ws\n", DllName); 92 } 93 94 VOID NTAPI AVrfpNtdllHeapFreeCallback(PVOID AllocationBase, SIZE_T AllocationSize) 95 { 96 DbgPrint(PROVIDER_PREFIX ": Heap free 0x%x @ %p\n", AllocationSize, AllocationBase); 97 /* TODO: Sanity checks */ 98 } 99 100 PVOID AVrfpFindReplacementThunk(PVOID Proc) 101 { 102 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 103 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 104 105 for (DllDescriptor = AVrfpDllDescriptors; DllDescriptor->DllName; ++DllDescriptor) 106 { 107 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor->ThunkName; ++ThunkDescriptor) 108 { 109 if (ThunkDescriptor->ThunkOldAddress == Proc) 110 { 111 return ThunkDescriptor->ThunkNewAddress; 112 } 113 } 114 } 115 return Proc; 116 } 117 118 119 NTSTATUS NTAPI AVrfpLdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress) 120 { 121 NTSTATUS (NTAPI *oLdrGetProcedureAddress)(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress); 122 NTSTATUS Status; 123 PVOID Replacement; 124 125 oLdrGetProcedureAddress = AVrfpNtdllThunks[0].ThunkOldAddress; 126 127 Status = oLdrGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress); 128 if (!NT_SUCCESS(Status)) 129 return Status; 130 131 Replacement = AVrfpFindReplacementThunk(*ProcedureAddress); 132 if (Replacement != *ProcedureAddress) 133 { 134 *ProcedureAddress = Replacement; 135 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS) 136 DbgPrint(PROVIDER_PREFIX ": AVrfpLdrGetProcedureAddress (%p, %Z) -> thunk address %p\n", BaseAddress, Name, *ProcedureAddress); 137 } 138 139 return Status; 140 } 141 142 FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName) 143 { 144 FARPROC (WINAPI* oGetProcAddress)(IN HMODULE hModule, IN LPCSTR lpProcName); 145 FARPROC Proc, Replacement; 146 147 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_LOGCALLS) 148 DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s)\n", hModule, lpProcName); 149 150 oGetProcAddress = AVrfpKernel32Thunks[0].ThunkOldAddress; 151 Proc = oGetProcAddress(hModule, lpProcName); 152 if (!Proc) 153 return Proc; 154 155 Replacement = AVrfpFindReplacementThunk(Proc); 156 if (Replacement != Proc) 157 { 158 Proc = Replacement; 159 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS) 160 DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s) -> thunk address %p\n", hModule, lpProcName, Proc); 161 } 162 163 return Proc; 164 } 165 166