挂海论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
超级变速器为电脑系统、软件程序、游戏加速平均提速100%有技术,来挂海,申请版主合作运营!█绝地求生█和平精英█CF高端辅助█ █DNF█绝地█和平█全网最低货源卡盟█诚招代理█ 15级和平精英小号 全网价格最低!
找个会写LOL防封的实力作者长期合作, 有责任心,有思路有想法,qq2243531888老板吃土卖卡,一张卡只赚1毛钱,我们只做卡密的搬运工!CF主播驱动/透视自瞄/和平/免费辅助 预判自瞄 长期稳定 联系QQ978587967点击进入网盘密码6666-飞翼来 物理USB压枪 版本/代理-
云顶之弈最实用的辅助工具智能记牌、五星上分大法解一下? 香港欧美socks5|https长效|API代理ip 纯硬件USB压枪!绝非世面垃圾东西 定制/代理 国际服SX破解版1R批卡QQ:754968 【绝地求生辅助货源】最全最稳『内部价格』『超低』
██【我要租此广告位】██... .
查看: 11258|回复: 243

[转载] 过 DNF TP 驱动保护(二)

  [复制链接]
6高级会员
605/1100

605

积分

171

主题

14

听众
已帮网友解决0 个问题
贡献
404
海币
1544
交易币
0
发表于 2014-6-3 16:07:14 | 显示全部楼层 |阅读模式
如果您下载的软件是收费的"请千万不要付款",那绝对是骗子,请立即联系本站举报,若您执意要付款被骗后本站概不负责。
目录:
01. 博文简介:
02. 环境及工具准备:
03. 分析 TP 所做的保护:
04. 干掉 NtOpenProcess 中的 Deep InLine Hook:
05. 干掉 NtOpenThread 中的 Deep InLine Hook:
06. 干掉 NtReadVirtualMemory 中的 InLine Hook:
07. 干掉 NtWriteVirtualMemory 中的 InLine Hook:
08. 干掉 KiAttachProcess 的 InLine Hook:
09. 干掉 NtGetContextThread 中的 InLine Hook:
10. 干掉 NtSetContextThread 中的 InLine Hook:
11. 干掉 DbgkpQueueMessage 中的 InLine Hook:
12. 干掉 DbgkpSetProcessDebugObject 中的 InLine Hook:
13. 干掉 Debug 清零:


共四篇,本篇为第二篇。


06. 干掉 NtReadVirtualMemory 中的 InLine Hook:

前面已经干掉了 TP 对 NtOpenProcess 以及 TP 对 NtOpenThread 所做的 Hook,
这样的话,我们已经可以使用 OD 或者 CE 看到 DNF 的游戏进程了,
弄过一些游戏方面内容的朋友应该都是知道 CE 的,这东东是开源的,不过是基于 Delphi 的,
工具做得很不错,可以通过 CE 来修改一些游戏进程的内存数据,比如可以修改一些简单的游戏的血值啊之类的,
但是,此时我们可以用 CE 来扫描一下 DNF 游戏进程的内存,你会发现根本扫描不到任何数据,
其实原因也很简单,TP 对 NtReadVirtualMemory 进行了浅层的 InLine Hook,
从而可以达到防止其他进程读取 DNF 游戏进程内存的目的,
而 CE 的话,在 Ring3 下是通过 ReadProcessMemory 来读取游戏内存的,
而 ReadProcessMemory 进入 Ring0 后又是调用的 NtReadVirtualMemory,
由于 NtReadVirtualMemory 被 TP 干掉了,所以自然用 CE 是扫描不出任何东西的,
要干掉 TP 对 NtReadVirtualMemory 所作的浅层 InLine Hook 其实是比较简单的,
因为 TP 并没有对 NtReadVirtualMemory 做检测,所以可以直接用 SSDT 来对抗掉浅层的 InLine Hook 就 OK。
至于原理的话,很简单,直接用 SSDT Hook 替换掉系统服务 NtReadVirtualMemory,
然后在 SSDTHookNtReadVirtualMemory 这个我们自己写的系统服务中判断,
如果是 DNF 进程的话,直接调用原来的 SSDT 系统服务就好,如果不是 DNF 进程的话,
我就跳过 TP 对 NtReadVirtualMemory 所做的 InLine Hook,也就是跳过前面 7 个字节就 OK 了。
对于这种干掉 InLine Hook 的原理,堕落天才的文章讲的最清楚了,我这里就不再班门弄斧了。

