From 4a96f375a0ff3f36615d4a1173c8201a96fde92d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 21 May 2026 13:02:52 +0300 Subject: [PATCH] [NTDLL] Unload DLLs on loader failure This is crucial, because otherwise they linger in the loader, waiting to run their init routine, which can cause failures later. --- dll/ntdll/ldr/ldrpe.c | 9 ++++++++- dll/ntdll/ldr/ldrutils.c | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dll/ntdll/ldr/ldrpe.c b/dll/ntdll/ldr/ldrpe.c index a09362ca4d3..272529788b0 100644 --- a/dll/ntdll/ldr/ldrpe.c +++ b/dll/ntdll/ldr/ldrpe.c @@ -961,7 +961,7 @@ LdrpSnapThunk(IN PVOID ExportBase, UNICODE_STRING TempUString; ANSI_STRING ForwarderName; PANSI_STRING ForwardName; - PVOID ForwarderHandle; + PVOID ForwarderHandle = NULL; ULONG ForwardOrdinal; /* Check if the snap is by ordinal */ @@ -1012,6 +1012,13 @@ LdrpSnapThunk(IN PVOID ExportBase, if ((ULONG)Ordinal >= ExportDirectory->NumberOfFunctions) { FailurePath: + /* Check if we loeaded a forwarder DLL */ + if (ForwarderHandle != NULL) + { + /* Unload the forwarder DLL */ + LdrUnloadDll(ForwarderHandle); + } + /* Is this a static snap? */ if (Static) { diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c index 19c90865531..b9a26d2f7f4 100644 --- a/dll/ntdll/ldr/ldrutils.c +++ b/dll/ntdll/ldr/ldrutils.c @@ -2378,6 +2378,15 @@ LdrpGetProcedureAddress( Status = _SEH2_GetExceptionCode(); } _SEH2_END; + + /* Check if it succeeded */ + if (!NT_SUCCESS(Status)) + { + /* Failed, unload the entry */ + DPRINT1("Initialization routine failed with 0x%08x\n", Status); + LdrUnloadDll(LdrEntry->DllBase); + LdrEntry = NULL; + } } }