__declspec(naked) VOID Nakd_NtOpenProcess()
{
__asm
{
push eax
}
//获得调用者的EPROCESS
processEPROCESS = IoGetCurrentProcess();
//将调用者的进程名保存到str1中
RtlInitAnsiString(&p_str1,(PCSZ)(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
}
}
}
BYTE OldPOpen[7]={0,0,0,0,0,0,0};
//////////////////////////////////////////////////////////////////////
// 名称: My_RecoveryHook_NtOpenProcess
// 功能: 解除游戏保护对NtOpenProcess的HOOK
// 参数:
// 返回: 状态
//////////////////////////////////////////////////////////////////////
NTSTATUS My_RecoveryHook_NtOpenProcess()
{
BYTE *NtOpenProcessAddress = NULL; //NtOpenProcess的地址
BYTE *p = NULL; //临时
TOP5CODE *top5code = NULL; //保存5字节内容
BYTE JmpAddress[7] = {0xBA,0,0,0,0,0xFF,0xE2};
TOP5CODE *tempcode=NULL;
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-7;
//保存调用ObOpenObjectByPointer函数以后的返回地址
p_ReturnAddress = p+5;
//将一条JMP Nakd_NtOpenProcess写入到数组中
tempcode=(TOP5CODE*)(ULONG)Nakd_NtOpenProcess;
*(ULONG *)(JmpAddress+1)=(ULONG)tempcode;
KdPrint(("%0X \n",*(ULONG *)(JmpAddress+1)));
//return 0;
WPOFF(); //清除CR0
//提升IRQL中断级
Irql=KeRaiseIrqlToDpcLevel();
//写入
RtlCopyMemory((BYTE*)OldPOpen,(BYTE*)p_MyHookAddress,7);
RtlCopyMemory(p_MyHookAddress,JmpAddress,7);
//恢复Irql
KeLowerIrql(Irql);
WPON(); //恢复CR0
return STATUS_SUCCESS;
}
这段代码是一外挂海的人下了看雪的代码稍微改编而成,但是不管是哪一方的代码都是蓝屏,小弟无解,小弟技术菜,还不能像某某大牛去调试,把去检测的给NOP了。。。。求助啊。。。
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!