有的童鞋可能会问,咱是如何知道 NtReadVirtualMemory 被 TP 干掉了呢 ?
很简单,还是采用前面的做法,用 Kernel Detective 就可以看到了,具体可以看下面的截图:

261.jpg

262.jpg

下面先贴出安装 SSDT 钩子的代码,该代码用来干掉 TP 对 NtReadVirtualMemory 的 InLine Hook:
   1:  /************************************************************************/   2:  /* 安装钩子从而过掉 TP 保护所 Hook 的 NtReadVirtualMemory - 让 TP 失效   3:  /* 保存 NtReadVirtualMemory 第 4,5,6,7 个字节(其实就是一个 ULONG 跳转地址)   4:  /* 因为这几个字节在不同的 XP 上会改变,所以在 SSDT Hook 之前保存下来   5:  /* 从而避免在此处进行硬编码   6:  /************************************************************************/   7:  VOID InstallPassTPNtReadVirtualMemory()   8:  {   9:      if(g_SSDTHookNtReadVirtualMemory > 0)  10:      {  11:          /* 获得 NtReadVirtualMemory 的地址 */  12:          ULONG uNtReadVirtualMemoryAddr = oldSysServiceAddr[g_SSDTHookNtReadVirtualMemory];  13:     14:          /* 如果是 DNF 进程,则跳到 NtReadVirtualMemory 执行,即不处理,从而让 DNF InLine Hook 生效 */  15:          uTPHookedNtReadVirtualMemoryJmpAddr = uNtReadVirtualMemoryAddr;  16:          /* 如果不是 DNF 进程,则跳过 TP 的 InLine Hook,从而使 TP 失效 */  17:          uMyHookedNtReadVirtualMemoryJmpAddr = uNtReadVirtualMemoryAddr + 7;  18:          /* 保存下未 Hook 之前的 NtReadVirtualMemory 的第 4,5,6,7 个字节 */  19:          uNtReadVirtualMemoryAddr_3 = *((ULONG *)(uNtReadVirtualMemoryAddr + 3));  20:     21:          InstallSysServiceHookByIndex(g_SSDTHookNtReadVirtualMemory, SSDTHookNtReadVirtualMemory);  22:     23:          KdPrint(("Pass TP - NtReadVirtualMemory Installed."));  24:      }  25:  }

下面再给出 SSDT Hook 的中继 API 的实现代码:
   1:  /************************************************************************/   2:  /* 自定义的 NtReadVirtualMemory,用来实现 SSDT Hook Kernel API   3:  /************************************************************************/   4:  NTSYSHOOKAPI VOID SSDTHookNtReadVirtualMemory()   5:  {   6:      /* 开始过滤 */   7:      if(ValIDAteCurrentProcessIsDNF() == TRUE)   8:      {   9:          __asm  10:          {  11:              /* 如果是 DNF 进程调用的话,则调用已经被 TP Hook 的 NtReadVirtualMemory */  12:              jmp    uTPHookedNtReadVirtualMemoryJmpAddr  13:          }  14:      }  15:     16:      __asm  17:      {  18:          /* 已经做了针对硬编码的处理 */  19:          /* 如果不是 DNF 进程调用的话,则跳过 TP Hook 的 NtReadVirtualMemory */  20:          push    0x1C  21:          push    uNtReadVirtualMemoryAddr_3  22:          jmp     uMyHookedNtReadVirtualMemoryJmpAddr  23:      }  24:  }

好,到这里就已经干掉了 TP 对 NtReadVirtualMemory 所做的 InLine Hook了,
对此最直白的效果就是用 CE 打开 DNF 游戏进程进行内存扫描,你会发现,On Year,可以正常扫描到 DNF 内存了。

263.jpg

264.jpg

07. 干掉 NtWriteVirtualMemory 中的 InLine Hook:

