免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

加载内核到内存中实现内核重载

driver.h
  1. #ifdef __cplusplus
  2. extern "C"
  3. {
  4. #endif
  5. #include <ntddk.h>
  6. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

  7. #ifdef __cplusplus
  8. }
  9. #endif

  10. #define PAGEDCODE code_seg("PAGE")
  11. #define LOCKEDCODE code_seg()
  12. #define INITCODE code_seg("INIT")

  13. #define PAGEDDATA data_seg("PAGE")
  14. #define LOCKEDDATA data_seg()
  15. #define INITDATA data_seg("INIT")

  16. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

  17. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);


  18. #define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
  19. #define IMAGE_NT_SIGNATURE                  0x00004550  // PE00

  20. typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
  21.         USHORT e_magic;                     // Magic number
  22.         USHORT e_cblp;                      // Bytes on last page of file
  23.         USHORT e_cp;                        // Pages in file
  24.         USHORT e_crlc;                      // Relocations
  25.         USHORT e_cparhdr;                   // Size of header in paragraphs
  26.         USHORT e_minalloc;                  // Minimum extra paragraphs needed
  27.         USHORT e_maxalloc;                  // Maximum extra paragraphs needed
  28.         USHORT e_ss;                        // Initial (relative) SS value
  29.         USHORT e_sp;                        // Initial SP value
  30.         USHORT e_csum;                      // Checksum
  31.         USHORT e_ip;                        // Initial IP value
  32.         USHORT e_cs;                        // Initial (relative) CS value
  33.         USHORT e_lfarlc;                    // File address of relocation table
  34.         USHORT e_ovno;                      // Overlay number
  35.         USHORT e_res[4];                    // Reserved words
  36.         USHORT e_oemid;                     // OEM identifier (for e_oeminfo)
  37.         USHORT e_oeminfo;                   // OEM information; e_oemid specific
  38.         USHORT e_res2[10];                  // Reserved words
  39.         LONG   e_lfanew;                    // File address of new exe header
  40. } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

  41. typedef struct _IMAGE_FILE_HEADER {
  42.         USHORT  Machine;
  43.         USHORT  NumberOfSections;
  44.         ULONG   TimeDateStamp;
  45.         ULONG   PointerToSymbolTable;
  46.         ULONG   NumberOfSymbols;
  47.         USHORT  SizeOfOptionalHeader;
  48.         USHORT  Characteristics;
  49. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

  50. typedef struct _IMAGE_DATA_DIRECTORY {
  51.         ULONG   VirtualAddress;
  52.         ULONG   Size;
  53. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

  54. #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

  55. typedef struct _IMAGE_OPTIONAL_HEADER {
  56.         //
  57.         // Standard fields.
  58.         //

  59.         USHORT  Magic;
  60.         UCHAR   MajorLinkerVersion;
  61.         UCHAR   MinorLinkerVersion;
  62.         ULONG   SizeOfCode;
  63.         ULONG   SizeOfInitializedData;
  64.         ULONG   SizeOfUninitializedData;
  65.         ULONG   AddressOfEntryPoint;
  66.         ULONG   BaseOfCode;
  67.         ULONG   BaseOfData;

  68.         //
  69.         // NT additional fields.
  70.         //

  71.         ULONG   ImageBase;
  72.         ULONG   SectionAlignment;
  73.         ULONG   FileAlignment;
  74.         USHORT  MajorOperatingSystemVersion;
  75.         USHORT  MinorOperatingSystemVersion;
  76.         USHORT  MajorImageVersion;
  77.         USHORT  MinorImageVersion;
  78.         USHORT  MajorSubsystemVersion;
  79.         USHORT  MinorSubsystemVersion;
  80.         ULONG   Win32VersionValue;
  81.         ULONG   SizeOfImage;
  82.         ULONG   SizeOfHeaders;
  83.         ULONG   CheckSum;
  84.         USHORT  Subsystem;
  85.         USHORT  DllCharacteristics;
  86.         ULONG   SizeOfStackReserve;
  87.         ULONG   SizeOfStackCommit;
  88.         ULONG   SizeOfHeapReserve;
  89.         ULONG   SizeOfHeapCommit;
  90.         ULONG   LoaderFlags;
  91.         ULONG   NumberOfRvaAndSizes;
  92.         IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  93. } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

  94. typedef IMAGE_OPTIONAL_HEADER32             IMAGE_OPTIONAL_HEADER;
  95. typedef PIMAGE_OPTIONAL_HEADER32            PIMAGE_OPTIONAL_HEADER;

  96. typedef struct _IMAGE_BASE_RELOCATION {
  97.         ULONG   VirtualAddress;
  98.         ULONG   SizeOfBlock;
  99.         USHORT  TypeOffset[1];
  100. } IMAGE_BASE_RELOCATION;
  101. typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;


  102. typedef struct _IMAGE_NT_HEADERS {
  103.         ULONG Signature;
  104.         IMAGE_FILE_HEADER FileHeader;
  105.         IMAGE_OPTIONAL_HEADER32 OptionalHeader;
  106. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

  107. typedef IMAGE_NT_HEADERS32                  IMAGE_NT_HEADERS;
  108. typedef PIMAGE_NT_HEADERS32                 PIMAGE_NT_HEADERS;

  109. typedef struct _IMAGE_EXPORT_DIRECTORY {
  110.         ULONG   Characteristics;
  111.         ULONG   TimeDateStamp;
  112.         USHORT  MajorVersion;
  113.         USHORT  MinorVersion;
  114.         ULONG   Name;
  115.         ULONG   Base;
  116.         ULONG   NumberOfFunctions;
  117.         ULONG   NumberOfNames;
  118.         ULONG   AddressOfFunctions;     // RVA from base of image
  119.         ULONG   AddressOfNames;         // RVA from base of image
  120.         ULONG   AddressOfNameOrdinals;  // RVA from base of image
  121. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;


  122. #define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
  123. #define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
  124. #define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
  125. #define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
  126. #define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
  127. #define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
  128. #define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
  129. //      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
  130. #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
  131. #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
  132. #define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
  133. #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
  134. #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
  135. #define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
  136. #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
  137. #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor


  138. #define IMAGE_SIZEOF_SHORT_NAME              8

  139. typedef struct _IMAGE_SECTION_HEADER {
  140.         UCHAR   Name[IMAGE_SIZEOF_SHORT_NAME];
  141.         union {
  142.                 ULONG   PhysicalAddress;
  143.                 ULONG   VirtualSize;
  144.         } Misc;
  145.         ULONG   VirtualAddress;
  146.         ULONG   SizeOfRawData;
  147.         ULONG   PointerToRawData;
  148.         ULONG   PointerToRelocations;
  149.         ULONG   PointerToLinenumbers;
  150.         USHORT  NumberOfRelocations;
  151.         USHORT  NumberOfLinenumbers;
  152.         ULONG   Characteristics;
  153. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

  154. #define IMAGE_REL_BASED_ABSOLUTE              0
  155. #define IMAGE_REL_BASED_HIGH                  1
  156. #define IMAGE_REL_BASED_LOW                   2
  157. #define IMAGE_REL_BASED_HIGHLOW               3
  158. #define IMAGE_REL_BASED_HIGHADJ               4
  159. #define IMAGE_REL_BASED_MIPS_JMPADDR          5
  160. #define IMAGE_REL_BASED_MIPS_JMPADDR16        9
  161. #define IMAGE_REL_BASED_IA64_IMM64            9
  162. #define IMAGE_REL_BASED_DIR64                 10



  163. #pragma pack(1)
  164. typedef struct ServiceDescriptorEntry {
  165.         unsigned int *ServiceTableBase;
  166.         unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  167.         unsigned int NumberOfServices;
  168.         unsigned char *ParamTableBase;
  169. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
  170. #pragma pack()

  171. EXTERN_C __declspec (dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;


  172. EXTERN_C NTKERNELAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(PVOID Base);

  173. EXTERN_C NTSYSAPI PVOID NTAPI RtlImageDirectoryEntryToData(
  174.                                                          PVOID BaseOfImage,
  175.                                                          BOOLEAN MappedAsImage,
  176.                                                          USHORT DirectoryEntry,
  177.                                                          PULONG Size
  178.                                                          );
复制代码
driver.cpp
  1. #include "Driver.h"

  2. //global
  3. ULONG g_uImageBase, g_uKernelBase;
  4. PServiceDescriptorTableEntry_t g_pNewSSDT;

  5. BOOLEAN IsOpenPae()
  6. {
  7.         ULONG uCr4 = 0;
  8.         __asm
  9.         {
  10.                 _emit 0x0f
  11.                 _emit 0x20
  12.                 _emit 0xe0
  13.                 mov uCr4, eax
  14.         }

  15.         if ((uCr4 & 0x00000020) == 0x00000020)
  16.         {
  17.                 return TRUE;
  18.         }
  19.         else
  20.         {
  21.                 return FALSE;
  22.         }
  23. }


  24. PVOID MiFindExportedRoutineByName (IN PVOID DllBase,
  25.                                                                    IN PANSI_STRING AnsiImageRoutineName)
  26. {
  27.         USHORT OrdinalNumber;
  28.         PULONG NameTableBase;
  29.         PUSHORT NameOrdinalTableBase;
  30.         PULONG Addr;
  31.         LONG High;
  32.         LONG Low;
  33.         LONG Middle;
  34.         LONG Result;
  35.         ULONG ExportSize; // 保存表项的大小
  36.         PVOID FunctionAddress;
  37.         PIMAGE_EXPORT_DIRECTORY ExportDirectory;

  38.         PAGED_CODE();

  39.         ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
  40.                 DllBase,
  41.                 TRUE,
  42.                 IMAGE_DIRECTORY_ENTRY_EXPORT,
  43.                 &ExportSize);

  44.         if (ExportDirectory == NULL) {
  45.                 return NULL;
  46.         }

  47.         NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
  48.         NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

  49.        
  50.         Low = 0;
  51.         Middle = 0;
  52.         High = ExportDirectory->NumberOfNames - 1;

  53.         while (High >= Low) {
  54.                 Middle = (Low + High) >> 1;

  55.                 Result = strcmp (AnsiImageRoutineName->Buffer,
  56.                         (PCHAR)DllBase + NameTableBase[Middle]);

  57.                 if (Result < 0) {
  58.                         High = Middle - 1;
  59.                 }
  60.                 else if (Result > 0) {
  61.                         Low = Middle + 1;
  62.                 }
  63.                 else {
  64.                         break;
  65.                 }
  66.         }

  67.         // 如果High < Low,表明没有在EAT中找到这个函数;否则,返回此函数的索引
  68.         if (High < Low) {
  69.                 return NULL;
  70.         }

  71.         OrdinalNumber = NameOrdinalTableBase[Middle];

  72.         // 如果索引值大于EAT中已有的函数数量,则查找失败
  73.         if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
  74.                 return NULL;
  75.         }

  76.         Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);

  77.         FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
  78.         ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
  79.                 (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));

  80.         return FunctionAddress;
  81. }



  82. VOID GetKernelFilePath(PWCHAR pszKernelName)
  83. {
  84.         PWCHAR pszFileName = NULL;
  85.         if (IsOpenPae())
  86.         {
  87.                 pszFileName = L"\\SystemRoot\\system32\\ntkrnlpa.exe";
  88.         }
  89.         else
  90.         {       
  91.                 pszFileName = L"\\SystemRoot\\system32\\ntoskrnl.exe";
  92.         }

  93.         RtlCopyMemory(pszKernelName, pszFileName, wcslen(pszFileName) * sizeof(WCHAR) + sizeof(WCHAR));
  94. }

  95. ULONG GetKernelBase(ULONG uImageBase)
  96. {
  97.         ANSI_STRING FuncName;
  98.         RtlInitAnsiString(&FuncName, "NtOpenProcess");

  99.         PVOID pFunc = MiFindExportedRoutineByName((PVOID)uImageBase, &FuncName);

  100.         ULONG uKernelBase = (ULONG)NtOpenProcess - ((ULONG)pFunc - uImageBase);

  101.         return uKernelBase;
  102. }



  103. PIMAGE_BASE_RELOCATION LdrProcessRelocationBlock(
  104.                                                   IN ULONG_PTR VA,
  105.                                                   IN ULONG SizeOfBlock,
  106.                                                   IN PUSHORT NextOffset,
  107.                                                   IN LONG_PTR Diff
  108.                                                   )
  109. {
  110.         PUCHAR FixupVA;
  111.         USHORT Offset;
  112.         LONG Temp;
  113.         ULONGLONG Value64;
  114.         LONGLONG Temp64;

  115.         while (SizeOfBlock--) {

  116.                 Offset = *NextOffset & (USHORT)0xfff;
  117.                 FixupVA = (PUCHAR)(VA + Offset);

  118.                 switch ((*NextOffset) >> 12) {

  119.                         case IMAGE_REL_BASED_HIGHLOW :
  120.                                
  121.                                 *(LONG UNALIGNED *)FixupVA += (ULONG) Diff;
  122.                                 break;

  123.                         case IMAGE_REL_BASED_HIGH :
  124.                                
  125.                                 Temp = *(PUSHORT)FixupVA << 16;
  126.                                 Temp += (ULONG) Diff;
  127.                                 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16);
  128.                                 break;

  129.                         case IMAGE_REL_BASED_HIGHADJ :
  130.                                
  131.                                 Temp = *(PUSHORT)FixupVA << 16;

  132.                                 ++NextOffset;
  133.                                 --SizeOfBlock;
  134.                                 Temp += (LONG)(*(PSHORT)NextOffset);
  135.                                 Temp += (ULONG) Diff;
  136.                                 Temp += 0x8000;
  137.                                 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16);

  138.                                 break;

  139.                         case IMAGE_REL_BASED_LOW :
  140.                                
  141.                                 Temp = *(PSHORT)FixupVA;
  142.                                 Temp += (ULONG) Diff;
  143.                                 *(PUSHORT)FixupVA = (USHORT)Temp;
  144.                                 break;

  145.                         case IMAGE_REL_BASED_IA64_IMM64:

  146.                                 FixupVA = (PUCHAR)((ULONG_PTR)FixupVA & ~(15));
  147.                                 Value64 = (ULONGLONG)0;

  148.                                 Value64+=Diff;

  149.                                 break;

  150.                         case IMAGE_REL_BASED_DIR64:

  151.                                 *(ULONG_PTR UNALIGNED *)FixupVA += Diff;

  152.                                 break;

  153.                         case IMAGE_REL_BASED_MIPS_JMPADDR :
  154.                        
  155.                                 Temp = (*(PULONG)FixupVA & 0x3ffffff) << 2;
  156.                                 Temp += (ULONG) Diff;
  157.                                 *(PULONG)FixupVA = (*(PULONG)FixupVA & ~0x3ffffff) |
  158.                                         ((Temp >> 2) & 0x3ffffff);

  159.                                 break;

  160.                         case IMAGE_REL_BASED_ABSOLUTE :
  161.                        
  162.                                 break;

  163.                         case 6 :
  164.                                
  165.                                 break;

  166.                         case 7 :
  167.                                
  168.                                 break;

  169.                         case 8 :

  170.                                 Temp64 = *(PUSHORT)FixupVA << 16;
  171.                                 ++NextOffset;
  172.                                 --SizeOfBlock;
  173.                                 Temp64 += (LONG)((SHORT)NextOffset[1]);
  174.                                 Temp64 <<= 16;
  175.                                 Temp64 += (LONG)((USHORT)NextOffset[0]);
  176.                                 Temp64 += Diff;
  177.                                 Temp64 += 0x8000;
  178.                                 Temp64 >>=16;
  179.                                 Temp64 += 0x8000;
  180.                                 *(PUSHORT)FixupVA = (USHORT)(Temp64 >> 16);
  181.                                 ++NextOffset;
  182.                                 --SizeOfBlock;
  183.                                 break;

  184.                         default :

  185.                         return (PIMAGE_BASE_RELOCATION)NULL;
  186.                 }
  187.                 ++NextOffset;
  188.         }
  189.         return (PIMAGE_BASE_RELOCATION)NextOffset;
  190. }


  191. BOOLEAN LdrRelocateImage (
  192.     IN PVOID NewBase,
  193.     IN PUCHAR LoaderName
  194.     )

  195. {
  196.     LONG_PTR Diff;
  197.     ULONG TotalCountBytes;
  198.     ULONG_PTR VA;
  199.     ULONG_PTR OldBase;
  200.     ULONG SizeOfBlock;
  201.     PUSHORT NextOffset;
  202.     PIMAGE_NT_HEADERS NtHeaders;
  203.     PIMAGE_BASE_RELOCATION NextBlock;

  204.    
  205.     NtHeaders = RtlImageNtHeader( NewBase );
  206.     if ( NtHeaders ) {
  207.         OldBase = NtHeaders->OptionalHeader.ImageBase;
  208.         }
  209.     else {
  210.         return FALSE;
  211.         }

  212.     NextBlock = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData(
  213.             NewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &TotalCountBytes);

  214.     if (!NextBlock || !TotalCountBytes) {

  215.         return FALSE;
  216.     }

  217.     while (TotalCountBytes) {
  218.         SizeOfBlock = NextBlock->SizeOfBlock;
  219.         TotalCountBytes -= SizeOfBlock;
  220.         SizeOfBlock -= sizeof(IMAGE_BASE_RELOCATION);
  221.         SizeOfBlock /= sizeof(USHORT);
  222.         NextOffset = (PUSHORT)((PCHAR)NextBlock + sizeof(IMAGE_BASE_RELOCATION));

  223.         VA = (ULONG_PTR)NewBase + NextBlock->VirtualAddress;
  224.         Diff = (PCHAR)LoaderName - (PCHAR)OldBase;

  225.         if ( !(NextBlock = LdrProcessRelocationBlock(VA,SizeOfBlock,NextOffset,Diff)) ) {

  226.             return FALSE;
  227.         }
  228.     }

  229.     return TRUE;
  230. }


  231. void SetNewSSDT(PVOID pNewImage, PVOID pOrigImage, PServiceDescriptorTableEntry_t *pNewServiceTable)
  232. {
  233.         ULONG uIndex, uOffset;
  234.         ULONG uNewKernelInc;
  235.         PServiceDescriptorTableEntry_t pNewSSDT;

  236.         uNewKernelInc = (ULONG) pNewImage - (ULONG) pOrigImage;
  237.         pNewSSDT = (PServiceDescriptorTableEntry_t) ((ULONG)&KeServiceDescriptorTable + uNewKernelInc);

  238.         if (!MmIsAddressValid(pNewSSDT))
  239.         {
  240.                 return;
  241.         }

  242.         pNewSSDT->NumberOfServices = KeServiceDescriptorTable.NumberOfServices;
  243.         uOffset = (ULONG)KeServiceDescriptorTable.ServiceTableBase - (ULONG)pOrigImage;
  244.         pNewSSDT->ServiceTableBase = (unsigned int *)((ULONG)pNewImage + uOffset);
  245.         if (!MmIsAddressValid(pNewSSDT->ServiceTableBase))
  246.         {
  247.                 return;
  248.         }

  249.         for (uIndex = 0; uIndex < pNewSSDT->NumberOfServices; uIndex++)
  250.         {
  251.                 pNewSSDT->ServiceTableBase[uIndex] += uNewKernelInc;
  252.         }


  253.         uOffset = (ULONG)KeServiceDescriptorTable.ParamTableBase - (ULONG)pOrigImage;
  254.         pNewSSDT->ParamTableBase = (unsigned char *)((ULONG)pNewImage + uOffset);

  255.         if (!MmIsAddressValid(pNewSSDT->ParamTableBase))
  256.         {
  257.                 return;
  258.         }
  259.         RtlCopyMemory(pNewSSDT->ParamTableBase, KeServiceDescriptorTable.ParamTableBase, pNewSSDT->NumberOfServices * sizeof(CHAR));

  260.         *pNewServiceTable = pNewSSDT;
  261.         KdPrint(("set new ssdt success!\n"));
  262. }


  263. NTSTATUS LoadKernelFile(PULONG pKernelBase, PULONG pLoadImageBase)
  264. {
  265.         WCHAR szKernelFullName[256];
  266.         RtlZeroMemory(szKernelFullName, 256 * sizeof(WCHAR));

  267.         GetKernelFilePath(szKernelFullName);

  268.         NTSTATUS Status;
  269.         HANDLE hFile;
  270.         OBJECT_ATTRIBUTES ObjAttr;
  271.         UNICODE_STRING usFileName;
  272.         IO_STATUS_BLOCK IoStatusBlock;
  273.         LARGE_INTEGER FileOffset;

  274.         IMAGE_DOS_HEADER ImageDosHeader;
  275.         IMAGE_NT_HEADERS ImageNtHeader;
  276.         IMAGE_SECTION_HEADER *pImageSectionHeader;


  277.         PVOID lpVirtualPointer;
  278.         ULONG SectionVirtualAddress, SizeOfSection;
  279.         ULONG PointerToRawData;
  280.         ULONG uIndex;

  281.         RtlInitUnicodeString(&usFileName, szKernelFullName);

  282.         InitializeObjectAttributes(&ObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

  283.         if (!MmIsAddressValid(szKernelFullName))
  284.         {
  285.                 return STATUS_UNSUCCESSFUL;
  286.         }

  287.         Status = ZwCreateFile(&hFile, GENERIC_ALL, &ObjAttr, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
  288.                 FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

  289.         if (!NT_SUCCESS(Status))
  290.         {
  291.                 KdPrint(("ZwCreateFile Failed:%X\n",Status));
  292.                 return Status;
  293.         }

  294.         FileOffset.QuadPart = 0;
  295.         Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, &ImageDosHeader, sizeof(IMAGE_DOS_HEADER),
  296.                 &FileOffset, NULL);
  297.         if (!NT_SUCCESS(Status))
  298.         {
  299.                 KdPrint(("read IMAGE_DOS_HEADER Failed:%X\n",Status));
  300.                 ZwClose(hFile);
  301.                 return Status;
  302.         }

  303.         FileOffset.QuadPart = ImageDosHeader.e_lfanew;
  304.         Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, &ImageNtHeader, sizeof(IMAGE_NT_HEADERS),
  305.                 &FileOffset, NULL);
  306.         if (!NT_SUCCESS(Status))
  307.         {
  308.                 KdPrint(("read IMAGE_NT_HEADERS Failed:%X\n",Status));
  309.                 ZwClose(hFile);
  310.                 return Status;
  311.         }

  312.         pImageSectionHeader = (IMAGE_SECTION_HEADER *)ExAllocatePool(PagedPool,
  313.                 sizeof(IMAGE_SECTION_HEADER) * ImageNtHeader.FileHeader.NumberOfSections);

  314.         if (pImageSectionHeader == 0)
  315.         {
  316.                 KdPrint(("pImageSectionHeader is null!\n"));
  317.                 ZwClose(hFile);
  318.                 return STATUS_UNSUCCESSFUL;
  319.         }
  320.         FileOffset.QuadPart += sizeof(IMAGE_NT_HEADERS);
  321.         Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, pImageSectionHeader,
  322.                 sizeof(IMAGE_SECTION_HEADER) * ImageNtHeader.FileHeader.NumberOfSections, &FileOffset, NULL);
  323.         if (!NT_SUCCESS(Status))
  324.         {
  325.                 KdPrint(("read IMAGE_SECTION_HEADER Failed:%X\n",Status));
  326.                 ZwClose(hFile);
  327.                 ExFreePool(pImageSectionHeader);
  328.                 return Status;
  329.         }

  330.         ULONG uSizeOfImage = ImageNtHeader.OptionalHeader.SizeOfImage;

  331.         lpVirtualPointer = ExAllocatePool(PagedPool, ImageNtHeader.OptionalHeader.SizeOfImage);
  332.         if (lpVirtualPointer == 0)
  333.         {
  334.                 KdPrint(("lpVirtualPointer is null!\n"));
  335.                 ZwClose(hFile);
  336.                 ExFreePool(pImageSectionHeader);
  337.                 return STATUS_UNSUCCESSFUL;
  338.         }

  339.         memset(lpVirtualPointer, 0, ImageNtHeader.OptionalHeader.SizeOfImage);
  340.         RtlCopyMemory(lpVirtualPointer, &ImageDosHeader, sizeof(IMAGE_DOS_HEADER));
  341.         RtlCopyMemory((PVOID)((ULONG)lpVirtualPointer + ImageDosHeader.e_lfanew), &ImageNtHeader, sizeof(IMAGE_NT_HEADERS));
  342.         RtlCopyMemory((PVOID)((ULONG)lpVirtualPointer + ImageDosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)),
  343.                 pImageSectionHeader, sizeof(IMAGE_SECTION_HEADER) * ImageNtHeader.FileHeader.NumberOfSections);


  344.         for (uIndex = 0; uIndex < ImageNtHeader.FileHeader.NumberOfSections; uIndex++)
  345.         {
  346.                 SectionVirtualAddress = pImageSectionHeader[uIndex].VirtualAddress;
  347.                 SizeOfSection = pImageSectionHeader[uIndex].SizeOfRawData;
  348.                 PointerToRawData = pImageSectionHeader[uIndex].PointerToRawData;

  349.                 FileOffset.QuadPart = PointerToRawData;
  350.                 Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)((ULONG)lpVirtualPointer + SectionVirtualAddress),
  351.                         SizeOfSection, &FileOffset, NULL);
  352.                 if (!NT_SUCCESS(Status))
  353.                 {
  354.                         KdPrint(("read failed is pImageSectionHeader[%d]:%X\n",uIndex, Status));
  355.                         ZwClose(hFile);
  356.                         ExFreePool(pImageSectionHeader);
  357.                         ExFreePool(lpVirtualPointer);
  358.                         return Status;
  359.                 }
  360.         }
  361.        
  362.        
  363.         ULONG uKernelBase = GetKernelBase((ULONG)lpVirtualPointer);

  364.         BOOLEAN bRet = LdrRelocateImage(lpVirtualPointer, (PUCHAR)uKernelBase);
  365.         if (bRet)
  366.         {
  367.                 SetNewSSDT(lpVirtualPointer, (PVOID)uKernelBase, &g_pNewSSDT);
  368.         }

  369.         *pKernelBase = uKernelBase;
  370.         *pLoadImageBase = (ULONG)lpVirtualPointer;


  371.         if (hFile != NULL)
  372.         {
  373.                 ZwClose(hFile);
  374.         }
  375.         return Status;
  376. }


  377. void UnKernelFile(ULONG uLoadImageBase)
  378. {
  379.         if (uLoadImageBase != 0)
  380.         {
  381.                 ExFreePool((PVOID)uLoadImageBase);
  382.         }
  383. }


  384. #pragma INITCODE
  385. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  386. {
  387.     NTSTATUS status = STATUS_SUCCESS;
  388.        
  389.         LoadKernelFile(&g_uKernelBase, &g_uImageBase);       

  390.     DriverObject->DriverUnload = DriverUnload;
  391.     return status;
  392. }

  393. #pragma PAGEDCODE
  394. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  395. {
  396.   
  397.         UnKernelFile(g_uImageBase);
  398.     KdPrint(("DriverEntry unLoading...\n"));
  399.   
  400. }
复制代码

返回列表