龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 4155|回复: 0

分享一下最新过TP DebugPort清零的方法

[复制链接]

14

主题

3

回帖

22

积分

编程入门

Rank: 1

龙马币
48

众所周知

TP 系统全称 TenProtect,是由腾讯自主研发推出的安全系统,可以有效保护游戏不受智辅侵犯,同时具备反木马盗号功能,
能有效的防止用户游戏帐号和虚拟财产被窃取。腾讯 TP 系统主要作用为智辅检测、反盗号、反非法工作室、防非法消息。

文章写的有点赶,没有带图,代码可能也有点乱,各位将就看看吧!

首先要提出的是,我现在所做的过 TP 驱动保护只支持 32 位 XP,在所有的 32 位 XP 上都可以正常运行,
不过 Win7 的话还不行,因为里面用到了搜索特征码来定位未导出 API,而我只针对 XP 做了处理。

首先我们先分析一下TP所做的保护:
1、 NtOpenProcess 中的 Deep InLine Hook:
2、 NtOpenThread 中的 Deep InLine Hook:
3、 NtReadVirtualMemory 中的 InLine Hook:
4、 NtWriteVirtualMemory 中的 InLine Hook:
5、 KiAttachProcess和KeStackAttachProcess的 InLine Hook:
6、 NtGetContextThread 中的 InLine Hook:
7、 NtSetContextThread 中的 InLine Hook:
8 、DebugPort清零:

大概主要的函数就是以上这些了,一些小HOOK就不写了。

我相信前7个函数的处理方法在网上应该已经被人讲过一遍又一遍了,所以我直接从DebugPort清零说起。

首先我们又虚拟机进行双机调试 下游戏基址+0xbc 的访问断点
可以发现现在最新的TP 有四处清零和一处检测
他们分别是

