xref: /reactos/dll/win32/verifier/verifier.c (revision 8a978a17)
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