本文纯属于技术交流,请不要拿去干伤天害理,尤其不能干有损企鹅之事,否则本人概不负责,,来源于网络,还之于网路,废话不多说,没驱动基础的和大牛们飘过(2013-12-6)
原理:企鹅干掉了全局变量KdDebuggerEnabled,KiDebugRoutine,2函数KdSendPacket,KdReceivePachet恢复即可
1:kdDebuggerEnabled:
地址获取:
extern PBOOLEAN KdDebuggerEnabled;
调试状态:*(PBYTE)KdDebuggerEnabled=0x01;
禁止调试:*(PBYTE)KdDebuggerEnabled=0x00;
就这么简单
2:KiDebugRoutine:写入函数地址KdpStub(禁止) /KdpTrap(调试)
思路就是在KdpStub函数头写入KdpTrap地址(本人采用特征码暴力搜索内核函数地址法获取2函数地址)
EnMem(true);//去内存保护
RtlCopyMemory(SaveStub,(PBYTE)KdpStub,6);//保存6bytes
*pKdDisableCount--;//恢复事要++
*(PBYTE)(KdpStub+5)=0xc3;//写入retn
*(PBYTE)KdDebuggerEnabled=0x01;//开启调试变量
EnMem(false);//开内存保护
WriteJump((PVOID)KdpStub,(PVOID)KdpTrap);3://写入JMP指令跳到KdpTrap
3:hook企鹅自己实现的KdSendPacket/KdReceivePacket
在其retn 10/retn 14两地址处写入JMP指令跳回到正常函数就可以让WinDug收到调试信息,后面当然要写入retn 10或retn 14(堆栈平衡),当然恢复时要和原来一样,最简单的办法是绕过TP的KdSendPacket/KdReceivePacket,采用绕过的办法TP是没法检测的
只要上面3步就可以双机调试了,亲测绝对能调试
4:备注,后面我没仔细分析了,有可能有CRC校验,还有INT 2D,INT 3都是线程检查调试状态,我采用的方法是摘除TP所有映像回调,内核定时器,用户层定时器回调,阻断其检查(网上源码多如牛毛)
5:最后有一个线程(大概5分钟一次)专门负责检查调试器状态,跟一下就知道了,在其头部retn作废它就OK了
修改步骤是:在游戏加载完毕才修改,虽然TP禁止了调试,只要修改了,则又可以调试了
思路最重要,为了防止TP打击,不传源码了,哪里不懂的可以交流.呵呵
[课程]FART 脱壳王!加量不加价!FART作者讲授!