TesSafe基址:   B13AF000
进程基址:        829FFDA0

  1. Breakpoint 0 hit
  2. <Unloaded_TesSafe.sys>+0x6ef1:
  3. b1117ef1 8b4624          mov     eax,dword ptr [esi+24h]

  4. Breakpoint 0 hit
  5. <Unloaded_TesSafe.sys>+0x22a2:
  6. b11132a2 8b09            mov     ecx,dword ptr [ecx]

  7. Breakpoint 0 hit
  8. <Unloaded_TesSafe.sys>+0xba4cc:
  9. b11cb4cc e9a8350000      jmp     <Unloaded_TesSafe.sys>+0xbda79 (b11cea79)

  10. Breakpoint 0 hit
  11. <Unloaded_TesSafe.sys>+0xbb0f2:
  12. b11cc0f2 e9c5f1ffff      jmp     <Unloaded_TesSafe.sys>+0xba2bc (b11cb2bc
复制代码


一处检测: TesSafe.sys +0x4082

在处理清零之前我们要先处理掉检测,不然要是直接把清零函数ret掉了,检测函数发现后就会重启我们的电脑。
我们要先通过IDA的逆向找出清零函数和检测函数的首地址

第一处清零首地址:TesSafe+0x6ea8;
第二处清零首地址:TesSafe+0x222e;

以下是两处VM的清零代码的地址:

第三处清零:TesSafe+0xbb0f0;
第四处清零:TesSafe+0xba4ca;

CRC检测首地址:TesSafe+0x4082;

知道这些信息后我们就开始写代码过了他吧!

代码:
  1. void HandleDebugZero(ULONG uImageBase) //主要清零处理函数
  2. {
  3.   ULONG uAddr_1=uImageBase + 0x4082;//清零CRC检测首地址
  4.   ULONG uAddr_2=uImageBase + 0x6ea8;//清零处1首地址
  5.   ULONG uAddr_3=uImageBase + 0x2228;//清零处2首地址

  6.   GetDnfEprocessAddr(uImageBase);   //取得DNF 进程基址
  7.   //这个进程基址在处理第三和第四处清零的时候用到
  8.    if(uImageBase==0)
  9.   {
  10.     return;
  11.   }

  12.   DisableWP();   //清除CR0

  13.   *(PUSHORT)uAddr_1=0xc3;
  14.     //由于这个检测函数没压入参数,所以直接ret
  15.            
  16.    
  17.   //0x6ea8 //第一处清零首地址,也是直接ret
  18.            *(PUCHAR)(uAddr_2)=0xc3;

  19.   //0x2228 //第二处清零首地址,还是直接ret
  20.   *(PUCHAR)(uAddr_3)=0xc3;

  21.   EnableWP();//恢复CR0
  22.   
  23.    g_uDebugPortOffset=g_uDebugPortOffset+0xbc;

  24.    //取到清零位置的地址
  25.   HandleDebugPortPop(true,uImageBase);//处理第三处清零
  26.   HandleDebugPortPush(true,uImageBase);//处理第四处清零
  27. }
复制代码


打字打到手都累了,下面就不加那么清楚的注释了,各位自己看下吧

  1. void HandleDebugPortPop(BOOLEAN bHook,ULONG uImageBase)
  2. {
  3.   if(bHook)
  4.   {
  5.     //hook pop
  6.     if(uImageBase==0)
  7.     {
  8.       return ;
  9.     }
  10.     g_uDebugPortPopHookAddr=uImageBase+0xbb0f0;//pop hook地址

  11.     g_uDebugPortPopRetAddr=uImageBase+0xba2bc;//pop retn 地址

  12.     if(g_uDebugPortPopHookAddr==0)
  13.     {
  14.       return;
  15.     }
  16.     RtlCopyMemory((PVOID)g_szBackupDebugPortPop, (PVOID)g_uDebugPortPopHookAddr, 5); //保存hook地址,用于恢复
  17.    
  18.     InLineHookEngine(g_uDebugPortPopHookAddr,(int)FuckDebugPortPop);
  19.     //__asm int 3
  20.   }
  21.   else
  22.   {
  23.     if(g_uDebugPortPopHookAddr==0)
  24.     {
  25.       return;
  26.     }
  27.     // 最好判断下 TP是否 已经卸载
  28.     int TesSafe=GetTesSafeBassAddr();
  29.     if(TesSafe!=0)
  30.     {
  31.     //KIRQL Irql=KeRaiseIrqlToDpcLevel();
  32.     DisableWP();
  33.         RtlCopyMemory((PVOID)g_uDebugPortPopHookAddr, (PVOID)g_szBackupDebugPortPop, 5);//保存hook地址,用于恢复
  34.     EnableWP();
  35.     }
  36.   }
  37. }


  38. void HandleDebugPortPush(BOOLEAN bHook,ULONG uImageBase)
  39. {
  40.   if(bHook)
  41.   {
  42.     //hook pop
  43.     if(uImageBase==0)
  44.     {
  45.       return ;
  46.     }
  47.     g_uDebugPortPushHookAddr=uImageBase+0xba4ca;//push hook地址

  48.     g_uDebugPortPushRetAddr=uImageBase+0xba2bc;//push retn 地址

  49.     if(g_uDebugPortPushHookAddr==0)
  50.     {
  51.       return;
  52.     }
  53.     RtlCopyMemory((PVOID)g_szBackupDebugPortPush,
  54.                 (PVOID)g_uDebugPortPushHookAddr,
  55.                        5);//保存hook地址,用于恢复
  56.    
  57.     InLineHookEngine(g_uDebugPortPushHookAddr,(int)FuckDebugPortPush);
  58.     //__asm int 3
  59.   }
  60.   else
  61.   {
  62.     if(g_uDebugPortPushHookAddr==0)
  63.     {
  64.       return;
  65.     }
  66.     // 最好判断下 TP是否 已经卸载
  67.     int TesSafe=GetTesSafeBassAddr();
  68.     if(TesSafe!=0)
  69.     {
  70.     //KIRQL Irql=KeRaiseIrqlToDpcLevel();
  71.     DisableWP();
  72.                                 RtlCopyMemory((PVOID)g_uDebugPortPushHookAddr,
  73.                 (PVOID)g_szBackupDebugPortPush,
  74.                        5);//保存hook地址,用于恢复
  75.     EnableWP();
  76.     }
  77.   }

  78. }

  79. __declspec(naked)void FuckDebugPortPop()
  80. {
  81.   //DbgPrint("Pop");
  82.   __asm
  83.   {
  84.     pushfd
  85.     cmp edx,g_uDebugPortOffset //判断入栈的参数是否是清零位置的地址
  86.     jnz POPLABLE
  87.     popfd
  88.     add esp,0x4
  89.     jmp g_uDebugPortPopRetAddr
  90. POPLABLE:
  91.     popfd
  92.     pop dword ptr [edx]
  93.     jmp g_uDebugPortPopRetAddr

  94.   }

  95. }

  96. __declspec(naked)void FuckDebugPortPush()
  97. {
  98.   //DbgPrint("Push");
  99.   __asm
  100.   {
  101.     pushfd
  102.     cmp edx,g_uDebugPortOffset//判断入栈的参数是否是清零位置的地址

  103.     jnz PUSHLABLE
  104.     popfd
  105.     push 0
  106.     jmp g_uDebugPortPushRetAddr
  107. PUSHLABLE:
  108.     popfd
  109.     push dword ptr [edx]
  110.     jmp g_uDebugPortPushRetAddr
  111.   }
  112. }
复制代码


最后提一点以下这两个函数要在驱动卸载的时候加到Unload函数中
  1. HandleDebugPortPop(false,0);
  2. HandleDebugPortPush(false,0);
复制代码


最后在自己的机子成功过了TP后,CE 可以读写内存,OD可以附加。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表