Author: fireball
Date: Wed Mar 16 09:49:07 2011
New Revision: 51059

URL: http://svn.reactos.org/svn/reactos?rev=51059&view=rev
Log:
[RTL]
- Implement LdrVerifyMappedImageChecksum (copied from ntdll/ldr/utils.c).

Modified:
    trunk/reactos/lib/rtl/image.c

Modified: trunk/reactos/lib/rtl/image.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/image.c?rev=51059&r1=51058&r2=51059&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/image.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/image.c [iso-8859-1] Wed Mar 16 09:49:07 2011
@@ -24,11 +24,78 @@
 NTAPI
 LdrVerifyMappedImageMatchesChecksum(
     IN PVOID BaseAddress,
-    IN ULONG NumberOfBytes,
+    IN ULONG ImageSize,
     IN ULONG FileLength)
 {
-    /* FIXME: TODO */
-    return TRUE;
+    PIMAGE_NT_HEADERS Header;
+    PUSHORT Ptr;
+    ULONG Sum;
+    ULONG CalcSum;
+    ULONG HeaderSum;
+    ULONG i;
+
+    /* Get NT header to check if it's an image at all */
+    Header = RtlImageNtHeader (BaseAddress);
+    if (!Header) return FALSE;
+
+    /* Get checksum to match */
+    HeaderSum = Header->OptionalHeader.CheckSum;
+
+    /* Zero checksum seems to be accepted */
+    if (HeaderSum == 0) return TRUE;
+
+    /* Calculate the checksum */
+    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;
+
+    if (CalcSum != HeaderSum)
+        DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x\n", BaseAddress, 
CalcSum, HeaderSum);
+
+    return (BOOLEAN)(CalcSum == HeaderSum);
 }
 
 /*


Reply via email to