reactos/dll/win32/verifier/verifier.c

181 lines
5.4 KiB
C
Raw Normal View History

2018-04-26 22:05:21 +00:00
/*
* PROJECT: Application verifier
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Main entrypoint
* COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
*/
#include <ndk/rtlfuncs.h>
#include <reactos/verifier.h>
#if 0
#define PROVIDER_PREFIX "AVRF"
#else
#define PROVIDER_PREFIX "RVRF"
#endif
VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
VOID NTAPI AVrfpNtdllHeapFreeCallback(PVOID AllocationBase, SIZE_T AllocationSize);
// DPFLTR_VERIFIER_ID
NTSTATUS
NTAPI
AVrfpLdrGetProcedureAddress(
_In_ PVOID BaseAddress,
_In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name,
_In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
_Out_ PVOID *ProcedureAddress);
2018-04-26 22:05:21 +00:00
static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpNtdllThunks[] =
{
{ "LdrGetProcedureAddress", NULL, AVrfpLdrGetProcedureAddress },
{ NULL }
};
FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName);
static RTL_VERIFIER_THUNK_DESCRIPTOR AVrfpKernel32Thunks[] =
{
{ "GetProcAddress", NULL, AVrfpGetProcAddress },
{ NULL }
};
static RTL_VERIFIER_DLL_DESCRIPTOR AVrfpDllDescriptors[] =
{
{ L"ntdll.dll", 0, NULL, AVrfpNtdllThunks },
{ L"kernel32.dll", 0, NULL, AVrfpKernel32Thunks },
{ NULL }
};
RTL_VERIFIER_PROVIDER_DESCRIPTOR AVrfpProvider =
{
/*.Length =*/ sizeof(AVrfpProvider),
/*.ProviderDlls =*/ AVrfpDllDescriptors,
/*.ProviderDllLoadCallback =*/ AVrfpDllLoadCallback,
/*.ProviderDllUnloadCallback =*/ AVrfpDllUnloadCallback,
/*.VerifierImage =*/ NULL,
/*.VerifierFlags =*/ 0,
/*.VerifierDebug =*/ 0,
/*.RtlpGetStackTraceAddress =*/ NULL,
/*.RtlpDebugPageHeapCreate =*/ NULL,
/*.RtlpDebugPageHeapDestroy =*/ NULL,
/*.ProviderNtdllHeapFreeCallback =*/ AVrfpNtdllHeapFreeCallback
};
BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_VERIFIER:
*(PRTL_VERIFIER_PROVIDER_DESCRIPTOR*)lpReserved = &AVrfpProvider;
break;
}
return TRUE;
}
VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
{
PLDR_DATA_TABLE_ENTRY LdrEntry = (PLDR_DATA_TABLE_ENTRY)Reserved;
DbgPrint(PROVIDER_PREFIX ": %ws @ %p: ep: %p\n", DllName, DllBase, LdrEntry->EntryPoint);
/* TODO: Hook entrypoint */
}
VOID NTAPI AVrfpDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
{
DbgPrint(PROVIDER_PREFIX ": unloading %ws\n", DllName);
}
VOID NTAPI AVrfpNtdllHeapFreeCallback(PVOID AllocationBase, SIZE_T AllocationSize)
{
DbgPrint(PROVIDER_PREFIX ": Heap free 0x%x @ %p\n", AllocationSize, AllocationBase);
/* TODO: Sanity checks */
}
PVOID AVrfpFindReplacementThunk(PVOID Proc)
{
PRTL_VERIFIER_DLL_DESCRIPTOR DllDescriptor;
PRTL_VERIFIER_THUNK_DESCRIPTOR ThunkDescriptor;
for (DllDescriptor = AVrfpDllDescriptors; DllDescriptor->DllName; ++DllDescriptor)
{
for (ThunkDescriptor = DllDescriptor->DllThunks; ThunkDescriptor->ThunkName; ++ThunkDescriptor)
{
if (ThunkDescriptor->ThunkOldAddress == Proc)
{
return ThunkDescriptor->ThunkNewAddress;
}
}
}
return Proc;
}
NTSTATUS NTAPI
AVrfpLdrGetProcedureAddress(
_In_ PVOID BaseAddress,
_In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name,
_In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
_Out_ PVOID *ProcedureAddress)
2018-04-26 22:05:21 +00:00
{
NTSTATUS(NTAPI *oLdrGetProcedureAddress)(
_In_ PVOID BaseAddress,
_In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name,
_In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
_Out_ PVOID *ProcedureAddress);
2018-04-26 22:05:21 +00:00
NTSTATUS Status;
PVOID Replacement;
oLdrGetProcedureAddress = AVrfpNtdllThunks[0].ThunkOldAddress;
Status = oLdrGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress);
if (!NT_SUCCESS(Status))
return Status;
Replacement = AVrfpFindReplacementThunk(*ProcedureAddress);
if (Replacement != *ProcedureAddress)
{
*ProcedureAddress = Replacement;
if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS)
DbgPrint(PROVIDER_PREFIX ": AVrfpLdrGetProcedureAddress (%p, %Z) -> thunk address %p\n", BaseAddress, Name, *ProcedureAddress);
}
return Status;
}
FARPROC WINAPI AVrfpGetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName)
{
FARPROC (WINAPI* oGetProcAddress)(IN HMODULE hModule, IN LPCSTR lpProcName);
FARPROC Proc, Replacement;
if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_LOGCALLS)
DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s)\n", hModule, lpProcName);
oGetProcAddress = AVrfpKernel32Thunks[0].ThunkOldAddress;
Proc = oGetProcAddress(hModule, lpProcName);
if (!Proc)
return Proc;
Replacement = AVrfpFindReplacementThunk(Proc);
if (Replacement != Proc)
{
Proc = Replacement;
if (AVrfpProvider.VerifierDebug & RTL_VRF_DBG_VERIFIER_SHOWDYNTHUNKS)
DbgPrint(PROVIDER_PREFIX ": AVrfpGetProcAddress (%p, %s) -> thunk address %p\n", hModule, lpProcName, Proc);
}
return Proc;
}