Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
3.7 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. imagedir.c
  5. Abstract:
  6. The module contains the code to translate an image directory type to
  7. the address of the data for that entry.
  8. Author:
  9. Steve Wood (stevewo) 18-Aug-1989
  10. Environment:
  11. User Mode or Kernel Mode
  12. Revision History:
  13. --*/
  14. #include "ntrtlp.h"
  15. //
  16. // Define forward referenced prootypes.
  17. //
  18. USHORT
  19. ChkSum(
  20. ULONG PartialSum,
  21. PUSHORT Source,
  22. ULONG Length
  23. );
  24. #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
  25. #pragma alloc_text(PAGE,ChkSum)
  26. #pragma alloc_text(PAGE,LdrVerifyMappedImageMatchesChecksum)
  27. #endif
  28. USHORT
  29. ChkSum(
  30. ULONG PartialSum,
  31. PUSHORT Source,
  32. ULONG Length
  33. )
  34. /*++
  35. Routine Description:
  36. Compute a partial checksum on a portion of an imagefile.
  37. Arguments:
  38. PartialSum - Supplies the initial checksum value.
  39. Sources - Supplies a pointer to the array of words for which the
  40. checksum is computed.
  41. Length - Supplies the length of the array in words.
  42. Return Value:
  43. The computed checksum value is returned as the function value.
  44. --*/
  45. {
  46. RTL_PAGED_CODE();
  47. //
  48. // Compute the word wise checksum allowing carries to occur into the
  49. // high order half of the checksum longword.
  50. //
  51. while (Length--) {
  52. PartialSum += *Source++;
  53. PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff);
  54. }
  55. //
  56. // Fold final carry into a single word result and return the resultant
  57. // value.
  58. //
  59. return (USHORT)(((PartialSum >> 16) + PartialSum) & 0xffff);
  60. }
  61. BOOLEAN
  62. LdrVerifyMappedImageMatchesChecksum (
  63. IN PVOID BaseAddress,
  64. IN ULONG FileLength
  65. )
  66. /*++
  67. Routine Description:
  68. This functions computes the checksum of an image mapped as a data file.
  69. Arguments:
  70. BaseAddress - Supplies a pointer to the base of the mapped file.
  71. FileLength - Supplies the length of the file in bytes.
  72. Return Value:
  73. TRUE - The checksum stored in the image matches the checksum of the data.
  74. FALSE - The checksum in the image is not correct.
  75. --*/
  76. {
  77. PUSHORT AdjustSum;
  78. PIMAGE_NT_HEADERS NtHeaders;
  79. USHORT PartialSum;
  80. ULONG HeaderSum;
  81. ULONG CheckSum;
  82. RTL_PAGED_CODE();
  83. //
  84. // Compute the checksum of the file and zero the header checksum value.
  85. //
  86. HeaderSum = 0;
  87. PartialSum = ChkSum(0, (PUSHORT)BaseAddress, (FileLength + 1) >> 1);
  88. //
  89. // If the file is an image file, then subtract the two checksum words
  90. // in the optional header from the computed checksum before adding
  91. // the file length, and set the value of the header checksum.
  92. //
  93. NtHeaders = RtlImageNtHeader(BaseAddress);
  94. if (NtHeaders != NULL) {
  95. HeaderSum = NtHeaders->OptionalHeader.CheckSum;
  96. #ifndef NTOS_KERNEL_RUNTIME
  97. //
  98. // On Nt 3.1 and 3.5, we allowed printer drivers with 0 checksums into
  99. // csrss unintentionally. This means that we must allow this forever.
  100. // I don't want to allow this for kernel mode drivers, so I will only
  101. // allow 0 checksums of the high order bit is clear ?
  102. //
  103. if ( HeaderSum == 0 ) {
  104. return TRUE;
  105. }
  106. #endif // NTOS_KERNEL_RUNTIME
  107. AdjustSum = (PUSHORT)(&NtHeaders->OptionalHeader.CheckSum);
  108. PartialSum -= (PartialSum < AdjustSum[0]);
  109. PartialSum -= AdjustSum[0];
  110. PartialSum -= (PartialSum < AdjustSum[1]);
  111. PartialSum -= AdjustSum[1];
  112. } else {
  113. PartialSum = 0;
  114. HeaderSum = FileLength;
  115. }
  116. //
  117. // Compute the final checksum value as the sum of the paritial checksum
  118. // and the file length.
  119. //
  120. CheckSum = (ULONG)PartialSum + FileLength;
  121. return (CheckSum == HeaderSum);
  122. }