上面又干掉了 TP 对 NtReadVirtualMemory 的 InLine Hook 了,从而实现了 CE 读取 DNF 进程的内存。
但是你可以试着用 CE 修改 DNF 进程的内存,你很快就会发现,虽然可以扫描内存,但是并不可以读取内存,
而后你也肯定能够想到,既然有防止读取内存,那肯定也有防止写入内存,
而后你又自然会找到 NtWriteVirtualMemory 上来,等你找到 NtWriteVirtualMemory 后,
你又基本能够确定,搞定这个 API 和搞定 NtReadVirtualMemory 应该是差不多的,
因为这两个 API 就是一对啊,一个读,一个写,所以 TP 肯定也是采用相同的做法来处理这两个 API,
当然,你上面的猜想都是正确的,所以咱还是用 SSDT 来干掉 TP 对 NtWriteVirtualMemory 所做的 InLine。
代码和上面的 NtReadVirtualMemory 差不多,这里也还是贴出来一下吧,俺先放两幅截图,然后再贴代码出来:

265.jpg

266.jpg

下面先贴出安装 SSDT 钩子的代码,该代码用来干掉 TP 对 NtWriteVirtualMemory 的 InLine Hook:
   1:  /************************************************************************/   2:  /* 安装钩子从而过掉 TP 保护所 Hook 的 NtWriteVirtualMemory - 让 TP 失效   3:  /* 保存 NtWriteVirtualMemory 第 4,5,6,7 个字节(其实就是一个 ULONG 跳转地址)   4:  /* 因为这几个字节在不同的 XP 上会改变,所以在 SSDT Hook 之前保存下来   5:  /* 从而避免在此处进行硬编码   6:  /************************************************************************/   7:  VOID InstallPassTPNtWriteVirtualMemory()   8:  {   9:      if(g_SSDTHookNtWriteVirtualMemory > 0)  10:      {  11:          /* 获得 NtWriteVirtualMemory 的地址 */  12:          ULONG uNtWriteVirtualMemoryAddr = oldSysServiceAddr[g_SSDTHookNtWriteVirtualMemory];  13:     14:          /* 如果是 DNF 进程,则跳到 NtWriteVirtualMemory 执行,即不处理,从而让 DNF InLine Hook 生效 */  15:          uTPHookedNtWriteVirtualMemoryJmpAddr = uNtWriteVirtualMemoryAddr;  16:          /* 如果不是 DNF 进程,则跳过 TP 的 InLine Hook,从而使 TP 失效 */  17:          uMyHookedNtWriteVirtualMemoryJmpAddr = uNtWriteVirtualMemoryAddr + 7;  18:          /* 保存下未 Hook 之前的 NtReadVirtualMemory 的第4,5,6,7 个字节 */  19:          uNtWriteVirtualMemoryAddr_3 = *((ULONG *)(uNtWriteVirtualMemoryAddr + 3));  20:     21:          InstallSysServiceHookByIndex(g_SSDTHookNtWriteVirtualMemory, SSDTHookNtWriteVirtualMemory);  22:     23:          KdPrint(("Pass TP - NtWriteVirtualMemory Installed."));  24:      }  25:  }

下面再给出 SSDT Hook 的中继 API 的实现代码:
   1:  /************************************************************************/   2:  /* 自定义的 NtWriteVirtualMemory,用来实现 SSDT Hook Kernel API   3:  /************************************************************************/   4:  NTSYSHOOKAPI VOID SSDTHookNtWriteVirtualMemory ()   5:  {   6:      /* 开始过滤 */   7:      if(ValidateCurrentProcessIsDNF() == TRUE)   8:      {   9:          __asm  10:          {  11:              /* 如果是 DNF 进程调用的话,则调用已经被 TP Hook 的 NtWriteVirtualMemory */  12:              jmp    uTPHookedNtWriteVirtualMemoryJmpAddr  13:          }  14:      }  15:     16:      __asm  17:      {  18:          /* 已经做了针对硬编码的处理 */  19:          /* 如果不是 DNF 进程调用的话,则跳过 TP Hook 的 NtWriteVirtualMemory */  20:          push    0x1C  21:          push    uNtWriteVirtualMemoryAddr_3  22:          jmp     uMyHookedNtWriteVirtualMemoryJmpAddr  23:      }  24:  }

