mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
be5c889cdf
- Convert some notations to SAL2 - "Name" parameter in LdrGetProcedureAddress/LdrpGetProcedureAddress should be optional - "DllCharacteristics" parameter in LdrGetDllHandle should be optional
180 lines
5.4 KiB
C
180 lines
5.4 KiB
C
/*
|
|
* 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);
|
|
|
|
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)
|
|
{
|
|
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);
|
|
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;
|
|
}
|
|
|