小弟我刚学驱动,试着网上的写了一下,主要针对NtReadVirtualMemory练习一下,目的是去掉其他驱动对该函数前10字节的inline hook 。驱动能正常加载,但是当我准备打开xuetr查看时就死机了,如果用kd查看就蓝屏。想问问为什么。下面代码中有两个地方有疑问,也请大侠们帮小弟看看,谢了
#include<ntddk.h>
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; //KeServiceDescriptorTable为导出函数
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////
ULONG JmpReadAddr;
ULONG OldReadAddr;
__declspec(naked)
NTSTATUS __stdcall
MyNtReadVirtualMemory(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG NumberOfBytesToRead,
PULONG NumberOfBytesReaded)
{
//跳过去
__asm
{
push 0x1c
push 80802ef0h //共十个字节(硬编码要注意改变)
//上面这句指令中的值在不同的系统中是不同的,好像应该是个什么地址,但这里为了简单测试
//采用硬编码,代码中的值是原函数在我操作系统中的值,
jmp [JmpReadAddr]
}
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = OnUnload;
KdPrint(("Unhooker load"));
Hook();
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint(("Unhooker unload!"));
Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
ULONG AddressRead;
AddressRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xba * 4;//0xbA为NtReadVirtualMemory服务ID
OldReadAddr = *(ULONG*)AddressRead;
JmpReadAddr = OldReadAddr + 10;
//上面这句代码中的OldReadAddr 地址看网上的例子是用的其他方式表示,这里由于对这个函数是否导出,和具体获取函数地址等还不是很了解。所以我采用了这种方法。不知道是否正确,还请指点,网上说的添加一个导出库,并且声明该函数原型,如果是这样的话我可以用下面这种形式获取地址吗 //JmpReadAddr = (ULONG)NtReadVirtualMemory + 10;
__asm
{
//去掉内存保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)AddressRead) = (ULONG)MyNtReadVirtualMemory;//HOOK SSDT
__asm
{
//恢复内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
//////////////////////////////////////////////////////
VOID Unhook()
{
ULONG AddressRead;
AddressRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xba * 4;//0xbA为NtReadVirtualMemory服务ID
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)AddressRead) = (ULONG)OldReadAddr;//还原SSDT
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
KdPrint(("Unhook"));
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!