好,到这里就已经拿下了 TP 对 NtWriteVirtualMemory 所做的 InLine Hook了,
对此最直白的效果大家也都可以想象得到了,那就是直接用 CE 打开 DNF 游戏进程进行内存修改,
你会发现,此时可以正常修改掉 DNF 游戏的内存了。

267.jpg


08. 干掉 KiAttachProcess 中的 InLine Hook:

前面已经干掉 NtOpenProcess 和 NtOpenThread 了,按道理来说,咱可以开始用 OD 来调试 DNF 游戏进程了,
不过你可以用 OD 尝试附加一下 DNF 的游戏进程,而后你会发现根本附加不上去,这又是为何呢 ?

268.jpg

首先需要明白 Ring3 在何种操作下,会导致内核调用 KiAttachProcess,
从字面意思上看,就是附加进程,在 Ring3 下的附加进程操作一般会出现在调试进程的时候,
比如用 OD 附加进程来进行调试,或者用 Visual Studio 附加进程进行调试,
其实咱猜的没错,就是当附加进程的时候会导致内核调用 KiAttachProcess,
TP 对这个未导出的 API 进行了 InLine Hook,从而使得 DNF 游戏进程不能被附加,
这样的话,咱的 OD 或者 Visual Studio 都是不能够附加上 DNF 的游戏进程来进行调试了。
正如前面分析的 NtReadVirtualMemory 和 NtWriteVirtualMemory 这两个 API 一样,
TP 对 KiAttachProcess 也是做的浅层的 InLine Hook,也就是只是 Hook 了函数头 7 个字节,
且 TP 对 KiAttachProcess 的 InLine Hook 也没有检测,所以干掉这个 API 还是比较简单的,
不过我们不可以像干掉 NtRead/WriteVirtualMemory 一样用 SSDT Hook 来对抗掉,
因为 KiAttachProcess 并没有在 SSDT 表中,不过我们可以直接恢复 TP 对 KiAttachProcess 的 Hook 即可。

前面也提到了 KiAttachProcess 是一个未导出的内核 API,
所以我们不能使用 MmGetSystemRoutineAddress 来获得它的地址,
不过好在 KeAttachProcess 这是一个导出的内核 API,
(一般 Kixxx 都是未导出的 API,而 Kexxx 则是导出的 API)
在 KeAttachProcess 的内部实质上是调用的 KiAttachProcess 来完成功能的,
所以咱可以通过 KeAttachProcess 来定位到 KiAttachProcess 的地址,
并且让人欣喜的是在 KeAttachProcess 中的第一个 call 就是 call KiAttachProcess,
所以搜索特征码也更加简单了,直接搜索第一个 e8 就 OK。
如果用 WinDbg 的话,你可以输几个命令就可以把 KeAttachProcess 的地址打印出来,但是现在咱走点弯路,
在驱动里面用 KdPrint 打印出 KeAttachProcess 的地址,然后我们再分析。
   1:  KdPrint(("KeAttachProcess: %x.", MmGetSystemFunAddress(L"KeAttachProcess")));

269.png

好,这里得到了 KeAttachProcess 的地址了,
那么咱就可以在 Kernel Detective 中来看看 KeAttachProcess 的反汇编代码了,
具体的就看图说话,俺也就不多说了,因为截图里面都明明白白摆着在哪里,

270.jpg

271.jpg

272.jpg

273.jpg

274.jpg

