[VERIFIER] Add skeleton provider.
authorMark Jansen <mark.jansen@reactos.org>
Thu, 26 Apr 2018 22:05:21 +0000 (00:05 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Sat, 12 May 2018 11:35:09 +0000 (13:35 +0200)
dll/win32/CMakeLists.txt
dll/win32/verifier/CMakeLists.txt [new file with mode: 0644]
dll/win32/verifier/verifier.c [new file with mode: 0644]
dll/win32/verifier/verifier.spec [new file with mode: 0644]
dll/win32/verifier/verifier_customstubs.c [new file with mode: 0644]

index e4639ac..9906d76 100644 (file)
@@ -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 (file)
index 0000000..d41a850
--- /dev/null
@@ -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 (file)
index 0000000..5c24bd5
--- /dev/null
@@ -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 (file)
index 0000000..03d81b8
--- /dev/null
@@ -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 (file)
index 0000000..20302b3
--- /dev/null
@@ -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;
+}
+