//NtOpenProcess
用到的全局变量[为了方便堆栈平衡的处理使用全局变量]
PEPROCESS processEPROCESS = NULL;
//
保存访问者的EPROCESS
ANSI_STRING p_str1,p_str2;
//
保存进程名称
BYTE *ObOpenObjectByPointerAddress = NULL;
//ObOpenObjectByPointer
的地址
BYTE *p_TpHookAddress = NULL;
//TP
的HOOK函数地址
BYTE *p_ReturnAddress = NULL;
//
返回到的地址
BYTE *p_MyHookAddress = NULL;
//
我们的HOOK函数在哪写入
//////////////////////////////////////////////////////////////////////
//
名称: Nakd_NtOpenProcess
//
功能: My_RecoveryHook_NtOpenProcess的中继函数
//
参数:
//
返回:
//////////////////////////////////////////////////////////////////////
static NAKED VOID Nakd_NtOpenProcess()
{
//
获得调用者的EPROCESS
processEPROCESS = IoGetCurrentProcess();
//
将调用者的进程名保存到str1中
RtlInitAnsiString(&p_str1,(ULONG)processEPROCESS+0x174);
//
将我们要比对的进程名放入str2
RtlInitAnsiString(&p_str2,DNF_EXE);
if
(RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
//
说明是DNF进程访问了这里
__asm
{
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
push p_ReturnAddress
mov eax,p_TpHookAddress
jmp eax
}
}
else
{
__asm
{
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
push p_ReturnAddress
mov eax,ObOpenObjectByPointerAddress
jmp eax
}
}
}
//////////////////////////////////////////////////////////////////////
//
名称: My_RecoveryHook_NtOpenProcess
//
功能: 解除游戏保护对NtOpenProcess的HOOK
//
参数:
//
返回: 状态
//////////////////////////////////////////////////////////////////////
NTSTATUS My_RecoveryHook_NtOpenProcess()
{
BYTE *NtOpenProcessAddress = NULL;
//NtOpenProcess
的地址
BYTE *p = NULL;
//
临时
TOP5CODE *top5code = NULL;
//
保存5字节内容
BYTE JmpAddress[6] = {0xE9,0,0,0,0,0x90};
KIRQL Irql;
//
获取NtOpenProcess的地址
NtOpenProcessAddress = (BYTE*)MyGetFunAddress(L
"NtOpenProcess"
);
if
(NtOpenProcessAddress == NULL)
{
KdPrint((
"NtOpenProcess地址获取失败\n"
));
return
FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
}
//
获取ObOpenObjectByPointer的地址
ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L
"ObOpenObjectByPointer"
);
if
(ObOpenObjectByPointerAddress == NULL)
{
KdPrint((
"ObOpenObjectByPointer地址获取失败\n"
));
return
FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
}
//
将p指向NtOpenProcess函数开始处
p = NtOpenProcessAddress;
//
用一个无限循环来判断给定的特征码来确定被HOOK位置
while
(1)
{
if
((*(p-7) == 0x50) &&
(*(p-0xE) == 0x56) &&
(*(p+0xd) == 0x50) &&
(*(p+0x16) == 0x3b) &&
(*(p+0x17) == 0xce) &&
(*p == 0xE8) &&
(*(p+5) == 0x8b) &&
(*(p+6) == 0xf8))
{
KdPrint((
"%0X \n"
,(ULONG)p));
break
;
}
//
推动指针向前走
p++;
}
//
将top5code指向 p 的当前处
//
用以取出 call [地址] 这5字节里面的地址
top5code = (TOP5CODE*)p;
p_TpHookAddress = (BYTE*)((ULONG)p+5+top5code->address);
//
找到我们写入自定义函数的地址
p_MyHookAddress = p-6;
//
保存调用ObOpenObjectByPointer函数以后的返回地址
p_ReturnAddress = p+5;
//
将一条JMP Nakd_NtOpenProcess写入到数组中
*(ULONG *)(JmpAddress+1)=(ULONG)Nakd_NtOpenProcess - ((ULONG)p_MyHookAddress+5);
WPOFF();
//
清除CR0
//
提升IRQL中断级
Irql=KeRaiseIrqlToDpcLevel();
//
写入
RtlCopyMemory(p_MyHookAddress,JmpAddress,6);
//
恢复Irql
KeLowerIrql(Irql);
WPON();
//
恢复CR0
return
STATUS_SUCCESS;
}