https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ad8a2edd850c507338e9fe...
commit ad8a2edd850c507338e9fe9ef186a83a81d14a44 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Fri Apr 27 00:05:21 2018 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Sat May 12 13:35:09 2018 +0200
[VERIFIER] Add skeleton provider. --- dll/win32/CMakeLists.txt | 1 + dll/win32/verifier/CMakeLists.txt | 12 +++ dll/win32/verifier/verifier.c | 165 ++++++++++++++++++++++++++++++ dll/win32/verifier/verifier.spec | 19 ++++ dll/win32/verifier/verifier_customstubs.c | 143 ++++++++++++++++++++++++++ 5 files changed, 340 insertions(+)
diff --git a/dll/win32/CMakeLists.txt b/dll/win32/CMakeLists.txt index e4639acf65..9906d76c9c 100644 --- a/dll/win32/CMakeLists.txt +++ b/dll/win32/CMakeLists.txt @@ -222,6 +222,7 @@ add_subdirectory(userenv) add_subdirectory(usp10) add_subdirectory(uxtheme) add_subdirectory(vbscript) +add_subdirectory(verifier) add_subdirectory(version) add_subdirectory(vssapi) add_subdirectory(wbemdisp) diff --git a/dll/win32/verifier/CMakeLists.txt b/dll/win32/verifier/CMakeLists.txt new file mode 100644 index 0000000000..d41a850cdb --- /dev/null +++ b/dll/win32/verifier/CMakeLists.txt @@ -0,0 +1,12 @@ + +spec2def(verifier.dll verifier.spec) + +list(APPEND SOURCE + verifier.c + verifier_customstubs.c + ${CMAKE_CURRENT_BINARY_DIR}/verifier.def) + +add_library(verifier SHARED ${SOURCE}) +set_module_type(verifier win32dll UNICODE ENTRYPOINT DllMain 12) +add_importlibs(verifier ntdll) +add_cd_file(TARGET verifier DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/verifier/verifier.c b/dll/win32/verifier/verifier.c new file mode 100644 index 0000000000..5c24bd5104 --- /dev/null +++ b/dll/win32/verifier/verifier.c @@ -0,0 +1,165 @@ +/* + * 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 PANSI_STRING Name, IN 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 PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress) +{ + NTSTATUS (NTAPI *oLdrGetProcedureAddress)(IN PVOID BaseAddress, IN PANSI_STRING Name, IN 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; +} + diff --git a/dll/win32/verifier/verifier.spec b/dll/win32/verifier/verifier.spec new file mode 100644 index 0000000000..03d81b8b69 --- /dev/null +++ b/dll/win32/verifier/verifier.spec @@ -0,0 +1,19 @@ +# Do not add stubs here! + +@ stdcall VerifierAddFreeMemoryCallback(ptr) # stub +@ stdcall VerifierCreateRpcPageHeap(ptr ptr ptr ptr ptr ptr) # stub +@ stdcall VerifierDeleteFreeMemoryCallback(ptr) # stub +@ stdcall VerifierDestroyRpcPageHeap(ptr) # stub +@ stdcall VerifierDisableFaultInjectionExclusionRange(ptr) # stub +@ stdcall VerifierDisableFaultInjectionTargetRange(ptr) # stub +@ stdcall VerifierEnableFaultInjectionExclusionRange(ptr ptr) # stub +@ stdcall VerifierEnableFaultInjectionTargetRange(ptr ptr) # stub +@ stdcall VerifierEnumerateResource(ptr ptr ptr ptr ptr) # stub +@ stdcall VerifierIsCurrentThreadHoldingLocks() # stub +@ stdcall VerifierIsDllEntryActive(ptr) # stub +@ cdecl VerifierLogMessage() # stub +@ stdcall VerifierQueryRuntimeFlags(ptr ptr) # stub +@ stdcall VerifierSetFaultInjectionProbability(ptr ptr) # stub +@ stdcall VerifierSetFlags(ptr ptr ptr) # stub +@ stdcall VerifierSetRuntimeFlags(ptr) # stub +@ stdcall VerifierStopMessage(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) # stub diff --git a/dll/win32/verifier/verifier_customstubs.c b/dll/win32/verifier/verifier_customstubs.c new file mode 100644 index 0000000000..20302b3549 --- /dev/null +++ b/dll/win32/verifier/verifier_customstubs.c @@ -0,0 +1,143 @@ +/* + * PROJECT: Application verifier + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Custom stubs, using only ntdll functions + * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) + */ + +#define WIN32_NO_STATUS +#include <ndk/rtlfuncs.h> + +#define EXCEPTION_WINE_STUB 0x80000100 + +#define __wine_spec_unimplemented_stub(module, function) \ +{ \ + EXCEPTION_RECORD ExceptionRecord = {0}; \ + ExceptionRecord.ExceptionRecord = NULL; \ + ExceptionRecord.ExceptionCode = EXCEPTION_WINE_STUB; \ + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; \ + ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)module; \ + ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)function; \ + ExceptionRecord.NumberParameters = 2; \ + RtlRaiseException(&ExceptionRecord); \ +} + +int NTAPI VerifierAddFreeMemoryCallback(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierAddFreeMemoryCallback(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierCreateRpcPageHeap(PVOID arg0, PVOID arg1, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5) +{ + DbgPrint("WARNING: calling stub VerifierCreateRpcPageHeap(%p, %p, %p, %p, %p, %p)\n", arg0, arg1, arg2, arg3, arg4, arg5); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierDeleteFreeMemoryCallback(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierDeleteFreeMemoryCallback(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierDestroyRpcPageHeap(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierDestroyRpcPageHeap(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierDisableFaultInjectionExclusionRange(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierDisableFaultInjectionExclusionRange(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierDisableFaultInjectionTargetRange(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierDisableFaultInjectionTargetRange(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierEnableFaultInjectionExclusionRange(PVOID arg0, PVOID arg1) +{ + DbgPrint("WARNING: calling stub VerifierEnableFaultInjectionExclusionRange(%p, %p)\n", arg0, arg1); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierEnableFaultInjectionTargetRange(PVOID arg0, PVOID arg1) +{ + DbgPrint("WARNING: calling stub VerifierEnableFaultInjectionTargetRange(%p, %p)\n", arg0, arg1); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierEnumerateResource(PVOID arg0, PVOID arg1, PVOID arg2, PVOID arg3, PVOID arg4) +{ + DbgPrint("WARNING: calling stub VerifierEnumerateResource(%p, %p, %p, %p, %p)\n", arg0, arg1, arg2, arg3, arg4); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierIsCurrentThreadHoldingLocks() +{ + DbgPrint("WARNING: calling stub VerifierIsCurrentThreadHoldingLocks()\n"); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierIsDllEntryActive(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierIsDllEntryActive(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int __cdecl VerifierLogMessage() +{ + DbgPrint("WARNING: calling stub VerifierLogMessage()\n"); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierQueryRuntimeFlags(PVOID arg0, PVOID arg1) +{ + DbgPrint("WARNING: calling stub VerifierQueryRuntimeFlags(%p, %p)\n", arg0, arg1); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierSetFaultInjectionProbability(PVOID arg0, PVOID arg1) +{ + DbgPrint("WARNING: calling stub VerifierSetFaultInjectionProbability(%p, %p)\n", arg0, arg1); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierSetFlags(PVOID arg0, PVOID arg1, PVOID arg2) +{ + DbgPrint("WARNING: calling stub VerifierSetFlags(%p, %p, %p)\n", arg0, arg1, arg2); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierSetRuntimeFlags(PVOID arg0) +{ + DbgPrint("WARNING: calling stub VerifierSetRuntimeFlags(%p)\n", arg0); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} + +int NTAPI VerifierStopMessage(PVOID arg0, PVOID arg1, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5, PVOID arg6, PVOID arg7, PVOID arg8, PVOID arg9) +{ + DbgPrint("WARNING: calling stub VerifierStopMessage(%p, %p, %p, %p, %p, %p, %p, %p, %p, %p)\n", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + __wine_spec_unimplemented_stub("verifier.dll", __FUNCTION__); + return 0; +} +