Author: ion Date: Sun Jul 10 13:51:40 2011 New Revision: 52607
URL: http://svn.reactos.org/svn/reactos?rev=52607&view=rev Log: [NTDLL]: Fix parsing and buffer overflow in LdrpLoadDll. Add more debug prints, and add some missing code (commented out) for later.
Modified: trunk/reactos/dll/ntdll/ldr/ldrutils.c
Modified: trunk/reactos/dll/ntdll/ldr/ldrutils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrutils.c?re... ============================================================================== --- trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] (original) +++ trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] Sun Jul 10 13:51:40 2011 @@ -16,6 +16,7 @@ /* GLOBALS *******************************************************************/
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache, LdrpGetModuleHandleCache; +BOOLEAN g_ShimsEnabled;
/* FUNCTIONS *****************************************************************/
@@ -1849,6 +1850,7 @@ PPEB Peb = NtCurrentPeb(); NTSTATUS Status = STATUS_SUCCESS; PWCHAR p1, p2; + WCHAR c; WCHAR NameBuffer[266]; LPWSTR RawDllName; UNICODE_STRING RawDllNameString; @@ -1857,39 +1859,47 @@
/* Find the name without the extension */ p1 = DllName->Buffer; -StartLoop: p2 = NULL; while (*p1) { - if (*p1++ == L'.') + c = *p1++; + if (c == L'.') { p2 = p1; } - else if (*p1 == L'\') - { - goto StartLoop; + else if (c == L'\') + { + p2 = NULL; } }
/* Save the Raw DLL Name */ RawDllName = NameBuffer; - if (DllName->Length >= sizeof(NameBuffer)) - { - /* The DLL's name is too long */ - return STATUS_NAME_TOO_LONG; - } + if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG; RtlMoveMemory(RawDllName, DllName->Buffer, DllName->Length);
/* Check if no extension was found or if we got a slash */ - if (!p2 || *p2 == '\') + if (!(p2) || (*p2 == '\')) { /* Check that we have space to add one */ - if (DllName->Length + LdrApiDefaultExtension.Length >= sizeof(NameBuffer)) + if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >= + sizeof(NameBuffer)) { /* No space to add the extension */ + DbgPrintEx(81, //DPFLTR_LDR_ID, + 0, + "LDR: %s - Dll name missing extension; with extension " + "added the name is too long\n" + " DllName: (@ %p) "%wZ"\n" + " DllName->Length: %u\n", + __FUNCTION__, + DllName, + DllName, + DllName->Length); return STATUS_NAME_TOO_LONG; }
+ /* FIXME: CLEAN THIS UP WITH Rtl String Functions */ /* Add it */ RtlMoveMemory((PVOID)((ULONG_PTR)RawDllName + DllName->Length), LdrApiDefaultExtension.Buffer, @@ -1941,16 +1951,18 @@ Redirected, &LdrEntry); if (!NT_SUCCESS(Status)) goto Quickie; - - /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */ - if (DllCharacteristics && - (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) - { - LdrEntry->EntryPoint = NULL; - LdrEntry->Flags &= ~LDRP_IMAGE_DLL; - } - - /* FIXME Mark the DLL Ranges for Stack Traces later */ + + /* FIXME: Need to mark the DLL range for the stack DB */ + //RtlpStkMarkDllRange(LdrEntry); + + /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */ + if ((DllCharacteristics) && + (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) + { + /* This is not a DLL, so remove such data */ + LdrEntry->EntryPoint = NULL; + LdrEntry->Flags &= ~LDRP_IMAGE_DLL; + }
/* Make sure it's a DLL */ if (LdrEntry->Flags & LDRP_IMAGE_DLL) @@ -1974,8 +1986,17 @@ InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, &LdrEntry->InInitializationOrderModuleList);
- /* Cancel the load and unload the DLL */ + /* Cancel the load */ LdrpClearLoadInProgress(); + + /* Unload the DLL */ + if (ShowSnaps) + { + DbgPrint("LDR: Unloading %wZ due to error %x walking " + "import descriptors", + DllName, + Status); + } LdrUnloadDll(LdrEntry->DllBase);
/* Return the error */ @@ -1996,12 +2017,26 @@ if (CallInit && LdrpLdrDatabaseIsSetup) { /* FIXME: Notify Shim Engine */ - + if (g_ShimsEnabled) + { + /* Call it */ + //ShimLoadCallback = RtlDecodeSystemPointer(g_pfnSE_DllLoaded); + //ShimLoadCallback(LdrEntry); + } + /* Run the init routine */ Status = LdrpRunInitializeRoutines(NULL); if (!NT_SUCCESS(Status)) { /* Failed, unload the DLL */ + if (ShowSnaps) + { + DbgPrint("LDR: Unloading %wZ because either its init " + "routine or one of its static imports failed; " + "status = 0x%08lx\n", + DllName, + Status); + } LdrUnloadDll(LdrEntry->DllBase); } }