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 26 NTAPI 27 AVrfpLdrGetProcedureAddress( 28 _In_ PVOID BaseAddress, 29 _In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name, 30 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal, 31 _Out_ PVOID *ProcedureAddress); 32 33 static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpNtdllThunks[] = 34 { 35 { "LdrGetProcedureAddress", NULL, AVrfpLdrGetProcedureAddress }, 36 { NULL } 37 }; 38 39 FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName); 40 41 static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpKernel32Thunks[] = 42 { 43 { "GetProcAddress", NULL, AVrfpGetProcAddress }, 44 { NULL } 45 }; 46 47 static RTL_VERIFIER_DLL_DESCRIPTOR AVrfpDllDescriptors[] = 48 { 49 { L"ntdll.dll", 0, NULL, AVrfpNtdllThunks }, 50 { L"kernel32.dll", 0, NULL, AVrfpKernel32Thunks }, 51 { NULL } 52 }; 53 54 RTL_VERIFIER_PROVIDER_DESCRIPTOR AVrfpProvider = 55 { 56 /*.Length =*/ sizeof(AVrfpProvider), 57 /*.ProviderDlls =*/ AVrfpDllDescriptors, 58 /*.ProviderDllLoadCallback =*/ AVrfpDllLoadCallback, 59 /*.ProviderDllUnloadCallback =*/ AVrfpDllUnloadCallback, 60 /*.VerifierImage =*/ NULL, 61 /*.VerifierFlags =*/ 0, 62 /*.VerifierDebug =*/ 0, 63 /*.RtlpGetStackTraceAddress =*/ NULL, 64 /*.RtlpDebugPageHeapCreate =*/ NULL, 65 /*.RtlpDebugPageHeapDestroy =*/ NULL, 66 /*.ProviderNtdllHeapFreeCallback =*/ AVrfpNtdllHeapFreeCallback 67 }; 68 69 70 71 BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved) 72 { 73 switch (dwReason) 74 { 75 case DLL_PROCESS_ATTACH: 76 case DLL_PROCESS_DETACH: 77 case DLL_THREAD_ATTACH: 78 case DLL_THREAD_DETACH: 79 break; 80 case DLL_PROCESS_VERIFIER: 81 *(PRTL_VERIFIER_PROVIDER_DESCRIPTOR*)lpReserved = &AVrfpProvider; 82 break; 83 } 84 return TRUE; 85 } 86 87 VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved) 88 { 89 PLDR_DATA_TABLE_ENTRY LdrEntry = (PLDR_DATA_TABLE_ENTRY)Reserved; 90 DbgPrint(PROVIDER_PREFIX ": %ws @ %p: ep: %p\n", DllName, DllBase, LdrEntry->EntryPoint); 91 /* TODO: Hook entrypoint */ 92 } 93 94 95 VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved) 96 { 97 DbgPrint(PROVIDER_PREFIX ": unloading %ws\n", DllName); 98 } 99 100 VOID NTAPI AVrfpNtdllHeapFreeCallback(PVOID AllocationBase, SIZE_T AllocationSize) 101 { 102 DbgPrint(PROVIDER_PREFIX ": Heap free 0x%x @ %p\n", AllocationSize, AllocationBase); 103 /* TODO: Sanity checks */ 104 } 105 106 PVOID AVrfpFindReplacementThunk(PVOID Proc) 107 { 108 PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor; 109 PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor; 110 111 for (DllDescriptor = AVrfpDllDescriptors; DllDescriptor->DllName; ++DllDescriptor) 112 { 113 for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor->ThunkName; ++ThunkDescriptor) 114 { 115 if (ThunkDescriptor->ThunkOldAddress == Proc) 116 { 117 return ThunkDescriptor->ThunkNewAddress; 118 } 119 } 120 } 121 return Proc; 122 } 123 124 125 NTSTATUS NTAPI 126 AVrfpLdrGetProcedureAddress( 127 _In_ PVOID BaseAddress, 128 _In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name, 129 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal, 130 _Out_ PVOID *ProcedureAddress) 131 { 132 NTSTATUS(NTAPI *oLdrGetProcedureAddress)( 133 _In_ PVOID BaseAddress, 134 _In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name, 135 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal, 136 _Out_ PVOID *ProcedureAddress); 137 NTSTATUS Status; 138 PVOID Replacement; 139 140 oLdrGetProcedureAddress = AVrfpNtdllThunks[0].ThunkOldAddress; 141 142 Status = oLdrGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress); 143 if (!NT_SUCCESS(Status)) 144 return Status; 145 146 Replacement = AVrfpFindReplacementThunk(*ProcedureAddress); 147 if (Replacement != *ProcedureAddress) 148 { 149 *ProcedureAddress = Replacement; 150 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS) 151 DbgPrint(PROVIDER_PREFIX ": AVrfpLdrGetProcedureAddress (%p, %Z) -> thunk address %p\n", BaseAddress, Name, *ProcedureAddress); 152 } 153 154 return Status; 155 } 156 157 FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName) 158 { 159 FARPROC (WINAPI* oGetProcAddress)(IN HMODULE hModule, IN LPCSTR lpProcName); 160 FARPROC Proc, Replacement; 161 162 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_LOGCALLS) 163 DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s)\n", hModule, lpProcName); 164 165 oGetProcAddress = AVrfpKernel32Thunks[0].ThunkOldAddress; 166 Proc = oGetProcAddress(hModule, lpProcName); 167 if (!Proc) 168 return Proc; 169 170 Replacement = AVrfpFindReplacementThunk(Proc); 171 if (Replacement != Proc) 172 { 173 Proc = Replacement; 174 if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS) 175 DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s) -> thunk address %p\n", hModule, lpProcName, Proc); 176 } 177 178 return Proc; 179 } 180 181