本文章纯属技术交流,拿来主义勿进
(以下所提供的代码偏移现在肯定已经变化了)
本部分采用暴力干掉tp所有的保护措施,实际辅助运行不会采用这种方法
第一步: 我们首先要做的是保证双机调试能顺利进行,我用的是两台机机器通过串口调试(大部分人喜欢用虚拟机双机调试,我还是觉得2台机器方便,呵呵)
tp 限制双机调试有2个办法的:
1 调用KdDisableDebugger,禁止调试,并且检测系统是否已经禁止调试了
跟踪看看:
首先 断在 KdDisableDebugger上, 手动屏蔽掉实现代码(eb KdDisableDebugger + 1d eb)
跳到上层代码,发现在检测 KdDisableDebugger 结果,如果没有生效的话就会跳回到调用KdDisableDebugger的代码,所以直接在跳转代码上处理(ew TesSafe+0x7031 9090)
继续:断在第二次执行 KdDisableDebugger 上,这次会正对KiDebugRoutine 操作,如果不处理就直接会蓝屏的 mov [ecx]... 此时ecx是0,所以(ew TesSafe+0x7161 9090) 就搞定了.
2. 2d中断 检测系统是否被调试
这次需要查找2d中断 检测代码,通过直接搜索 汇编( int 2Dh ,int3) 基本上可以定位他的位置.直接NOP掉它就是(ew TesSafe+0x20db 9090;eb TesSafe+0x20db+2 90)
第二步: 干掉KdSendPacket KdReceivePacket hook
这个比较简单,在该函数设置写断点,即可马上跟踪到,NOP掉即可
第三步: 干掉所有定时器
这个也比较简单,设置断点 IoInitializeTimer即可马上跟踪到,NOP掉即可
到此,驱动初始化就算结束了,我将我建立的驱动初始化函数调用做了个图:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
接着,开始是在IRP_MJ_DEVICE_CONTROL调用中
第四步:: 干掉所有线程
这个也比较简单,直接在PsCreateSystemThread 设置断点,因为有其他程序干扰,所以断点应该:bp PsCreateSystemThread".if poi(esp)<a9704000{gc}.elsif poi(esp)>a9840000{gc}.else{}"。
第五步: 干掉DCP定时器
很处理线程一样的做法 断点:(bp KeInitializeDpc ".if poi(esp)<a9704000{gc}.elsif poi(esp)>a9840000{gc}.else{}")
第六步:干掉 inlinehook NtOpenProcess 处理函数(不是干掉NtOpenProcess inlinehook)
在检测到有进程被打开后,tp会启动检测函数,对代码进行校验,导致机器重启,所以必须干掉启动检测函数,一般启动检测函数都是采用异步函数,所以我们跟踪IoQueueWorkItem的调用就可以定位到它了。
nt!NtOpenProcess+0x229:call TesSafe+0xb98c (inlinehook NtOpenProcess)
TesSafe+0xbb2d:call TesSafe+0xa248>>>>>>>>>(ed TesSafe+0xa248 0xc3c3c3c3)
TesSafe+0x95af:IoQueueWorkItem (回调函数 TesSafe+0xa1e8)
(一下为系统线程执行)
TesSafe+0xa1e8:
TesSafe+0xa210:call TesSafe+0x9ab8 重启
byte ptr [TesSafe+0x40500] 为0时不重启,否则重启
第七步:干掉ssdt 函数头inlinehook
定位SSDT inlinehook比较简单,只要在SSDT函数体设置写断点,很轻松就可以定位了,直接NOP掉它即可
第八步:干掉对kdbclass.sys 的headhook
最近的版本tp 为了防止使用虚拟鼠标键盘(可能针对按键精灵),它对kdbclass.sys中一个函数进行了headhook,导致虚拟输入驱动没办法找到KeyboardClassServiceCallback 和 MouseClassServiceCallback,设置写断点,马上就可以找到它,NOP掉就是
到此 IRP_MJ_DEVICE_CONTROL 部分就算出来完成,一下记录了跟踪的函数调用表
I
还有IRP_MJ_READ,也有部分需要处理
第九步:干掉 IRP_MJ_READ 中启动 IoQueueWorkItem调用函数,以及下面的重启代码跳转掉
IRP_MJ_READ TesSafe+0x12358:
TesSafe+0x10bc1:call TesSafe+0xd8da>>>>>(eb TesSafe + 0x10bc1 0x90;ed TesSafe + 0x10bc1 + 1 0x90909090)
TesSafe+0xd939:call IoQueueWorkItem (执行函数:TesSafe+0xd728,该函数也会导致重启)
TesSafe+0x10bd1: 再次修改,直接跳转,离开下面的重启代码>>>>(eb TesSafe+0x10bd1 0x90;eb TesSafe+0x10bd1+1 0xe9(jmp))
TesSafe+0x10c5d: 开始重启代码
TesSafe+0x10c79:重启
到此,已经完全,暴力的干掉了tp所有的保护,但想要开始使用od等工具还需要处理NtOpenProcess inlinehook,为什么不直接干掉它的inlinehook呢,因为游戏本身会做一些检测,测试它的NtOpenProcess inlinehook。处理方法直接采用文章(http://bbs.pediy.com/showthread.php?t=126802)的方法即可,这里不再详述。
以上都处理完毕后,tp所有的保护功能都已被干掉,可以直接使用od等工具对游戏进行调试了。
实际使用过程中发现,有时候会出现非法第三方的检测。毕竟属于暴利手段,太过粗糙,人家还是有检测手段的,但能调试程序,而且出现检测的几率很少,也算是够用了。
但对于运行辅助,这种方法显然是不可行的,可经过对整个tp跟踪的过程,发现要绕开tp去读写游戏数据是多么的简单。只要能把tp程序分析透彻了,其他处理都已经变得非常简单了,采用绕行的方式,tp是不可能检测出来的。