[NTDLL/LDR]
authorAleksey Bragin <aleksey@reactos.org>
Wed, 16 Mar 2011 09:52:41 +0000 (09:52 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Wed, 16 Mar 2011 09:52:41 +0000 (09:52 +0000)
- Rewrite LdrImageMatchesChecksum, remove now outdated LdrpCheckImageChecksum.

svn path=/trunk/; revision=51060

reactos/dll/ntdll/ldr/ldrapi.c
reactos/dll/ntdll/ldr/utils.c

index db71d74..55e1582 100644 (file)
@@ -246,4 +246,136 @@ Quickie:
     return Status;
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle,
+                              IN PLDR_CALLBACK Callback,
+                              IN PVOID CallbackContext,
+                              OUT PUSHORT ImageCharacteristics)
+{
+    FILE_STANDARD_INFORMATION FileStandardInfo;
+    PIMAGE_IMPORT_DESCRIPTOR ImportData;
+    PIMAGE_SECTION_HEADER LastSection;
+    IO_STATUS_BLOCK IoStatusBlock;
+    PIMAGE_NT_HEADERS NtHeader;
+    HANDLE SectionHandle;
+    SIZE_T ViewSize = 0;
+    PVOID ViewBase = NULL;
+    BOOLEAN Result;
+    NTSTATUS Status;
+    PVOID ImportName;
+    ULONG Size;
+
+    DPRINT("LdrVerifyImageMatchesChecksum() called\n");
+
+    /* Create the section */
+    Status = NtCreateSection(&SectionHandle,
+                             SECTION_MAP_EXECUTE,
+                             NULL,
+                             NULL,
+                             PAGE_EXECUTE,
+                             SEC_COMMIT,
+                             FileHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status);
+        return Status;
+    }
+
+    /* Map the section */
+    Status = NtMapViewOfSection(SectionHandle,
+                                NtCurrentProcess(),
+                                &ViewBase,
+                                0,
+                                0,
+                                NULL,
+                                &ViewSize,
+                                ViewShare,
+                                0,
+                                PAGE_EXECUTE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
+        NtClose(SectionHandle);
+        return Status;
+    }
+
+    /* Get the file information */
+    Status = NtQueryInformationFile(FileHandle,
+                                    &IoStatusBlock,
+                                    &FileStandardInfo,
+                                    sizeof(FILE_STANDARD_INFORMATION),
+                                    FileStandardInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
+        NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
+        NtClose(SectionHandle);
+        return Status;
+    }
+
+    /* Protect with SEH */
+    _SEH2_TRY
+    {
+        /* Verify the checksum */
+        Result = LdrVerifyMappedImageMatchesChecksum(ViewBase,
+                                                     ViewSize,
+                                                     FileStandardInfo.EndOfFile.LowPart);
+
+        /* Check if a callback was supplied */
+        if (Result && Callback)
+        {
+            /* Get the NT Header */
+            NtHeader = RtlImageNtHeader(ViewBase);
+
+            /* Check if caller requested this back */
+            if (ImageCharacteristics)
+            {
+                /* Return to caller */
+                *ImageCharacteristics = NtHeader->FileHeader.Characteristics;
+            }
+
+            /* Get the Import Directory Data */
+            ImportData = RtlImageDirectoryEntryToData(ViewBase,
+                                                      FALSE,
+                                                      IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                      &Size);
+
+            /* Make sure there is one */
+            if (ImportData)
+            {
+                /* Loop the imports */
+                while (ImportData->Name)
+                {
+                    /* Get the name */
+                    ImportName = RtlImageRvaToVa(NtHeader,
+                                                 ViewBase,
+                                                 ImportData->Name,
+                                                 &LastSection);
+
+                    /* Notify the callback */
+                    Callback(CallbackContext, ImportName);
+                    ImportData++;
+                }
+            }
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */
+        Result = FALSE;
+    }
+    _SEH2_END;
+
+    /* Unmap file and close handle */
+    NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
+    NtClose(SectionHandle);
+
+    /* Return status */
+    return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status;
+}
+
 /* EOF */
index cd7c7d6..e03cb12 100644 (file)
@@ -2950,76 +2950,6 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIO
     return(Status);
 }
 
