From 80c4567edffe504df3e75f565001391f88fdac06 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sat, 4 Mar 2017 20:34:36 +0000 Subject: [PATCH] [NTDLL] Implement some basic shim engine integration. CORE-10368 svn path=/trunk/; revision=74064 --- reactos/dll/ntdll/include/ntdllp.h | 19 +++++++ reactos/dll/ntdll/ldr/ldrapi.c | 7 ++- reactos/dll/ntdll/ldr/ldrinit.c | 21 +++++--- reactos/dll/ntdll/ldr/ldrutils.c | 82 ++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 12 deletions(-) diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index 4b9db908760..8164a294c13 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -47,6 +47,13 @@ extern BOOLEAN LdrpShutdownInProgress; extern UNICODE_STRING LdrpKnownDllPath; extern PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache, LdrpLoadedDllHandleCache; extern ULONG RtlpDphGlobalFlags; +extern BOOLEAN g_ShimsEnabled; +extern PVOID g_pShimEngineModule; +extern PVOID g_pfnSE_DllLoaded; +extern PVOID g_pfnSE_DllUnloaded; +extern PVOID g_pfnSE_InstallBeforeInit; +extern PVOID g_pfnSE_InstallAfterInit; +extern PVOID g_pfnSE_ProcessDying; /* ldrinit.c */ NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); @@ -139,6 +146,18 @@ LdrpFetchAddressOfEntryPoint(PVOID ImageBase); VOID NTAPI LdrpFreeUnicodeString(PUNICODE_STRING String); +VOID NTAPI +LdrpGetShimEngineInterface(); + +VOID +NTAPI +LdrpLoadShimEngine(IN PWSTR ImageName, + IN PUNICODE_STRING ProcessImage, + IN PVOID pShimData); + +VOID NTAPI +LdrpUnloadShimEngine(); + /* FIXME: Cleanup this mess */ typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB); diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index 3414c6ec52c..c49be3deadd 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -1404,7 +1404,12 @@ LdrUnloadDll(IN PVOID BaseAddress) LdrEntry->EntryPoint); } - /* FIXME: Call Shim Engine and notify */ + /* Call Shim Engine and notify */ + if (g_ShimsEnabled) + { + VOID (NTAPI* SE_DllUnloaded)(PVOID) = RtlDecodeSystemPointer(g_pfnSE_DllUnloaded); + SE_DllUnloaded(LdrEntry); + } /* Unlink it */ CurrentEntry = LdrEntry; diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 71c224010cf..614c290ba9e 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -901,10 +901,12 @@ LdrShutdownProcess(VOID) if (LdrpShutdownInProgress) return STATUS_SUCCESS; /* Tell the Shim Engine */ - //if (ShimsEnabled) - //{ - /* FIXME */ - //} + if (g_ShimsEnabled) + { + VOID(NTAPI *SE_ProcessDying)(); + SE_ProcessDying = RtlDecodeSystemPointer(g_pfnSE_ProcessDying); + SE_ProcessDying(); + } /* Tell the world */ if (ShowSnaps) @@ -2110,8 +2112,7 @@ LdrpInitializeProcess(IN PCONTEXT Context, { /* Load the Shim Engine */ Peb->AppCompatInfo = NULL; - //LdrpLoadShimEngine(OldShimData, ImagePathName, OldShimData); - DPRINT1("We do not support shims yet\n"); + LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData); } else { @@ -2134,7 +2135,13 @@ LdrpInitializeProcess(IN PCONTEXT Context, return Status; } - /* FIXME: Unload the Shim Engine if it was loaded */ + /* Notify Shim Engine */ + if (g_ShimsEnabled) + { + VOID(NTAPI *SE_InstallAfterInit)(PUNICODE_STRING, PVOID); + SE_InstallAfterInit = RtlDecodeSystemPointer(g_pfnSE_InstallAfterInit); + SE_InstallAfterInit(&ImagePathName, OldShimData); + } /* Check if we have a user-defined Post Process Routine */ if (NT_SUCCESS(Status) && Peb->PostProcessInitRoutine) diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 84ab7bf3572..d960c7fcee1 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -17,7 +17,14 @@ /* GLOBALS *******************************************************************/ PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache, LdrpGetModuleHandleCache; + BOOLEAN g_ShimsEnabled; +PVOID g_pShimEngineModule; +PVOID g_pfnSE_DllLoaded; +PVOID g_pfnSE_DllUnloaded; +PVOID g_pfnSE_InstallBeforeInit; +PVOID g_pfnSE_InstallAfterInit; +PVOID g_pfnSE_ProcessDying; /* FUNCTIONS *****************************************************************/ @@ -2548,12 +2555,11 @@ LdrpLoadDll(IN BOOLEAN Redirected, /* If we have to run the entrypoint, make sure the DB is ready */ if (CallInit && LdrpLdrDatabaseIsSetup) { - /* FIXME: Notify Shim Engine */ + /* Notify Shim Engine */ if (g_ShimsEnabled) { - /* Call it */ - //ShimLoadCallback = RtlDecodeSystemPointer(g_pfnSE_DllLoaded); - //ShimLoadCallback(LdrEntry); + VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded); + SE_DllLoaded(LdrEntry); } /* Run the init routine */ @@ -2654,4 +2660,72 @@ LdrpClearLoadInProgress(VOID) return ModulesCount; } +PVOID LdrpGetShimEngineFunction(PCSZ FunctionName) +{ + ANSI_STRING Function; + NTSTATUS Status; + PVOID Address; + RtlInitAnsiString(&Function, FunctionName); + Status = LdrGetProcedureAddress(g_pShimEngineModule, &Function, 0, &Address); + return NT_SUCCESS(Status) ? Address : NULL; +} + +VOID +NTAPI +LdrpGetShimEngineInterface() +{ + PVOID SE_DllLoaded = LdrpGetShimEngineFunction("SE_DllLoaded"); + PVOID SE_DllUnloaded = LdrpGetShimEngineFunction("SE_DllUnloaded"); + PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit"); + PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit"); + PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying"); + + if (SE_DllLoaded && SE_DllUnloaded && SE_InstallBeforeInit && SE_InstallAfterInit && SE_ProcessDying) + { + g_pfnSE_DllLoaded = RtlEncodeSystemPointer(SE_DllLoaded); + g_pfnSE_DllUnloaded = RtlEncodeSystemPointer(SE_DllUnloaded); + g_pfnSE_InstallBeforeInit = RtlEncodeSystemPointer(SE_InstallBeforeInit); + g_pfnSE_InstallAfterInit = RtlEncodeSystemPointer(SE_InstallAfterInit); + g_pfnSE_ProcessDying = RtlEncodeSystemPointer(SE_ProcessDying); + g_ShimsEnabled = TRUE; + } + else + { + LdrpUnloadShimEngine(); + } +} + + +VOID +NTAPI +LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData) +{ + UNICODE_STRING ShimLibraryName; + PVOID ShimLibrary; + NTSTATUS Status; + RtlInitUnicodeString(&ShimLibraryName, ImageName); + Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, TRUE); + if (NT_SUCCESS(Status)) + { + g_pShimEngineModule = ShimLibrary; + LdrpGetShimEngineInterface(); + if (g_ShimsEnabled) + { + VOID(NTAPI *SE_InstallBeforeInit)(PUNICODE_STRING, PVOID); + SE_InstallBeforeInit = RtlDecodeSystemPointer(g_pfnSE_InstallBeforeInit); + SE_InstallBeforeInit(ProcessImage, pShimData); + } + } +} + +VOID +NTAPI +LdrpUnloadShimEngine() +{ + /* Make sure we do not call into the shim engine anymore */ + g_ShimsEnabled = FALSE; + LdrUnloadDll(g_pShimEngineModule); + g_pShimEngineModule = NULL; +} + /* EOF */