功能模块
枚举Hook()
PE与内核重载
内核模块(驱动)
内核信息(线程,DPC定时器,系统回调)
过滤驱动
DISPATCH例程
系统进程
系统服务
网络连接(TCP/UDP端口与IP)
删文件(强删文件思路,正在运行中的程序,sectionObject里面的值清0,构造个IRP下发,独占的就去全局句柄表拷贝句柄,然后关掉,对于硬链接(不夸磁盘盘符的,通过引用计数,软连接是快捷方式)占坑的方式是XCB,或者磁盘填0删除)
杀进程(通过线程插入APC,通常线程运行的级别是PASSIVE_LEVEL,插入APC的话级别高,优先运行,就杀掉了。还可以通过ZwTerminateProcess更低的PspTerminateProcess)
禁止驱动加载
禁止进程创建
禁止文件创建
DriverEntry流程
应用层和内核层通信不是走到DeviceIoControl,通过Hook了ZwCreateFile,SSDT的NtReadFile。把其中的handle设置为控制码。所以如果为了方便以后观摩a盾的某些功能就去NtReadFile去查看。SSDThook也不一样,正常是拿SSDFT表首地址,然后通过eax(xp是ZW函数起始加1就是索引,后面版本搜索eax)拿index。然后找到函数地址。A盾是通过函数名字,解析ntdll.dll文件,找到索引号。通过将其加载到内存,再解析pe文件导出表,所以不能在x64运行。
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath )
{
ULONG ulSize;
ULONG ulKeServiceDescriptorTable;
int i = 0;
PEPROCESS EProcess;
HANDLE HThreadHandle;
HANDLE ThreadHandle;
DriverObject->DriverUnload = DriverUnload;
PDriverObject = DriverObject;//PDriverObject全局对象记录驱动对象
RetAddress=*(DWORD*)((DWORD)&DriverObject-4);//驱动调用约定是stdcall,所以栈从下到上依次是theRegistryPath,DriverObject,返回地址,老ebp,局部变量。DriverObject-4就是返回地址
//返回地址再Ntskernl.dll中因为是系统调用了driverEntry,拿返回地址为了栈回溯
ulMyDriverBase = DriverObject->DriverStart;
ulMyDriverSize = DriverObject->DriverSize;
DebugOn = FALSE; //开启调式信息
KdPrint(("//---------------------------------------//\r\n"
"// A-Protect Anti-Rootkit Kernel Module //\r\n"
"// Kernel Module Version 0.2.5 //\r\n"
"// website:http://www.3600safe.com //\r\n"
"//---------------------------------------//\r\n"));
//DriverEntry处于system上下文,拿到Eprocess属于系统的eprocess
SystemEProcess = PsGetCurrentProcess();
WinVersion = GetWindowsVersion(); //初始化系统版本
if (WinVersion)
KdPrint(("Init Windows version Success\r\n"));
DepthServicesRegistry = NULL;
//-----------------------------------------
//注册一个系统回调
if (PsCreateSystemThread(
&HThreadHandle,
0,
NULL,
NULL,
NULL,
IsKernelBooting,
NULL) == STATUS_SUCCESS)
{
ZwClose(HThreadHandle);
}
return STATUS_SUCCESS;
}
WIN_VER_DETAIL GetWindowsVersion()
{
UNICODE_STRING ustrFuncName = { 0 };
RTL_OSVERSIONINFOEXW osverinfo = { sizeof(osverinfo) };
PFN_RtlGetVersion pfnRtlGetVersion = NULL;
if (WinVersion)
return WinVersion;
RtlInitUnicodeString(&ustrFuncName, L"RtlGetVersion");
pfnRtlGetVersion = MmGetSystemRoutineAddress(&ustrFuncName); //根据函数名字拿地址,不直接用RtlGetVersion,而是这样,因为RtlGetVersion不是所有系统都有的
if (pfnRtlGetVersion)
{
pfnRtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo);
}
else
{
PsGetVersion(&osverinfo.dwMajorVersion, &osverinfo.dwMinorVersion, &osverinfo.dwBuildNumber, NULL);
}
// KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n",
// osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber,
// osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));
if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0)
{
WinVersion = WINDOWS_VERSION_2K;
}
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1)
{
WinVersion = WINDOWS_VERSION_XP;
}
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2)
{
if (osverinfo.wServicePackMajor==0)
{
WinVersion = WINDOWS_VERSION_2K3;
}
else
{
WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
}
}
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0)
{
WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
}
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1)
{
WinVersion = WINDOWS_VERSION_7;
}
return WinVersion;
}
VOID IsKernelBooting(IN PVOID Context)
{
PEPROCESS EProcess;
NTSTATUS status;
PUCHAR KiFastCallEntry;
while (1)
{
EProcess = NULL;
if (LookupProcessByName("Smss.exe",&EProcess) == STATUS_SUCCESS)//自己写查找进程链里有无这个smss的进程。eprocess里的imageName就是名字
//eprocess未导出。可以硬编码便宜长度,driverEntry拿到system的eprocess结构,然后自己的eprocess的imagename偏移距离其他eprocess应该一样。
//找smss因为,这个内核会启动会话管理器(Session Manager)这个是windows系统中,第一个创建的用户模式进程,其作用如下
/*
1.创建系统环境变量
2.启动win32k.sys,这是windows子系统的内核模式部分
3.启动csrss,这个是windows子系统用户模式部分
4.启动winlogon.exe
5.创建虚拟内存页面文件
6.对一些必要的文件进行改名,(主要是驱动文件,如果更新后,下次重启跟新)
*/
{
_asm
{//获取kifastcall,应用层进内核入口,检测隐藏进程
pushad;
mov ecx, 0x176;
rdmsr;
mov KiFastCallEntry, eax;
popad;
}
if (*KiFastCallEntry == 0xe9)//jmp,意味着被hook了
{
KdPrint(("Terminate System Thread"));
PsTerminateSystemThread(STATUS_SUCCESS);
}
if (ReLoadNtos(PDriverObject,RetAddress) == STATUS_SUCCESS)//重载内核
{
InitControl();
if (bKernelBooting)
{
//---------------------------------------
//demo,深度服务扫描隐藏
//---------------------------------------
DepthServicesRegistry = (PSERVICESREGISTRY)ExAllocatePool(NonPagedPool,(sizeof(SERVICESREGISTRY)+sizeof(SERVICESREGISTRY_INFORMATION))*1024);
if (DepthServicesRegistry)
{
memset(DepthServicesRegistry,0,(sizeof(SERVICESREGISTRY)+sizeof(SERVICESREGISTRY_INFORMATION))*1024);
status = QueryServicesRegistry(DepthServicesRegistry);
if (status == STATUS_SUCCESS)
{
Safe_CreateValueKey(
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\3600safe",
REG_SZ,
L"QueryServicesRegistry",
L"success"
);
}
}
bKernelBooting = FALSE;
}
PsTerminateSystemThread(STATUS_SUCCESS);
}else
{
//不是随机启动,就退出线程
if (!bKernelBooting)
PsTerminateSystemThread(STATUS_SUCCESS);
}
}
else
{
bKernelBooting = TRUE;
}
WaitMicroSecond(1000);
}
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath )
{
ULONG ulSize;
ULONG ulKeServiceDescriptorTable;
int i = 0;
PEPROCESS EProcess;
HANDLE HThreadHandle;
HANDLE ThreadHandle;
DriverObject->DriverUnload = DriverUnload;
PDriverObject = DriverObject;//PDriverObject全局对象记录驱动对象
RetAddress=*(DWORD*)((DWORD)&DriverObject-4);//驱动调用约定是stdcall,所以栈从下到上依次是theRegistryPath,DriverObject,返回地址,老ebp,局部变量。DriverObject-4就是返回地址
//返回地址再Ntskernl.dll中因为是系统调用了driverEntry,拿返回地址为了栈回溯
ulMyDriverBase = DriverObject->DriverStart;
ulMyDriverSize = DriverObject->DriverSize;
DebugOn = FALSE; //开启调式信息
KdPrint(("//---------------------------------------//\r\n"
"// A-Protect Anti-Rootkit Kernel Module //\r\n"
"// Kernel Module Version 0.2.5 //\r\n"
"// website:http://www.3600safe.com //\r\n"
"//---------------------------------------//\r\n"));
//DriverEntry处于system上下文,拿到Eprocess属于系统的eprocess
SystemEProcess = PsGetCurrentProcess();
WinVersion = GetWindowsVersion(); //初始化系统版本
if (WinVersion)
KdPrint(("Init Windows version Success\r\n"));
DepthServicesRegistry = NULL;
//-----------------------------------------
//注册一个系统回调
if (PsCreateSystemThread(
&HThreadHandle,
0,
NULL,
NULL,
NULL,
IsKernelBooting,
NULL) == STATUS_SUCCESS)
{
ZwClose(HThreadHandle);
}
return STATUS_SUCCESS;
}
BOOL GetSystemKernelModuleInfo(WCHAR **SystemKernelModulePath,PDWORD SystemKernelModuleBase,PDWORD SystemKernelModuleSize)
{
NTSTATUS status;
ULONG ulSize,i;
PMODULES pModuleList;
char *lpszKernelName=NULL;
ANSI_STRING AnsiKernelModule;
UNICODE_STRING UnicodeKernelModule;
BOOL bRet=TRUE;
__try
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
NULL,
0,
&ulSize
);
if (status!=STATUS_INFO_LENGTH_MISMATCH)
{
return NULL;
}
pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,ulSize);
if (pModuleList)
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
pModuleList,
ulSize,
&ulSize
);
if (!NT_SUCCESS(status))
{
if (DebugOn)
KdPrint(("ZwQuerySystemInformation error:%x %d\r\n",status,RtlNtStatusToDosError(status)));
bRet = FALSE;
}
}
if (!bRet)
{
if (pModuleList)
ExFreePool(pModuleList);
return NULL;
}
*SystemKernelModulePath=ExAllocatePool(NonPagedPool,260*2);
if (*SystemKernelModulePath==NULL)
{
*SystemKernelModuleBase=0;
*SystemKernelModuleSize=0;
return NULL;
}
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;
}
BOOL InitSafeOperationModule(PDRIVER_OBJECT pDriverObject,WCHAR *SystemModulePath,ULONG KernelModuleBase)
{
UNICODE_STRING FileName;
HANDLE hSection;
PDWORD FixdOriginalKiServiceTable;
PDWORD CsRootkitOriginalKiServiceTable;
int i=0;
if (DebugOn)
KdPrint(("Safe->Get System Kernel Module Info %ws:%08x\r\n",SystemModulePath,KernelModuleBase));
if (DebugOn)
KdPrint(("Safe->DriverObject:%08x\r\n",pDriverObject));
//自己peload 一个ntos*,这样就解决了跟其他安全软件的冲突啦~
if (!PeLoad(SystemModulePath,&ImageModuleBase,pDriverObject,KernelModuleBase))
{
if (DebugOn)
KdPrint(("Safe->PeLoad failed\n"));
return FALSE;
}
if (DebugOn)
KdPrint(("Safe->ModuleBase:%08x\r\n",ImageModuleBase));
OriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (!OriginalKiServiceTable)
{
if (DebugOn)
KdPrint(("OriginalKiServiceTable Failed\n"));
return FALSE;
}
if(!GetOriginalKiServiceTable(ImageModuleBase,KernelModuleBase,&OriginalKiServiceTable))
{
if (DebugOn)
KdPrint(("Safe->Get Original KiServiceTable Failed\n"));
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
if (DebugOn)
KdPrint(("Safe->OriginalKiServiceTable %X\n",OriginalKiServiceTable));
//填充每一个ssdt对应函数地址~这里的地址是reload的
FixOriginalKiServiceTable((PDWORD)OriginalKiServiceTable,(DWORD)ImageModuleBase,KernelModuleBase);
OriginalServiceDescriptorTable=ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (OriginalServiceDescriptorTable == NULL)
{
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(OriginalServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//这是一个干净的原始表,每个表里所对应的SSDT函数的地址都是有效的~
OriginalServiceDescriptorTable->ServiceTable = (PDWORD)OriginalKiServiceTable;
OriginalServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
OriginalServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
OriginalServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
CsRootkitOriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (CsRootkitOriginalKiServiceTable==NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(CsRootkitOriginalKiServiceTable,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
Safe_ServiceDescriptorTable = ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (Safe_ServiceDescriptorTable == NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(CsRootkitOriginalKiServiceTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
//这是一个干净的原始表,每个表里所对应的SSDT函数的地址都是原始函数
RtlZeroMemory(Safe_ServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//填充原始函数地址
for (i=0;i<KeServiceDescriptorTable->TableSize;i++)
{
CsRootkitOriginalKiServiceTable[i] = OriginalServiceDescriptorTable->ServiceTable[i];
}
Safe_ServiceDescriptorTable->ServiceTable = (PDWORD)CsRootkitOriginalKiServiceTable;
Safe_ServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
Safe_ServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
Safe_ServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
//释放就会bsod
//ExFreePool(OriginalKiServiceTable);
return TRUE;
}
BOOL 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;
Status=KernelOpenFile(FileFullPath,&hFile,0x100020,0x80,1,1,0x20);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
if (DebugOn)
KdPrint(("Open File ok\n"));
Status=KernelGetFileSize(hFile,&FileSize);
if (!NT_SUCCESS(Status))
{
ZwClose(hFile);
return FALSE;
}
if (DebugOn)
KdPrint(("Get File Size ok\n"));
Length=FileSize.LowPart;
FileBuffer=ExAllocatePool(PagedPool,Length);
if (FileBuffer==NULL)
{
ZwClose(hFile);
return FALSE;
}
Status=KernelReadFile(hFile,NULL,Length,FileBuffer,&IoStatus);
if (!NT_SUCCESS(Status))
{
ZwClose(hFile);
ExFreePool(FileBuffer);
return FALSE;
}
if (DebugOn)
KdPrint(("Read File Ok\n"));
ZwClose(hFile);
if (DebugOn)
KdPrint(("ZwClose ok\n"));
if(!ImageFile(FileBuffer,&ImageBase))
{
if (DebugOn)
KdPrint(("ImageFile failed\n"));
ExFreePool(FileBuffer);
return FALSE;
}
ExFreePool(FileBuffer);
//2k3下MiFindExportedRoutine调用失败
if(!FixImportTable(ImageBase,ExistImageBase,DeviceObject))
{
if (DebugOn)
KdPrint(("FixImportTable failed\n"));
ExFreePool(ImageBase);
return FALSE;
}
if(!FixBaseRelocTable(ImageBase,ExistImageBase))
{
if (DebugOn)
KdPrint(("FixBaseRelocTable failed\n"));
ExFreePool(ImageBase);
return FALSE;
}
*ImageModeleBase=ImageBase;
if (DebugOn)
KdPrint(("reload success\n"));
return TRUE;
}
其中要自己实现readfile等不能调用zwxxx因为可能已经被污染了。随便观察个比如readfile,通过自己构造irp,然后iocalldriver调用
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);
ObDereferenceObject(FileObject);
return status;
}
NTSTATUS
IrpReadFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
//
if(ByteOffset == NULL)
{
if(!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(Buffer, Length);
if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO)
{
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
}
else
{
Irp->UserBuffer = Buffer;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock->Status;
ULONG ReLoadNtosCALL(WCHAR *lpwzFuncTion,ULONG ulOldNtosBase,ULONG ulReloadNtosBase)
{
UNICODE_STRING UnicodeFunctionName;
ULONG ulOldFunctionAddress;
ULONG ulReloadFunctionAddress;
int index=0;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress,position;
char* functionName;
IMAGE_EXPORT_DIRECTORY *pExportTable;
ULONG ulNtDllModuleBase;
UNICODE_STRING UnicodeFunction;
UNICODE_STRING UnicodeExportTableFunction;
ANSI_STRING ExportTableFunction;
__try
{
if (RRtlInitUnicodeString &&
RRtlCompareUnicodeString &&
RMmGetSystemRoutineAddress &&
RMmIsAddressValid)
{
RRtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)RMmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase;
if (RMmIsAddressValid(ulReloadFunctionAddress))
{
return ulReloadFunctionAddress;
}
//从导出表里获取
ulNtDllModuleBase = ulReloadNtosBase;
pDosHeader = (PIMAGE_DOS_HEADER)ulReloadNtosBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return NULL;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return NULL;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulNtDllModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulNtDllModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
functionName = (char*)( (BYTE*)ulNtDllModuleBase + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulNtDllModuleBase + arrayOfFunctionAddresses[functionOrdinal]);
RtlInitAnsiString(&ExportTableFunction,functionName);
RtlAnsiStringToUnicodeString(&UnicodeExportTableFunction,&ExportTableFunction,TRUE);
RRtlInitUnicodeString(&UnicodeFunction,lpwzFuncTion);
if (RRtlCompareUnicodeString(&UnicodeExportTableFunction,&UnicodeFunction,TRUE) == 0)
{
RtlFreeUnicodeString(&UnicodeExportTableFunction);
return functionAddress;
}
RtlFreeUnicodeString(&UnicodeExportTableFunction);
}
return NULL;
}
RtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)MmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase;
//KdPrint(("%ws:%08x:%08x",lpwzFuncTion,ulOldFunctionAddress,ulReloadFunctionAddress));
if (MmIsAddressValid(ulReloadFunctionAddress))
{
return ulReloadFunctionAddress;
}
//
}__except(EXCEPTION_EXECUTE_HANDLER){
KdPrint(("EXCEPTION_EXECUTE_HANDLER"));
}
return NULL;
}