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&a... ============================================================================== --- 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); }
/*