#include "KernelReload.h" #include "FileSystem.h" #include "FixRelocation.h" /*ZwQuerySystemInformation大法 枚举模块信息 获得第一模块 Ntos..*/ BOOLEAN GetSystemKernelModuleInfo(WCHAR **SystemKernelModulePath,PDWORD SystemKernelModuleBase,PDWORD SystemKernelModuleSize) { NTSTATUS status; ULONG ulSize,i; PMODULES pModuleList; char *lpszKernelName=NULL; ANSI_STRING AnsiKernelModule; UNICODE_STRING UnicodeKernelModule; BOOLEAN bRet=TRUE; __try { status=ZwQuerySystemInformation( SystemModuleInformation, NULL, 0, &ulSize ); if (status != STATUS_INFO_LENGTH_MISMATCH) { return FALSE; } pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,ulSize); if (pModuleList) { status=ZwQuerySystemInformation( SystemModuleInformation, pModuleList, ulSize, &ulSize ); if (!NT_SUCCESS(status)) { bRet = FALSE; } } if (!bRet) { if (pModuleList) ExFreePool(pModuleList); return FALSE; } *SystemKernelModulePath=ExAllocatePool(NonPagedPool,260*2); if (*SystemKernelModulePath==NULL) { *SystemKernelModuleBase=0; *SystemKernelModuleSize=0; return FALSE; } lpszKernelName = pModuleList->smi[0].ModuleNameOffset+pModuleList->smi[0].ImageName; //第一模块名称 RtlInitAnsiString(&AnsiKernelModule,lpszKernelName); RtlAnsiStringToUnicodeString(&UnicodeKernelModule,&AnsiKernelModule,TRUE); RtlZeroMemory(*SystemKernelModulePath,260*2); wcscat(*SystemKernelModulePath,L"\\SystemRoot\\system32\\"); memcpy( *SystemKernelModulePath+wcslen(L"\\SystemRoot\\system32\\"), //第一模块路径 UnicodeKernelModule.Buffer, UnicodeKernelModule.Length ); *SystemKernelModuleBase=(DWORD)pModuleList->smi[0].Base; //获得第一模块地址 *SystemKernelModuleSize=(DWORD)pModuleList->smi[0].Size; //获得第一模块大小 ExFreePool(pModuleList); RtlFreeUnicodeString(&UnicodeKernelModule); }__except(EXCEPTION_EXECUTE_HANDLER){ } return TRUE; } /*获得文件对象中DeviceObject和RealDevice*/ BOOLEAN IoGetFileSystemVpbInfo(IN PFILE_OBJECT FileObject,PDEVICE_OBJECT *DeviceObject,PDEVICE_OBJECT *RealDevice) { //PDEVICE_OBJECT deviceObject; // If the file object has a mounted Vpb, use its DeviceObject. if(FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL) { *DeviceObject = FileObject->Vpb->DeviceObject; *RealDevice= FileObject->Vpb->RealDevice; // Otherwise, if the real device has a VPB that indicates that it is mounted, // then use the file system device object associated with the VPB. } else if ( !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) && FileObject->DeviceObject->Vpb != NULL && FileObject->DeviceObject->Vpb->DeviceObject != NULL ) { *DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject; *RealDevice = FileObject->DeviceObject->Vpb->RealDevice; // Otherwise, just return the real device object. } else { *DeviceObject = FileObject->DeviceObject; *RealDevice=NULL; } if (*RealDevice==NULL||*DeviceObject==NULL) { return FALSE; } // Simply return the resultant file object. return TRUE; } //获得FileObject中的RealDevice和DeviceObject BOOLEAN GetDeviceObjectFromFileFullName(WCHAR *FileFullName,PDEVICE_OBJECT *RealDevice, PDEVICE_OBJECT *DeviceObject) { WCHAR wRootName[32]={0}; UNICODE_STRING RootName; OBJECT_ATTRIBUTES ObjectAttributes={0}; NTSTATUS status; HANDLE hFile; IO_STATUS_BLOCK IoStatus; PFILE_OBJECT FileObject; if (FileFullName[0]==0x005C) {//in \Windows\system32\ntkrnlpa.exe wcscpy(wRootName,L"\\SystemRoot"); } else { wcscpy(wRootName,L"\\DosDevices\\*:\\"); wRootName[12]=FileFullName[0]; } RtlInitUnicodeString(&RootName,wRootName); InitializeObjectAttributes(&ObjectAttributes, &RootName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); //RootName.Buffer = "\SystemRoot" status = IoCreateFile( &hFile, SYNCHRONIZE, &ObjectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, 0, NULL, IO_NO_PARAMETER_CHECKING); if (!NT_SUCCESS(status)) { return FALSE; } status=ObReferenceObjectByHandle(hFile,1,*IoFileObjectType,KernelMode,&FileObject,NULL); if (!NT_SUCCESS(status)) { ZwClose(hFile); return FALSE; } if(!IoGetFileSystemVpbInfo(FileObject,DeviceObject,RealDevice)) //获得FileObject中的deviceObject和RealDevice { ObfDereferenceObject(FileObject); ZwClose(hFile); return FALSE; } ObfDereferenceObject(FileObject); ZwClose(hFile); return TRUE; } /*获得系统目录*/ BOOLEAN GetWindowsRootName(WCHAR *WindowsRootName) { UNICODE_STRING RootName,ObjectName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hLink; NTSTATUS status; WCHAR *SystemRootName=(WCHAR*)0x7FFE0030; WCHAR *ObjectNameBuffer=(WCHAR*)ExAllocatePool(NonPagedPool,260*2); if (ObjectNameBuffer==NULL) { return FALSE; } RtlZeroMemory(ObjectNameBuffer,260*2); RtlInitUnicodeString(&RootName,L"\\SystemRoot"); InitializeObjectAttributes(&ObjectAttributes,&RootName,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); status=ZwOpenSymbolicLinkObject(&hLink,1,&ObjectAttributes); if (NT_SUCCESS(status)) { ObjectName.Buffer=ObjectNameBuffer; ObjectName.Length=0; ObjectName.MaximumLength=260*2; status=ZwQuerySymbolicLinkObject(hLink,&ObjectName,NULL); //ObjectNameBuffer \Device\Harddisk0\Partition1\Windows if (NT_SUCCESS(status)) { int ObjectNameLength=ObjectName.Length/2; int Index; for (Index=ObjectNameLength-1;Index>0;Index--) { if (ObjectNameBuffer[Index]==0x005C) { if (!MmIsAddressValid(&WindowsRootName[ObjectNameLength-Index])) { break; } //\Windows WindowsRootName RtlCopyMemory(WindowsRootName,&ObjectNameBuffer[Index],(ObjectNameLength-Index)*2); ExFreePool(ObjectNameBuffer); return TRUE; } } } } ExFreePool(ObjectNameBuffer); if (!MmIsAddressValid(SystemRootName)) { return FALSE; } if (SystemRootName[1]!=0x003A||SystemRootName[2]!=0x005C) { return FALSE; } wcscpy(WindowsRootName,&SystemRootName[2]); return TRUE; } /* 自己创建文件对象,挂入FileObject->IrpList 并返回文件句柄 */ //\SystemRoot\system32\ntkrnlpa.exe NTSTATUS KernelOpenFile(wchar_t *FileFullName, PHANDLE FileHandle, ACCESS_MASK DesiredAccess, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions) { WCHAR SystemRootName[32]=L"\\SystemRoot"; WCHAR *FileNodeName=NULL; UNICODE_STRING FilePath; PDEVICE_OBJECT RealDevice,DeviceObject; NTSTATUS status=STATUS_UNSUCCESSFUL; PFILE_OBJECT FileObject; FileNodeName=ExAllocatePool(NonPagedPool,260*2); if (FileNodeName==NULL) { return status; } RtlZeroMemory(FileNodeName,260*2); if (_wcsnicmp(FileFullName,SystemRootName,wcslen(SystemRootName))==0) //忘记相等返回什么了 不过应该是不完整路径 这里面是修复 { //in int Len; if(!GetWindowsRootName(FileNodeName)) // \Windows { ExFreePool(FileNodeName); return status; } Len=wcslen(SystemRootName); wcscat(FileNodeName,&FileFullName[Len]); //FileNodeName == \Windows\system32\ntkrnlpa.exe //FileFullName == \SystemRoot\system32\ntkrnlpa.exe } else { if (FileFullName[1]!=0x003A||FileFullName[2]!=0x005C) { return status; } wcscpy(FileNodeName,&FileFullName[2]); } if(!GetDeviceObjectFromFileFullName(FileFullName,&RealDevice,&DeviceObject)) //获得FileObject中的DeviceObject和RealDevice { ExFreePool(FileNodeName); return status; } //FileNodeName == \Windows\system32\ntkrnlpa.exe RtlInitUnicodeString(&FilePath,FileNodeName); status=IrpCreateFile(&FilePath,DesiredAccess,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,DeviceObject,RealDevice,&FileObject); //创建文件对象 挂入FileObject->IrpList中 if (!NT_SUCCESS(status)) { ExFreePool(FileNodeName); return status; } //根据文件对象,获得文件句柄 status=ObOpenObjectByPointer( FileObject, OBJ_KERNEL_HANDLE, //verifier下测试要指定OBJ_KERNEL_HANDLE 0, DesiredAccess|0x100000, *IoFileObjectType, 0, FileHandle); ObfDereferenceObject(FileObject); return status; } //查询irp信息,返回filesize NTSTATUS KernelGetFileSize(HANDLE hFile, PLARGE_INTEGER FileSize) { NTSTATUS status; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject,RealDevice; FILE_STANDARD_INFORMATION FileInformation; status=ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &FileObject, 0); if (!NT_SUCCESS(status)) { return status; } if(!IoGetFileSystemVpbInfo(FileObject,&DeviceObject,&RealDevice)) { ObDereferenceObject(FileObject); return STATUS_UNSUCCESSFUL; } //查询irp堆栈信息,传入FileObject status=IrpQueryInformationFile(FileObject,DeviceObject,&FileInformation,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation); if (!NT_SUCCESS(status)) { ObDereferenceObject(FileObject); return status; } FileSize->HighPart=FileInformation.EndOfFile.HighPart; FileSize->LowPart=FileInformation.EndOfFile.LowPart; ObDereferenceObject(FileObject); return status; } /* 传入文件句柄、文件大小读取文件到内存中 */ NTSTATUS KernelReadFile(HANDLE hFile, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID FileBuffer, PIO_STATUS_BLOCK IoStatusBlock) { NTSTATUS status; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject,RealDevice; FILE_STANDARD_INFORMATION FileInformation; status=ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &FileObject, 0); if (!NT_SUCCESS(status)) { return status; } if(!IoGetFileSystemVpbInfo(FileObject,&DeviceObject,&RealDevice)) { ObDereferenceObject(FileObject); return STATUS_UNSUCCESSFUL; } status=IrpReadFile(FileObject,DeviceObject,IoStatusBlock,FileBuffer,Length,ByteOffset); //Irp请求,将文件读入缓冲区中 ObDereferenceObject(FileObject); return status; } /* 修复FileBuffer中的偏移 按照VirtualAglin 对齐 filebuffer 为读取的内存 ,ImageModuleBase为系统中的模块地址 */ BOOLEAN ImageFile(BYTE *FileBuffer,BYTE **ImageModuleBase) { PIMAGE_DOS_HEADER ImageDosHeader; PIMAGE_NT_HEADERS ImageNtHeaders; PIMAGE_SECTION_HEADER ImageSectionHeader; DWORD FileAlignment,SectionAlignment,NumberOfSections,SizeOfImage,SizeOfHeaders; DWORD Index; BYTE *ImageBase; DWORD SizeOfNtHeaders; ImageDosHeader=(PIMAGE_DOS_HEADER)FileBuffer; if (ImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { return FALSE; } ImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuffer+ImageDosHeader->e_lfanew); if (ImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE) { return FALSE; } FileAlignment=ImageNtHeaders->OptionalHeader.FileAlignment;//0x200 SectionAlignment=ImageNtHeaders->OptionalHeader.SectionAlignment;//0x1000 NumberOfSections=ImageNtHeaders->FileHeader.NumberOfSections;//0x16 SizeOfImage=ImageNtHeaders->OptionalHeader.SizeOfImage;//0x412000 SizeOfHeaders=ImageNtHeaders->OptionalHeader.SizeOfHeaders;//0x800 SizeOfImage=AlignSize(SizeOfImage,SectionAlignment);//0x412000 ImageBase=ExAllocatePool(NonPagedPool,SizeOfImage); if (ImageBase==NULL) { return FALSE; } RtlZeroMemory(ImageBase,SizeOfImage); //0xf8 SizeOfNtHeaders=sizeof(ImageNtHeaders->FileHeader) + sizeof(ImageNtHeaders->Signature)+ImageNtHeaders->FileHeader.SizeOfOptionalHeader; ImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)ImageNtHeaders+SizeOfNtHeaders); for (Index=0;IndexSizeOfImage) {//no in ImageSectionHeader[NumberOfSections-1].SizeOfRawData = SizeOfImage-ImageSectionHeader[NumberOfSections-1].VirtualAddress; } RtlCopyMemory(ImageBase,FileBuffer,SizeOfHeaders); for (Index=0;IndexDriverSection 遍历 内核模块 */ PVOID GetKernelModuleBase(PDRIVER_OBJECT DriverObject,char *KernelModuleName) { PLDR_DATA_TABLE_ENTRY DriverSection,LdrEntry; ANSI_STRING AnsiKernelModuleName; UNICODE_STRING UniKernelModuleName; UNICODE_STRING ModuleName; WCHAR *Buffer; int Lentgh,Index; RtlInitAnsiString(&AnsiKernelModuleName,KernelModuleName); RtlAnsiStringToUnicodeString(&UniKernelModuleName,&AnsiKernelModuleName,TRUE); Buffer=ExAllocatePool(NonPagedPool,260*2); if (Buffer==NULL) { return NULL; } RtlZeroMemory(Buffer,206*2); DriverSection=DriverObject->DriverSection; LdrEntry=(PLDR_DATA_TABLE_ENTRY)DriverSection->InLoadOrderLinks.Flink; while (LdrEntry&&DriverSection!=LdrEntry) { //(DWORD)LdrEntry->DllBase>=*(DWORD*)MmSystemRangeStart&& if (LdrEntry->FullDllName.Length>0&& LdrEntry->FullDllName.Buffer!=NULL) { if (MmIsAddressValid(&LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length/2-1])) { Lentgh=LdrEntry->FullDllName.Length/2; for (Index=Lentgh-1;Index>0;Index--) { if (LdrEntry->FullDllName.Buffer[Index]==0x005C) { break; } } if (LdrEntry->FullDllName.Buffer[Index]==0x005C) { RtlCopyMemory(Buffer,&(LdrEntry->FullDllName.Buffer[Index+1]),(Lentgh-Index-1)*2); ModuleName.Buffer=Buffer; ModuleName.Length=(Lentgh-Index-1)*2; ModuleName.MaximumLength=260*2; } else { RtlCopyMemory(Buffer,LdrEntry->FullDllName.Buffer,Lentgh*2); ModuleName.Buffer=Buffer; ModuleName.Length=Lentgh*2; ModuleName.MaximumLength=260*2; } if (RtlEqualUnicodeString(&ModuleName,&UniKernelModuleName,TRUE)) { ExFreePool(Buffer); return LdrEntry->DllBase; } } } LdrEntry=(PLDR_DATA_TABLE_ENTRY)LdrEntry->InLoadOrderLinks.Flink; } ExFreePool(Buffer); return NULL; } /* 通过导出表获得函数地址 */ PVOID MiFindExportedRoutine ( IN PVOID DllBase, BOOLEAN ByName, IN char *RoutineName, DWORD Ordinal ) { USHORT OrdinalNumber; PULONG NameTableBase; PUSHORT NameOrdinalTableBase; PULONG AddressTableBase; PULONG Addr; LONG High; LONG Low; LONG Middle; LONG Result; ULONG ExportSize; PVOID FunctionAddress; PIMAGE_EXPORT_DIRECTORY ExportDirectory; PAGED_CODE(); //获得导出表 ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData ( DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize); if (ExportDirectory == NULL) { return NULL; } NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames); NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals); AddressTableBase=(PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions); if (!ByName) { return (PVOID)AddressTableBase[Ordinal]; } Low = 0; Middle = 0; High = ExportDirectory->NumberOfNames - 1; while (High >= Low) { Middle = (Low + High) >> 1; Result = strcmp (RoutineName, (PCHAR)DllBase + NameTableBase[Middle]); if (Result < 0) { High = Middle - 1; } else if (Result > 0) { Low = Middle + 1; } else { break; } } if (High < Low) { return NULL; } OrdinalNumber = NameOrdinalTableBase[Middle]; if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) { return NULL; } Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions); FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]); // // Forwarders are not used by the kernel and HAL to each other. // ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) || (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize))); return FunctionAddress; } BOOLEAN InsertOriginalFirstThunk(DWORD ImageBase,DWORD ExistImageBase,PIMAGE_THUNK_DATA FirstThunk) { DWORD Offset; PIMAGE_THUNK_DATA OriginalFirstThunk; Offset=(DWORD)FirstThunk-ImageBase; OriginalFirstThunk=(PIMAGE_THUNK_DATA)(ExistImageBase+Offset); while (OriginalFirstThunk->u1.Function) { FirstThunk->u1.Function=OriginalFirstThunk->u1.Function; OriginalFirstThunk++; FirstThunk++; } return TRUE; } //修复导入表 BOOLEAN FixImportTable(BYTE *ImageBase,DWORD ExistImageBase,PDRIVER_OBJECT DriverObject) { PIMAGE_IMPORT_DESCRIPTOR ImageImportDescriptor=NULL; PIMAGE_THUNK_DATA ImageThunkData,FirstThunk; PIMAGE_IMPORT_BY_NAME ImortByName; DWORD ImportSize; PVOID ModuleBase; char ModuleName[260]; DWORD FunctionAddress; //得到导入表地址 ImageImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(ImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ImportSize); if (ImageImportDescriptor==NULL) { return FALSE; } while (ImageImportDescriptor->OriginalFirstThunk&&ImageImportDescriptor->Name) { strcpy(ModuleName,(char*)(ImageBase+ImageImportDescriptor->Name)); //导入信息名称 //ntoskrnl.exe(NTKRNLPA.exe、ntkrnlmp.exe、ntkrpamp.exe): if (_stricmp(ModuleName,"ntkrnlpa.exe")==0|| _stricmp(ModuleName,"ntoskrnl.exe")==0|| _stricmp(ModuleName,"ntkrnlmp.exe")==0|| _stricmp(ModuleName,"ntkrpamp.exe")==0) {//no in ModuleBase=GetKernelModuleBase(DriverObject,"ntkrnlpa.exe"); //通过DriverObject->DriverSection 遍历内核模块 if (ModuleBase==NULL) { ModuleBase=GetKernelModuleBase(DriverObject,"ntoskrnl.exe"); if (ModuleBase==NULL) { ModuleBase=GetKernelModuleBase(DriverObject,"ntkrnlmp.exe"); if (ModuleBase==NULL) { ModuleBase=GetKernelModuleBase(DriverObject,"ntkrpamp.exe"); } } } } else { ModuleBase=GetKernelModuleBase(DriverObject,ModuleName); } if (ModuleBase==NULL) { FirstThunk=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->FirstThunk); InsertOriginalFirstThunk((DWORD)ImageBase,ExistImageBase,FirstThunk); ImageImportDescriptor++; continue; } //PSHED.dll ImageThunkData=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->OriginalFirstThunk); FirstThunk=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->FirstThunk); while(ImageThunkData->u1.Ordinal) { //序号导入 if(IMAGE_SNAP_BY_ORDINAL32(ImageThunkData->u1.Ordinal)) { //通过系统内核的导出表 名称- 获得 函数地址 FunctionAddress=(DWORD)MiFindExportedRoutine(ModuleBase,FALSE,NULL,ImageThunkData->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32); if (FunctionAddress==0) { return FALSE; } FirstThunk->u1.Function=FunctionAddress; } //函数名导入 else { // ImortByName=(PIMAGE_IMPORT_BY_NAME)(ImageBase+ImageThunkData->u1.AddressOfData); FunctionAddress=(DWORD)MiFindExportedRoutine(ModuleBase,TRUE,ImortByName->Name,0); if (FunctionAddress==0) { return FALSE; } FirstThunk->u1.Function=FunctionAddress; } FirstThunk++; ImageThunkData++; } ImageImportDescriptor++; } return TRUE; } /* system32//NtosKrnl.exe .. */ BOOLEAN PeLoad( WCHAR *FileFullPath, BYTE **ImageModeleBase, PDRIVER_OBJECT DeviceObject, DWORD ExistImageBase ) { NTSTATUS Status; HANDLE hFile; LARGE_INTEGER FileSize; DWORD Length; BYTE *FileBuffer; BYTE *ImageBase; IO_STATUS_BLOCK IoStatus; //\SystemRoot\system32\ntkrnlpa.exe Status=KernelOpenFile(FileFullPath,&hFile,0x100020,0x80,1,1,0x20); //自己创建文件对象,挂入FileObject->IrpList 并返回文件句柄 if (!NT_SUCCESS(Status)) { return FALSE; } Status=KernelGetFileSize(hFile,&FileSize); //读取irp信息,返回filesize if (!NT_SUCCESS(Status)) { ZwClose(hFile); return FALSE; } Length=FileSize.LowPart; FileBuffer=ExAllocatePool(PagedPool,Length); if (FileBuffer==NULL) { ZwClose(hFile); return FALSE; } Status=KernelReadFile(hFile,NULL,Length,FileBuffer,&IoStatus); //传入文件句柄、文件大小 通过irp请求,读取文件到内存中 if (!NT_SUCCESS(Status)) { ZwClose(hFile); ExFreePool(FileBuffer); return FALSE; } ZwClose(hFile); if(!ImageFile(FileBuffer,&ImageBase)) //修复FileBuffer中的偏移 按照VirtualAglin 对齐 得到全局ImageModuleBase { ExFreePool(FileBuffer); return FALSE; } ExFreePool(FileBuffer); //2k3下MiFindExportedRoutine调用失败 if(!FixImportTable(ImageBase,ExistImageBase,DeviceObject)) //修复导入表 { ExFreePool(ImageBase); return FALSE; } if(!FixBaseRelocTable(ImageBase,ExistImageBase)) //修复重定位表 { ExFreePool(ImageBase); return FALSE; } *ImageModeleBase=ImageBase; //得到最后的基地址 就是 和 原来内存中格式一样的 一块ntos return TRUE; }