能力值:
( LV2,RANK:10 )
|
-
-
101 楼
这个 真不错啊!
|
能力值:
( LV11,RANK:180 )
|
-
-
102 楼
太给里了. 这哥们. 解决了我多年的困扰啊
|
能力值:
( LV2,RANK:10 )
|
-
-
103 楼
mark一下 楼主辛苦
|
能力值:
( LV2,RANK:10 )
|
-
-
104 楼
能看懂一点点点点,但大部分完全不懂了。。。。 LZ大半夜不睡,发贴,真是辛苦了啊
|
能力值:
( LV5,RANK:60 )
|
-
-
105 楼
牛X 的人,崇拜下
|
能力值:
( LV2,RANK:10 )
|
-
-
106 楼
感谢lz,看了lz的帖子,犹如当头棒喝,醍醐灌顶,让我幡然醒悟!!
|
能力值:
( LV2,RANK:10 )
|
-
-
107 楼
kd> uf KdDisableDebugger
nt!KdDisableDebugger:
80823d62 6a01 push 1
80823d64 e82dffffff call nt!KdDisableDebuggerWithLock (80823c96)
80823d69 c3 ret
kd> uf KdDisableDebuggerWithLock
nt!KdDisableDebuggerWithLock:
80823c96 8bff mov edi,edi
80823c98 55 push ebp
80823c99 8bec mov ebp,esp
80823c9b 51 push ecx
80823c9c 53 push ebx
80823c9d 33db xor ebx,ebx
80823c9f 381d6c0c8a80 cmp byte ptr [nt!KdBlockEnable (808a0c6c)],bl
80823ca5 885dff mov byte ptr [ebp-1],bl
80823ca8 740a je nt!KdDisableDebuggerWithLock+0x1e (80823cb4)
修改KdDisableDebugger或者KdDisableDebuggerWithLock头为xor eax,eax;ret ?后在游戏启动的时候System CPU使用率都会99%,机器基本卡死,卡了半个小时也没看见游戏启动画面...
|
能力值:
( LV3,RANK:20 )
|
-
-
108 楼
好东西啊,难得lz共享出来
|
能力值:
( LV2,RANK:10 )
|
-
-
109 楼
mark mark mark mark mark
|
能力值:
( LV2,RANK:10 )
|
-
-
110 楼
不是很懂,但这样好饿帖子,必须得顶
|
能力值:
( LV2,RANK:10 )
|
-
-
111 楼
哎,内核真是麻烦,啰嗦死了
|
能力值:
( LV2,RANK:10 )
|
-
-
112 楼
两个硬件断点检测的处理 是否能再细腻点?
|
能力值:
( LV2,RANK:10 )
|
-
-
113 楼
一头雾水啊
|
能力值:
( LV2,RANK:10 )
|
-
-
114 楼
嗯,很详细哈
但有个问题,像NtReadVirtualMemory这类未导出函不能用MmGetSystemRoutine获取地址,而使用KeServiceDescriptorTable来取得当前地址,如果NtReadVirtualMemory本身被其它程式给SDDT HOOK了,那获取当前地址不就出错了?
碰到过这样的问题,不懂有没好的方法可以处理
|
能力值:
( LV2,RANK:10 )
|
-
-
115 楼
......我用DDK编译了下,发现224处错误,痛苦呀!贴上我改的OpenThread
//NtOpenThread用到的全局变量[为了方便堆栈平衡的处理使用全局变量] PEPROCESS threadEPROCESS = NULL; //保存访问者的EPROCESS ANSI_STRING t_str1,t_str2; //保存进程名称 BYTE *ObOpenObjectByPointerAddress = NULL; //ObOpenObjectByPointer的地址 BYTE *t_TpHookAddress = NULL; //TP的HOOK函数地址 BYTE *t_ReturnAddress = NULL; //返回到的地址 BYTE *t_MyHookAddress = NULL; //我们的HOOK函数在哪写入 ////////////////////////////////////////////////////////////////////// // 名称: Nakd_NtOpenThread // 功能: My_RecoveryHook_NtOpenThread的中继函数 // 参数: // 返回: ////////////////////////////////////////////////////////////////////// static NAKED VOID Nakd_NtOpenThread() { //获得调用者的EPROCESS threadEPROCESS = IoGetCurrentProcess(); //将调用者的进程名保存到str1中 RtlInitAnsiString(&t_str1,(ULONG)threadEPROCESS+0x174); //将我们要比对的进程名放入str2 RtlInitAnsiString(&t_str2,DNF_EXE); if (RtlCompareString(&t_str1,&t_str2,TRUE) == 0) { //说明是DNF进程访问了这里 __asm { push dword ptr [ebp-34h] push dword ptr [ebp-20h] push t_ReturnAddress mov eax,t_TpHookAddress jmp eax } } else { __asm { push dword ptr [ebp-34h] push dword ptr [ebp-20h] push t_ReturnAddress mov eax,ObOpenObjectByPointerAddress jmp eax } } } ////////////////////////////////////////////////////////////////////// // 名称: My_RecoveryHook_NtOpenProcess // 功能: 解除游戏保护对NtOpenProcess的HOOK // 参数: // 返回: 状态 ////////////////////////////////////////////////////////////////////// NTSTATUS My_RecoveryHook_NtOpenThread() { BYTE *NtOpenThreadAddress = NULL; //NtOpenProcess的地址 BYTE *p = NULL; //临时 TOP5CODE *top5code = NULL; //保存5字节内容 BYTE JmpAddress[6] = {0xE9,0,0,0,0,0x90}; KIRQL Irql;
//获取NtOpenProcess的地址 NtOpenThreadAddress = (BYTE*)MyGetFunAddress(L"NtOpenThread"); if (NtOpenThreadAddress == 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 = NtOpenThreadAddress; BYTE szCode[7]={0x50,0xff,0x75,0xcc,0xff,0x75,0xe0}; //用一个无限循环来判断给定的特征码来确定被HOOK位置 for(int i=0;i<400; i++) { if (RtlCompareMemory(p,szCode,7) == 0) { p +=7; KdPrint(("%0X \n",(ULONG)p)); break; } //推动指针向前走 p++; }
//将top5code指向 p 的当前处 //用以取出 call [地址] 这5字节里面的地址 top5code = (TOP5CODE*)p; t_TpHookAddress = (BYTE*)((ULONG)p+5+top5code->address);
//找到我们写入自定义函数的地址 t_MyHookAddress = p-6; //保存调用ObOpenObjectByPointer函数以后的返回地址 t_ReturnAddress = p+5;
//将一条JMP Nakd_NtOpenProcess写入到数组中 *(ULONG *)(JmpAddress+1)=(ULONG)Nakd_NtOpenProcess - ((ULONG)t_MyHookAddress+5);
WPOFF(); //清除CR0 //提升IRQL中断级 Irql=KeRaiseIrqlToDpcLevel(); //写入 RtlCopyMemory(t_MyHookAddress,JmpAddress,6); //恢复Irql KeLowerIrql(Irql); WPON(); //恢复CR0
return STATUS_SUCCESS; }
|
能力值:
( LV2,RANK:10 )
|
-
-
116 楼
BYTE Signature1 = 0x56, //p-1 Signature2 = 0x57, //p-2 Signature3 = 0x5F, //p-3 Signature4 = 0x5E, //p+5 Signature5 = 0xE8; //p第一个字节
不知道楼主用什么编译器,这样也能编译成功?
|
能力值:
( LV2,RANK:10 )
|
-
-
117 楼
楼上一定第一次使用ddk编译器 不解释
|
能力值:
( LV2,RANK:10 )
|
-
-
118 楼
貌似 debugPort 的检测又增加了2处把。、、、 崩溃、、、那两处太恐怖了、、
|
能力值:
( LV2,RANK:10 )
|
-
-
119 楼
仰望楼主 发现自己多么的不努力。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
120 楼
楼主真是好人啊
|
能力值:
( LV2,RANK:10 )
|
-
-
121 楼
好文章,标记一下慢慢学习研究
|
能力值:
( LV2,RANK:10 )
|
-
-
122 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
123 楼
虽然很多还看不明白,慢慢学习
|
能力值:
( LV15,RANK:520 )
|
-
-
124 楼
过程很好,思路很好,讲解很详细,谢谢!
|
能力值:
( LV2,RANK:10 )
|
-
-
125 楼
学习了,游戏的保护很强大啊
|
|
|