-
-static BOOLEAN
-LdrpCheckImageChecksum (IN PVOID BaseAddress,
-                        IN ULONG ImageSize)
-{
-    PIMAGE_NT_HEADERS Header;
-    PUSHORT Ptr;
-    ULONG Sum;
-    ULONG CalcSum;
-    ULONG HeaderSum;
-    ULONG i;
-
-    Header = RtlImageNtHeader (BaseAddress);
-    if (Header == NULL)
-        return FALSE;
-
-    HeaderSum = Header->OptionalHeader.CheckSum;
-    if (HeaderSum == 0)
-        return TRUE;
-
-    Sum = 0;
-    Ptr = (PUSHORT) BaseAddress;
-    for (i = 0; i < ImageSize / sizeof (USHORT); i++)
-    {
-        Sum += (ULONG)*Ptr;
-        if (HIWORD(Sum) != 0)
-        {
-            Sum = LOWORD(Sum) + HIWORD(Sum);
-        }
-        Ptr++;
-    }
-
-    if (ImageSize & 1)
-    {
-        Sum += (ULONG)*((PUCHAR)Ptr);
-        if (HIWORD(Sum) != 0)
-        {
-            Sum = LOWORD(Sum) + HIWORD(Sum);
-        }
-    }
-
-    CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum));
-
-    /* Subtract image checksum from calculated checksum. */
-    /* fix low word of checksum */
-    if (LOWORD(CalcSum) >= LOWORD(HeaderSum))
-    {
-        CalcSum -= LOWORD(HeaderSum);
-    }
-    else
-    {
-        CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1;
-    }
-
-    /* fix high word of checksum */
-    if (LOWORD(CalcSum) >= HIWORD(HeaderSum))
-    {
-        CalcSum -= HIWORD(HeaderSum);
-    }
-    else
-    {
-        CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1;
-    }
-
-    /* add file length */
-    CalcSum += ImageSize;
-
-    return (BOOLEAN)(CalcSum == HeaderSum);
-}
-
 /*
  * Compute size of an image as it is actually present in virt memory
  * (i.e. excluding NEVER_LOAD sections)
@@ -3049,100 +2979,6 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
     return ResidentSize;
 }
 
-
-/***************************************************************************
- * NAME                                                         EXPORTED
- *      LdrVerifyImageMatchesChecksum
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- * NOTE
- *
- * @implemented
- */
-NTSTATUS NTAPI
-LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
-                               IN PLDR_CALLBACK Callback,
-                               IN PVOID CallbackContext,
-                               OUT PUSHORT ImageCharacterstics)
-{
-    FILE_STANDARD_INFORMATION FileInfo;
-    IO_STATUS_BLOCK IoStatusBlock;
-    HANDLE SectionHandle;
-    SIZE_T ViewSize;
-    PVOID BaseAddress;
-    BOOLEAN Result;
-    NTSTATUS Status;
-
-    DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
-
-    Status = NtCreateSection (&SectionHandle,
-                              SECTION_MAP_READ,
-                              NULL,
-                              NULL,
-                              PAGE_READONLY,
-                              SEC_COMMIT,
-                              FileHandle);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status);
-        return Status;
-    }
-
-    ViewSize = 0;
-    BaseAddress = NULL;
-    Status = NtMapViewOfSection (SectionHandle,
-                                 NtCurrentProcess (),
-                                 &BaseAddress,
-                                 0,
-                                 0,
-                                 NULL,
-                                 &ViewSize,
-                                 ViewShare,
-                                 0,
-                                 PAGE_READONLY);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
-        NtClose (SectionHandle);
-        return Status;
-    }
-
-    Status = NtQueryInformationFile(FileHandle,
-                                    &IoStatusBlock,
-                                    &FileInfo,
-                                    sizeof (FILE_STANDARD_INFORMATION),
-                                    FileStandardInformation);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
-        NtUnmapViewOfSection (NtCurrentProcess(),
-                              BaseAddress);
-        NtClose (SectionHandle);
-        return Status;
-    }
-
-    Result = LdrpCheckImageChecksum(BaseAddress,
-                                    FileInfo.EndOfFile.u.LowPart);
-    if (Result == FALSE)
-    {
-        Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
-    }
-
-    NtUnmapViewOfSection (NtCurrentProcess(),
-                          BaseAddress);
-
-    NtClose(SectionHandle);
-
-    return Status;
-}
-
 PIMAGE_BASE_RELOCATION
 NTAPI
 LdrProcessRelocationBlock(