updates and moves

n/a
This commit is contained in:
vxunderground
2022-04-11 20:00:13 -05:00
parent 1275ea2e03
commit 900263ea6f
809 changed files with 149115 additions and 1594 deletions
@@ -0,0 +1,820 @@
#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;
}