MalwareSourceCode/Win32/Proof of Concepts/CheckKernelEATHook/CheckKernelHookDrv/CheckKernelHook/KernelReload.c
vxunderground 900263ea6f updates and moves
n/a
2022-04-11 20:00:13 -05:00

821 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;Index<NumberOfSections;Index++)
{
ImageSectionHeader[Index].SizeOfRawData=AlignSize(ImageSectionHeader[Index].SizeOfRawData,FileAlignment);
ImageSectionHeader[Index].Misc.VirtualSize=AlignSize(ImageSectionHeader[Index].Misc.VirtualSize,SectionAlignment);
}
if (ImageSectionHeader[NumberOfSections-1].VirtualAddress+ImageSectionHeader[NumberOfSections-1].SizeOfRawData>SizeOfImage)
{//no in
ImageSectionHeader[NumberOfSections-1].SizeOfRawData = SizeOfImage-ImageSectionHeader[NumberOfSections-1].VirtualAddress;
}
RtlCopyMemory(ImageBase,FileBuffer,SizeOfHeaders);
for (Index=0;Index<NumberOfSections;Index++)
{
DWORD FileOffset=ImageSectionHeader[Index].PointerToRawData;
DWORD Length=ImageSectionHeader[Index].SizeOfRawData;
DWORD ImageOffset=ImageSectionHeader[Index].VirtualAddress;
RtlCopyMemory(&ImageBase[ImageOffset],&FileBuffer[FileOffset],Length);
}
*ImageModuleBase=ImageBase;
return TRUE;
}
ULONG AlignSize(ULONG nSize, ULONG nAlign)
{
return ((nSize + nAlign - 1) / nAlign * nAlign);
}
/*
通过DriverObject->DriverSection 遍历 内核模块
*/
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;
}