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
DllMain(HANDLE hInstance,DWORD dwReason,LPVOID lpReserved)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
AVrfpDllLoadCallback(PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved)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
AVrfpDllUnloadCallback(PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved)95 VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
96 {
97 DbgPrint(PROVIDER_PREFIX ": unloading %ws\n", DllName);
98 }
99
AVrfpNtdllHeapFreeCallback(PVOID AllocationBase,SIZE_T AllocationSize)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
AVrfpFindReplacementThunk(PVOID Proc)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
AVrfpGetProcAddress(IN HMODULE hModule,IN LPCSTR lpProcName)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