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?rev=52607&r1=52606&r2=52607&view=diff
==============================================================================
--- 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);
             }
         }


Reply via email to