179 lines
3.7 KiB
C
179 lines
3.7 KiB
C
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
imagedir.c
|
|
|
|
Abstract:
|
|
|
|
The module contains the code to translate an image directory type to
|
|
the address of the data for that entry.
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 18-Aug-1989
|
|
|
|
Environment:
|
|
|
|
User Mode or Kernel Mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "ntrtlp.h"
|
|
|
|
//
|
|
// Define forward referenced prootypes.
|
|
//
|
|
|
|
USHORT
|
|
ChkSum(
|
|
ULONG PartialSum,
|
|
PUSHORT Source,
|
|
ULONG Length
|
|
);
|
|
|
|
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
|
|
#pragma alloc_text(PAGE,ChkSum)
|
|
#pragma alloc_text(PAGE,LdrVerifyMappedImageMatchesChecksum)
|
|
#endif
|
|
|
|
USHORT
|
|
ChkSum(
|
|
ULONG PartialSum,
|
|
PUSHORT Source,
|
|
ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Compute a partial checksum on a portion of an imagefile.
|
|
|
|
Arguments:
|
|
|
|
PartialSum - Supplies the initial checksum value.
|
|
|
|
Sources - Supplies a pointer to the array of words for which the
|
|
checksum is computed.
|
|
|
|
Length - Supplies the length of the array in words.
|
|
|
|
Return Value:
|
|
|
|
The computed checksum value is returned as the function value.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
RTL_PAGED_CODE();
|
|
|
|
//
|
|
// Compute the word wise checksum allowing carries to occur into the
|
|
// high order half of the checksum longword.
|
|
//
|
|
|
|
while (Length--) {
|
|
PartialSum += *Source++;
|
|
PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff);
|
|
}
|
|
|
|
//
|
|
// Fold final carry into a single word result and return the resultant
|
|
// value.
|
|
//
|
|
|
|
return (USHORT)(((PartialSum >> 16) + PartialSum) & 0xffff);
|
|
}
|
|
|
|
BOOLEAN
|
|
LdrVerifyMappedImageMatchesChecksum (
|
|
IN PVOID BaseAddress,
|
|
IN ULONG FileLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This functions computes the checksum of an image mapped as a data file.
|
|
|
|
Arguments:
|
|
|
|
BaseAddress - Supplies a pointer to the base of the mapped file.
|
|
|
|
FileLength - Supplies the length of the file in bytes.
|
|
|
|
Return Value:
|
|
|
|
TRUE - The checksum stored in the image matches the checksum of the data.
|
|
|
|
FALSE - The checksum in the image is not correct.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PUSHORT AdjustSum;
|
|
PIMAGE_NT_HEADERS NtHeaders;
|
|
USHORT PartialSum;
|
|
ULONG HeaderSum;
|
|
ULONG CheckSum;
|
|
|
|
RTL_PAGED_CODE();
|
|
|
|
//
|
|
// Compute the checksum of the file and zero the header checksum value.
|
|
//
|
|
|
|
HeaderSum = 0;
|
|
PartialSum = ChkSum(0, (PUSHORT)BaseAddress, (FileLength + 1) >> 1);
|
|
|
|
//
|
|
// If the file is an image file, then subtract the two checksum words
|
|
// in the optional header from the computed checksum before adding
|
|
// the file length, and set the value of the header checksum.
|
|
//
|
|
|
|
NtHeaders = RtlImageNtHeader(BaseAddress);
|
|
if (NtHeaders != NULL) {
|
|
HeaderSum = NtHeaders->OptionalHeader.CheckSum;
|
|
|
|
#ifndef NTOS_KERNEL_RUNTIME
|
|
//
|
|
// On Nt 3.1 and 3.5, we allowed printer drivers with 0 checksums into
|
|
// csrss unintentionally. This means that we must allow this forever.
|
|
// I don't want to allow this for kernel mode drivers, so I will only
|
|
// allow 0 checksums of the high order bit is clear ?
|
|
//
|
|
|
|
|
|
if ( HeaderSum == 0 ) {
|
|
return TRUE;
|
|
}
|
|
#endif // NTOS_KERNEL_RUNTIME
|
|
|
|
AdjustSum = (PUSHORT)(&NtHeaders->OptionalHeader.CheckSum);
|
|
PartialSum -= (PartialSum < AdjustSum[0]);
|
|
PartialSum -= AdjustSum[0];
|
|
PartialSum -= (PartialSum < AdjustSum[1]);
|
|
PartialSum -= AdjustSum[1];
|
|
} else {
|
|
PartialSum = 0;
|
|
HeaderSum = FileLength;
|
|
}
|
|
|
|
//
|
|
// Compute the final checksum value as the sum of the paritial checksum
|
|
// and the file length.
|
|
//
|
|
|
|
CheckSum = (ULONG)PartialSum + FileLength;
|
|
return (CheckSum == HeaderSum);
|
|
}
|