下面给出获取 KiAttachProcess 地址的代码:
   1:  /************************************************************************/   2:  /* 获取函数 KiAttachProcess 的地址   3:  /* KiAttachProcess 在 KeAttachProcess 中的第一个 Call(e8 指令) 位置   4:  /************************************************************************/   5:  ULONG GetKiAttachProcessAddr()   6:  {   7:      ULONG uCallAddr = 0;   8:      ULONG uKeAttachProcessAddr = 0;   9:      ULONG uKiAttachProcessAddr = 0;  10:      CHAR szCode[1] =   11:      {  12:          (char)0xe8  13:      };  14:     15:      /* 获取 KeAttachProcess 的地址 */  16:      uKeAttachProcessAddr = MmGetSystemFunAddress(L"KeAttachProcess");  17:     18:      /* 搜索特征码 e8 */  19:      uCallAddr = SearchFeature(uKeAttachProcessAddr, szCode, 1);  20:      if (uCallAddr == 0)  21:      {  22:          uKiAttachProcessAddr = 0;  23:      }  24:      else  25:      {  26:          /* 获取 KiAttachProcess 的地址 */  27:          uKiAttachProcessAddr = *((ULONG *)uCallAddr) + uCallAddr + 4;  28:      }  29:     30:      return uKiAttachProcessAddr;  31:  }

得到了 KiAttachProcess 的地址,那么下面就要来干掉 KiAttachProcess 了,
为了简单实现,我一开始干掉 KiAttachProcess 的做法是采用的硬编码,
在得到 KiAttachProcess 地址后,可以用 Xuetr 来反汇编这个地址,
从而看到 KiAttachProcess 的反汇编指令,所以我的做法就是,
直接将 Xuetr 中 KiAttachProcess 的头 7 个字节以硬编码的形式保存在数组中,
然后等 TP 启动后,我用保存下来的这 7 个字节直接去恢复 KiAttachProcess 就 OK,
这种方式在我的虚拟机 XP 里面是 OK 的,因为我就是从这台 XP 上获取的 7 个字节的硬编码,
但是在别的 XP 系统上就不 OK 了,原因是 KiAttachProcess 头 7 个字节并不是所有的 XP 都相同的,
直接拿不一致的硬编码去恢复肯定是会 BSOD 的,不过后来我用了一种简单的办法就干掉这个问题了,
办法很简单,在 TP 启动之前,我动态去读取 KiAttachProcess 的头 7 个字节,并且保存在数组中,
等 TP 启动后,我就用数组中的这 7 个字节去恢复 TP 对 KiAttachProcess 所做的 InLine Hook。

实现的具体代码很简单,下面也贴出来:
先在 TP 启动之前保存 KiAttachProcess 的头 7 个字节:
   1:      PUCHAR pKiAttachProcessAddr = NULL;   2:      3:      pKiAttachProcessAddr = (PUCHAR)GetKiAttachProcessAddr();   4:      5:      KdPrint(("KiAttachProcess: %x.", uKiAttachProcessAddr));   6:      7:      /* 保存 KiAttachProcess 被 DNF Hook 之前的头 API_HOOK_HEADER_LEN 个字节 */   8:      for(uIndex = 0; uIndex < API_HOOK_HEADER_LEN; uIndex++)   9:      {  10:          szKiAttachProcessOriginCode[uIndex] = pKiAttachProcessAddr[uIndex];  11:      }

TP 启动之后恢复被 TP 修改掉的 KiAttachProcess 的头 7 个字节:
   1:  /************************************************************************/   2:  /* 恢复 KiAttachProcess 头 9 个字节从而恢复 KiAttachProcess - 让 TP 失效   3:  /* 这里使用了硬编码,去掉硬编码的思路如下:   4:  /* 在 TP 未启动之前,先保存下 KiAttachProcess 的头 9 个字节   5:  /* 然后在 TP 启动之后,恢复这 9 个字节就 OK   6:  /************************************************************************/   7:  VOID RecoveryTPHookedKiAttachProcess()   8:  {   9:      ULONG uIndex = 0;  10:      ULONG uOldAttr = 0;  11:     12:      KIRQL kOldIRQL = PASSIVE_LEVEL;  13:      PUCHAR pKiAttachProcessAddr = NULL;  14:     15:      /* 获取到 KiAttachProcess 的地址 */  16:      pKiAttachProcessAddr = (PUCHAR)GetKiAttachProcessAddr();  17:     18:      EnableWriteProtect(&uOldAttr);  19:      kOldIRQL = KeRaiseIrqlToDpcLevel();  20:     21:      /* 恢复 KiAttachProcess 的头 API_HOOK_HEADER_LEN 个字节 */  22:      for(uIndex = 0; uIndex < API_HOOK_HEADER_LEN; uIndex++)  23:      {  24:          pKiAttachProcessAddr[uIndex] = szKiAttachProcessOriginCode[uIndex];  25:      }  26:     27:      KeLowerIrql(kOldIRQL);  28:      DisableWriteProtect(uOldAttr);  29:     30:      KdPrint(("Pass TP - KiAttachProcess Installed."));  31:  }


