H头文件
//
//
typedef struct _ServiceDescriptorTable {
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern PServiceDescriptorTable KeServiceDescriptorTable;
#pragma pack(1)
typedef struct _JMPCODE
{
BYTE E9;
ULONG JMPADDR;//88881234=B
}JMPCODE,*PJMPCODE;
#pragma pack()
//
//
ULONG GetNt_CurAddr() //获取当前SSDT_NtOpenProcess的当前地址
{
LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr;
KdPrint(("驱动成功被加载中.............................\n"));
//读取SSDT表中索引值为0x7A的函数
//poi(poi(KeServiceDescriptorTable)+0x7a*4)
t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
KdPrint(("当前ServiceTableBase地址为%x \n",t_addr));
SSDT_Adr=(PLONG)(t_addr+0x7A*4);
KdPrint(("当前t_addr+0x7A*4=%x \n",SSDT_Adr));
SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr;
KdPrint(("当前SSDT_NtOpenProcess_Cur_Addr地址为%x \n",SSDT_NtOpenProcess_Cur_Addr));
return SSDT_NtOpenProcess_Cur_Addr;
}
ULONG GetNt_OldAddr()
{
UNICODE_STRING Old_NtOpenProcess;
ULONG Old_Addr;
RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess");
Old_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址
KdPrint(("取得原函数NtOpenProcess的值为 %x",Old_Addr));
return Old_Addr;
}
//
//
CPP文件中:
全局变量:
JMPCODE oldCode;//用来保存前5字节 以便恢复
PJMPCODE pcur;
ULONG flag = 0;
//
//
DriverEntry函数:
ULONG cur,old;
JMPCODE JmpCode;
PJMPCODE pcur;
cur=GetNt_CurAddr();//A
old=GetNt_OldAddr();//C
if (cur!=old)
{
flag = 1;
//保存旧地址
pcur = (PJMPCODE)(cur);
oldCode.E9 = pcur->E9; //1字节
oldCode.JMPADDR = pcur->JMPADDR; //4字节
JmpCode.E9=0xE9;
JmpCode.JMPADDR=old-cur-5;
KdPrint(("要写入的地址%X",JmpCode.JMPADDR));
//写入JMP C-A-5=B //实际要写入地址
__asm //去掉页面保护
{
cli //关掉中断 避免在执行时被打扰 sti 允许操作
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
pcur=(PJMPCODE)(cur);
pcur->E9 = 0xE9;
pcur->JMPADDR = JmpCode.JMPADDR;
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
KdPrint(("NtOpenProcess被HOOK了"));
}
//
//
DDK_Unload函数:
__asm //去掉页面保护
{
cli //关掉中断 避免在执行时被打扰 sti 允许操作
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
if (flag)//全局 去看是否被HOOK 了 被HOOK才还原
{
pcur->E9 = oldCode.E9; //1字节
pcur->JMPADDR = oldCode.JMPADDR; //4字节
}
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
HOOK地址还原
最新推荐文章于 2023-10-31 11:28:44 发布