转载于织梦未来
本机环境:win7 64位
首先用工具PC Hunter 来查看下应用层钩子![3.jpg 3.jpg](http://www.mengwuji.net/data/attachment/forum/201310/20/112013h4546sk5aeyea116.jpg)
首先直接映入眼帘的就是DbgBreakPoint, DbgUiRemoteBreakin ,DbgUserBreakPoint 这三个inline hook 对 反调试 做得手脚
len(1) ntdll.dll->DbgBreakPoint 0x000000007787000C->_ inline C3 CC
len(5) ntdll.dll-> DbgUiRemoteBreakin 0x00000000778FF8EA->_ inline E9 D2 DC FA FF 6A 08 68 60 BA
len(1) ntdll.dll->DbgUserBreakPoint 0x000000007787000C->_ inline C3 CC
DbgBreakPoint和DbgUserBreakPoint 直接 retn返回了 而没有了中断CC
当我们在用OD附加游戏的时候,会创建一个远程线程,而创建这个线程来调试的时候没有了CC中断指令,这样调试器就接受不到中断指令。
我们可以用工具查看下ntdll.dl
ntdll_DbgBreakPoint_ApiDisasm
地址 十六进制 反汇编
---------------------------------------------------------------
7787000C CC INT3 ---此处被游戏直接改成 C3
7787000D C3 RETN
ntdll_DbgUserBreakPoint_ApiDisasm
地址 十六进制 反汇编
---------------------------------------------------------------
77870008 CC INT3 ---此处被游戏直接改成 C3
77870009 90 NOP
7787000A C3 RETN
两个api都直接RETN 没有了INT3中断,无法断下来。
之后我们再来看看 DbgUiRemoteBreakin 这个函数
地址 十六进制 反汇编
---------------------------------------------------------------
778FF8EA 6A 08 PUSH 8
778FF8EC 68 60BA8877 PUSH 7788BA60
778FF8F1 E8 EEE5F8FF CALL 7788DEE4
778FF8F6 64:A1 18000000 MOV EAX,FS:[18]
778FF8FC 8B40 30 MOV EAX,DS:[EAX+30]
778FF8FF 8078 02 00 CMP BYTE PTR DS:[EAX+2],0
778FF903 75 09 JNZ SHORT 778FF90E
778FF905 F605 D402FE7F 02TEST BYTE PTR DS:[7FFE02D4],2
778FF90C 74 28 JE SHORT 778FF936
778FF90E 64:A1 18000000 MOV EAX,FS:[18]
778FF914 F680 CA0F0000 20TEST BYTE PTR DS:[EAX+FCA],20
778FF91B 75 19 JNZ SHORT 778FF936
778FF91D 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
778FF921 E8 E606F7FF CALL ntdll.DbgBreakPoint
778FF926 EB 07 JMP SHORT 778FF92F
778FF928 33C0 XOR EAX,EAX
778FF92A 40 INC EAX
778FF92B C3 RETN
至于游戏对这个API做的一些手脚我们可以用OD附加一下试试,附加后游戏崩溃 不过 已经附加上有游戏的代码 就可以了
我们来查看下ntdll.dll这个模块
![1.jpg 1.jpg](http://www.mengwuji.net/data/attachment/forum/201310/20/094217s41asscye51qy9kz.jpg)
我们关键看的还是ntdll.dll的基址
77840000 再加上
序数 函数名 地址 参数量
62 DbgUiRemoteBreakin 0009F8EA 0
的偏移 77840000+0009F8EA = 778DF8EA
我们直接crtl+g转到778DF8EA
![2.jpg 2.jpg](http://www.mengwuji.net/data/attachment/forum/201310/20/094548qstvmcicx99d8a4v.jpg)
我们可以看到 这个地方第一句直接跳转到 ntdll.LdrShutdownProcess
我们再来看下解释。从字面的意思我们也能看出 结果是退出进程
![5.jpg 5.jpg](http://www.mengwuji.net/data/attachment/forum/201310/20/112023re3g422b6l6rp77t.jpg)
-----------------------------------------------------------
//这两句话是看雪中看到的资料 之后就没继续跟进细看
DbgUiRemoteBreakin是执行DbgBreakPoint前的一个调用
LdrShutdownProcess将直接给每个已经加载的dll模块发消息, dll将被卸载 这样就导致了OD一加载, dll等模块就被卸载掉了
地址 十六进制 反汇编
---------------------------------------------------------------
778DF8EA >^\E9 D2DCFAFF JMP ntdll.LdrShutdownProcess
778DF8EF 8677 E8 XCHG BYTE PTR DS:[EDI-18],DH
778DF8F2 EE OUT DX,AL
778DF8F3 E5 F8 IN EAX,0F8
778DF8F5 FF64A1 18 JMP DWORD PTR DS:[ECX+18]
778DF8F9 0000 ADD BYTE PTR DS:[EAX],AL
778DF8FB 008B 40308078 ADD BYTE PTR DS:[EBX+78803040],CL
778DF901 0200 ADD AL,BYTE PTR DS:[EAX]
778DF903 75 09 JNZ SHORT ntdll.778DF90E
778DF905 F605 D402FE7F 0>TEST BYTE PTR DS:[7FFE02D4],2
778DF90C 74 28 JE SHORT ntdll.778DF936
778DF90E 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
778DF914 F680 CA0F0000 2>TEST BYTE PTR DS:[EAX+FCA],20
778DF91B 75 19 JNZ SHORT ntdll.778DF936
778DF91D 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
778DF921 E8 E606F7FF CALL ntdll.DbgBreakPoint //此处调用了 ntdll.DbgBreakPoint
778DF926 EB 07 JMP SHORT ntdll.778DF92F
778DF928 33C0 XOR EAX,EAX
778DF92A 40 INC EAX
778DF92B C3 RETN
从此段代码可以看出“ DbgUiRemoteBreakin , 是执行DbgBreakPoint前的一个调用”
原API
地址 十六进制 反汇编
---------------------------------------------------------------
778FF8EA 6A 08 PUSH 8
778FF8EC 68 60BA8877 PUSH 7788BA60
778FF8F1 E8 EEE5F8FF CALL 7788DEE4
HOOK 后API
地址 十六进制 反汇编
---------------------------------------------------------------
778DF8EA >^\E9 D2DCFAFF JMP ntdll.LdrShutdownProcess
778DF8EF 8677 E8 XCHG BYTE PTR DS:[EDI-18],DH
778DF8F2 EE OUT DX,AL
778DF8F3 E5 F8 IN EAX,0F8
778DF8F5 FF64A1 18 JMP DWORD PTR DS:[ECX+18]
DbgUiRemoteBreakin 是ntdll提供的用于在目标进程中创建远线程下软件断点的函数
伪代码如下: 当我们用OD调试时,CreateRemoteThread函数在目标程序中创建 DbgUiRemoteBreakin线程的时候,是下了INT 3软中断。
因为是在调试状态, 所以调试器可以捕获这个异常。如果目标程序没有被调试的话,程序就会正常执行。
总结:
通过对比我们就可以看出游戏HOOK的手法
这样我们就可以为我们恢复R3层inline hook做了很好的铺垫
如果我们用工具恢复R3层Hook的话 马上就会被恢复,这个原因就在于有线程的检测。
之后就不太理解了!!查阅资料说
至于哪个线程是干什么的 我们应该用工具去挂起线程来测试测试,找出哪个才是检测的线程,
在尝试了很多次 后也没找到太好的方法 (线程太多 )希望懂的大牛们 能讲讲具体的原理,最好带个例子
本人在此先行感谢!