到这里,我们又把 KiAttachProcess 给搞定了,所以此时咱可以用 OD 来附加 DNF 游戏进程试试看了,
此时你会发现咱可以将 OD 附加上去了,不过可惜的是,就算附加上去了,离使用 OD 来调试 DNF 还远着呢,
因为 TP 对 DNF 游戏进程还有其他的保护措施,它在内核里面 Hook 的 API 可不止这么点哦。


总结:

《过 DNF TP 驱动保护》的第二篇到这里就结束了,经过上面的处理,
我们已经过掉了 TP 所做 InLine Hook 的 5 个 API 了,
首先是 NtOpenProcess 和 NtOpenThread 的深层 InLine Hook,
然后是 SSDT 系统服务函数 NtReadVirtualMemory 和 NtWriteVirtualMemory 的浅层次 InLine Hook,
最后我们也干掉了 TP 对未导出内核函数 KiAttachProcess 所做的浅层次 InLine Hook。
虽然也干掉了不少 TP 在内核中 Hook 的 API 了,但是这离过 DNF TP 驱动保护还比较远的,
详情还得留到下回分解了。
游客,如果您要查看本帖隐藏内容请回复




联系我时,请说是在 挂海论坛 上看到的,谢谢!

免费评分

参与人数 4海币 +4 收起 理由
lonny522 + 1 支持开源~!感谢分享
qq270122483 + 1
戒律之锁链 + 1
八云紫 + 1

查看全部评分




上一篇:过 DNF TP 驱动保护(一)
下一篇:VB函数添加大师(不断更新)
4中级会员
365/600

365

积分

109

主题

2

听众
已帮网友解决0 个问题
贡献
256
海币
2515
交易币
0
发表于 2014-7-12 06:32:58 | 显示全部楼层
楼主,不论什么情况你一定要hold住!hold住就是胜利!

89

积分

26

主题

3

听众
已帮网友解决0 个问题
贡献
63
海币
1094
交易币
0
发表于 2014-7-27 10:46:39 | 显示全部楼层
楼主 支持一下

0

积分

0

主题

3

听众
已帮网友解决0 个问题
贡献
0
海币
2
交易币
0
发表于 2014-7-29 10:12:55 | 显示全部楼层
支持,外挂海 强烈支持楼主ing……

92

积分

43

主题

1

听众
已帮网友解决0 个问题
贡献
49
海币
112
交易币
0
发表于 2014-8-10 16:25:31 | 显示全部楼层
看帖看完了至少要顶一下,还可以加入到淘帖哦!

0

积分

0

主题

0

听众
已帮网友解决0 个问题
贡献
0
海币
10
交易币
0
发表于 2014-8-21 06:38:52 | 显示全部楼层
没啥说的先顶在下!!!!!!!!!!
3正式会员
279/300

279

积分

110

主题

6

听众
已帮网友解决0 个问题
贡献
169
海币
5792
交易币
0
发表于 2014-8-29 19:02:08 | 显示全部楼层
这不错!终于等到了!
贡献
0
海币
57
交易币
0
发表于 2014-9-3 13:40:25 | 显示全部楼层

楼主 支持一下

1

积分

0

主题

3

听众
已帮网友解决0 个问题
贡献
1
海币
1
交易币
0
发表于 2014-12-18 07:39:32 | 显示全部楼层
激动人心,无法言表!
8资深会员
1333/1800

1333

积分

291

主题

30

听众
已帮网友解决0 个问题
贡献
1042
海币
729
交易币
5
发表于 2014-12-21 23:37:03 | 显示全部楼层
1v1飘过
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|挂海论坛

GMT+8, 2019-10-21 15:44 , Processed in 0.343200 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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