看流星社区

 找回密码
 注册账号
查看: 3115|回复: 0

分享过TP DebugPort清零的方法

[复制链接]

该用户从未签到

发表于 2018-3-4 10:27:45 | 显示全部楼层 |阅读模式

首先要提出的是,我现在所做的过 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

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

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

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

Breakpoint 0 hit
<Unloaded_TesSafe.sys>+0xbb0f2:
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.      //由于这个检测函数没压入参数,所以直接ret
  14.     *(PUSHORT)uAddr_1=0xc3;
  15.      
  16.     //0x6ea8 //第一处清零首地址,也是直接ret
  17.     *(PUCHAR)(uAddr_2)=0xc3;

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

  20.     EnableWP();//恢复CR0

  21.     g_uDebugPortOffset=g_uDebugPortOffset+0xbc;
  22.     //取到清零位置的地址

  23.     HandleDebugPortPop(true,uImageBase);//处理第三处清零
  24.     HandleDebugPortPush(true,uImageBase);//处理第四处清零
  25. }
复制代码



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

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

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

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

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

  82. }

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

  98.         }

  99. }

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

  107.                 jnz PUSHLABLE
  108.                 popfd
  109.                 push 0
  110.                 jmp g_uDebugPortPushRetAddr
  111. PUSHLABLE:
  112.                 popfd
  113.                 push dword ptr [edx]
  114.                 jmp g_uDebugPortPushRetAddr
  115.         }

  116. }
复制代码


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

最后在自己的机子成功过了TP后,CE 可以读写内存,OD可以附加。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-27 03:12

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表