关于Win7 x64下过TP保护(内核层)(转)

首先特别感谢梦老大,本人一直没搞懂异常处理机制,看了他的教程之后终于明白了。
在他的教程里我学到了不少东西。
第一次在论坛发帖,就说说Win7 x64位下怎么过TP保护。如果有讲错的地方,还望指出。
说不定我发帖后一星期TP就会大更新呢。
打字排版好辛苦。 
先说说内核层,看大家的反应后再说说应用层的保护。(包括解决CE非法问题)

调试对象:DXF
调试工具:OD、Windbg
调试环境:Win7 SP1 X64

调试先言:我记得TP最近的一次大更新是在去年的暑假,在那之前的ring0保护和现在的已经大有不同了。
不过还是少不了DebugPort清零。

内核层部分:
x64下因为有PatchGuard的限制,很多保护都被巨硬给抹掉了。
比如SSDT Hook Inline Hook 所以TP无法继续使用这些保护手段了。
除非腾Xun冒着被巨硬吊销数字签名的风险来阻止我们调试。
我曾经在看雪论坛里看过有个人写的文章,它亲自测试在x64环境下清零调试端口,结果发生了蓝屏,
所以在x64下TP是不会清零的。这样就省了不少的事情。
但是自从那次TP大更新后新加入了ValidAccessMask清零。
那么在ring0中 TP除了ValidAccessMask清零,还有反双机调试,这里不是我们讨论的范畴。
我们只是讨论如何才能正常调试游戏,于是在内核层我们只要解决ValidAccessMask清零就可以了。

调试权限(ValidAccessMask)的清零
这个标志位其实是DebugObject (调试对象)的权限,如果为0将导致无法创建调试对象(缺少权限)。
常见的情况就是OD无法附加任何进程,这个保护刚刚出的时候很多菜鸟都没搞懂,包括我自己(知道被我师傅说我等级太低时的心情是什么?)。
这个DebugObject在很多调试函数中都有用到 ,比如NtCreateDebugObject就有需要访问调试对象。
所以要想办法恢复这个标志位。
我们有三种选择:1、自己恢复原来的值 2、找到TP清零的位置Nop掉 3、移位(重建DebugObject)
这里我选择了第一种。

具体步骤如下:
①定位DebugObject:
在NtCreateDebugObject里就有DebugObject的地址。
1: kd> uf NtCreateDebugObject
nt!NtCreateDebugObject:
fffff800`042697a0 48895c2408      mov     qword ptr [rsp+8],rbx
fffff800`042697a5 4889742410      mov     qword ptr [rsp+10h],rsi
fffff800`042697aa 57              push    rdi
fffff800`042697ab 4883ec70        sub     rsp,70h
fffff800`042697af 418bf9          mov     edi,r9d
fffff800`042697b2 8bf2            mov     esi,edx
fffff800`042697b4 488bd9          mov     rbx,rcx
fffff800`042697b7 65488b042588010000 mov   rax,qword ptr gs:[188h]
fffff800`042697c0 448a90f6010000  mov     r10b,byte ptr [rax+1F6h]
fffff800`042697c7 4584d2          test    r10b,r10b
fffff800`042697ca 7414            je      nt!NtCreateDebugObject+0x40 (fffff800`042697e0)
nt!NtCreateDebugObject+0x2c:
fffff800`042697cc 488b052d38e5ff  mov     rax,qword ptr [nt!MmUserProbeAddress (fffff800`040bd000)]
fffff800`042697d3 483bc8          cmp     rcx,rax
fffff800`042697d6 480f43c8        cmovae  rcx,rax
fffff800`042697da 488b01          mov     rax,qword ptr [rcx]
fffff800`042697dd 488901          mov     qword ptr [rcx],rax
nt!NtCreateDebugObject+0x40:
fffff800`042697e0 48832300        and     qword ptr [rbx],0
fffff800`042697e4 41f7c1feffffff  test    r9d,0FFFFFFFEh
fffff800`042697eb 740a            je      nt!NtCreateDebugObject+0x57 (fffff800`042697f7)
nt!NtCreateDebugObject+0x4d:
fffff800`042697ed b80d0000c0      mov     eax,0C000000Dh
fffff800`042697f2 e9e4000000      jmp     nt!NtCreateDebugObject+0x13b (fffff800`042698db)
nt!NtCreateDebugObject+0x57:
fffff800`042697f7 488d442450      lea     rax,[rsp+50h]
fffff800`042697fc 4889442440      mov     qword ptr [rsp+40h],rax
fffff800`04269801 8364243800      and     dword ptr [rsp+38h],0
fffff800`04269806 8364243000      and     dword ptr [rsp+30h],0
fffff800`0426980b c744242868000000 mov     dword ptr [rsp+28h],68h
fffff800`04269813 488364242000    and     qword ptr [rsp+20h],0
fffff800`04269819 458aca          mov     r9b,r10b
fffff800`0426981c 488b158dd3daff  mov     rdx,qword ptr [nt!DbgkDebugObjectType (fffff800`04016bb0)]
fffff800`04269823 418aca          mov     cl,r10b
fffff800`04269826 e84572f1ff      call    nt!ObCreateObject (fffff800`04180a70)
fffff800`0426982b 4c8b4c2450      mov     r9,qword ptr [rsp+50h]
fffff800`04269830 4c894c2460      mov     qword ptr [rsp+60h],r9
fffff800`04269835 85c0            test    eax,eax
fffff800`04269837 0f889e000000    js      nt!NtCreateDebugObject+0x13b (fffff800`042698db)
这个红字就是了 
继续定位ValidAccessMask的地址。

1: kd> dq fffff800`04016bb0
fffff800`04016bb0  fffffa80`00c33200 00000000`00000000
fffff800`04016bc0  fffff8a0`0009a010 0000002a`00000012
fffff800`04016bd0  00000024`000000a1 fffff880`0119d9a0
fffff800`04016be0  00000002`00000001 fffff880`095deacc
fffff800`04016bf0  fffff800`03f873f0 00000000`00000007
fffff800`04016c00  00000003`00000000 fffff800`03e10448
fffff800`04016c10  fffffa80`01bae060 00000000`00000000
fffff800`04016c20  00000000`00000000 00000003`00000101

1: kd> dt _OBJECT_TYPE fffffa80`00c33200
nt!_OBJECT_TYPE
   +0x000 TypeList         : _LIST_ENTRY [ 0xfffffa80`00c33200 - 0xfffffa80`00c33200 ]
   +0x010 Name             : _UNICODE_STRING "DebugObject"
   +0x020 DefaultObject    : (null) 
   +0x028 Index            : 0xb ‘‘
   +0x02c TotalNumberOfObjects : 0
   +0x030 TotalNumberOfHandles : 0
   +0x034 HighWaterNumberOfObjects : 0
   +0x038 HighWaterNumberOfHandles : 0
  +0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0b0 TypeLock         : _EX_PUSH_LOCK
   +0x0b8 Key              : 0x75626544
   +0x0c0 CallbackList     : _LIST_ENTRY [ 0xfffffa80`00c332c0 - 0xfffffa80`00c332c0 ]

1: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`00c33200+40
nt!_OBJECT_TYPE_INITIALIZER
   +0x000 Length           : 0x70
   +0x002 ObjectTypeFlags  : 0x8 ‘‘
   +0x002 CaseInsensitive  : 0y0
   +0x002 UnnamedObjectsOnly : 0y0
   +0x002 UseDefaultObject : 0y0
   +0x002 SecurityRequired : 0y1
   +0x002 MaintainHandleCount : 0y0
   +0x002 MaintainTypeList : 0y0
   +0x002 SupportsObjectCallbacks : 0y0
   +0x002 CacheAligned     : 0y0
   +0x004 ObjectTypeCode   : 0
   +0x008 InvalidAttributes : 0
   +0x00c GenericMapping   : _GENERIC_MAPPING
   +0x01c ValidAccessMask  : 0x1f000f
   +0x020 RetainAccess     : 0
   +0x024 PoolType         : 0 ( NonPagedPool )
   +0x028 DefaultPagedPoolCharge : 0
   +0x02c DefaultNonPagedPoolCharge : 0x58
   +0x030 DumpProcedure    : (null) 
   +0x038 OpenProcedure    : (null) 
   +0x040 CloseProcedure   : 0xfffff800`042b18e0     void  nt!DbgkpCloseObject+0
   +0x048 DeleteProcedure  : 0xfffff800`04105200     void  nt!xHalEndOfBoot+0
   +0x050 ParseProcedure   : (null) 
   +0x058 SecurityProcedure : 0xfffff800`04170530     long  nt!SeDefaultObjectMethod+0
   +0x060 QueryNameProcedure : (null) 
   +0x068 OkayToCloseProcedure : (null)

于是我们就定位到了VaildAccessMask的地址了。

②恢复工作
它的默认值是0x1F000F
当我们自己手动修改成0时。
使用OD附加任意进程。
<ignore_js_op> 
无法附加,那我们就要手动恢复成0x1F000F。
具体方式我采用开DPC定时器的方法恢复,恢复的频率不会和TP的冲突。
代码我贴出一部分,部分函数需要自己手动编写,因为在64位下编写驱动寻找SSDT等都比较麻烦。
这些函数大家可以去网上一些x64驱动编写的教程里面抄下。
我在这里推荐下Tesla.Angela的教程《WIN64驱动编程基础教程》

  1. #ifndef PROC
  2. #define PROC
  3. PVOID pNtCreateDebugObject;
  4. PVOID pDbgkDebugObject;
  5. PVOID pDebugObject;
  6. PVOID pValidMask;
  7. KTIMER PassObjTimer;
  8. KDPC PassObjDpc;
  9. LARGE_INTEGER PassObjTime;
  10. PVOID pKeStackAttachProcess;
  11. PVOID pKeStackAttachProcessJmpAddr;
  12. byte  bufKeStackAttachProcess[13];
  13. VOID
  14. PassObj(
  15. __in struct _KDPC  *Dpc,
  16. __in_opt PVOID  DeferredContext,
  17. __in_opt PVOID  SystemArgument1,
  18. __in_opt PVOID  SystemArgument2
  19. )
  20. {
  21. __try
  22. {
  23. WriteProtectOff();
  24. *((ULONG*)pValidMask) = 0x1F000F;
  25. WriteProtectOn();
  26. }
  27. __except (1)
  28. {
  29. KeCancelTimer(&PassObjTimer);
  30. return;
  31. }
  32. KeSetTimer(&PassObjTimer, PassObjTime, &PassObjDpc);
  33. return;
  34. }
  35. VOID PassObjectMask()
  36. {
  37. PVOID pTargetAddr;
  38. pNtCreateDebugObject = (PVOID)GetSSDTFunctionAddress(144);
  39. pTargetAddr = (PVOID)(((ULONG64)pNtCreateDebugObject) + 0x7C);
  40. pDbgkDebugObject=(PVOID)(MAKE_TARGETADDR((*((ULONG*)(((ULONG64)pTargetAddr) + 3))), (ULONG64)pTargetAddr));
  41. pDebugObject = (PVOID)(*((ULONG64*)pDbgkDebugObject));
  42. pValidMask = (PVOID)(((ULONG64)pDebugObject) + 0x40 + 0x1c);
  43. PassObjTime.QuadPart = -10000 * 100;
  44. KeInitializeTimer(&PassObjTimer);
  45. KeInitializeDpc(&PassObjDpc, &PassObj, NULL);
  46. KeSetTimer(&PassObjTimer, PassObjTime, &PassObjDpc);
  47. }
  48. VOID UnPassObjectMask()
  49. {
  50. KeCancelTimer(&PassObjTimer);
  51. }
  52. #endif

复制代码

时间: 2024-10-22 00:19:20

关于Win7 x64下过TP保护(内核层)(转)的相关文章

关于Win7 x64下过TP保护(应用层)(转)

非常感谢大家那么支持我上一篇教程.Win10 快出了,所以我打算尽快把应用层的部分说完. 调试对象:DXF调试工具:CE.OD.PCHunter.Windbg调试先言:TP的应用层保护做得比较多,包括对调试器的检测,比如CE工具会被DXF报非法.有的保护还是内核与应用层交替保护. 应用层:1.TP让调试器卡死(内核互动)现象: <ignore_js_op> 如图,TP会检测调试器让调试器暂停运行,实际上就是暂停了调试器所有的线程而已.这个保护是今年7月份新出的,所以我这里重点分析下,我刚开始调

Win7 x64下进程保护与文件保护(ObRegisterCallbacks)

参考 http://bbs.pediy.com/showthread.php?t=168023 进程保护,在任务管理器不能结束进程 #ifndef CXX_PROTECTPROCESSX64_H #define CXX_PROTECTPROCESSX64_H #include <ntifs.h> #define PROCESS_TERMINATE 0x0001 #define PROCESS_VM_OPERATION 0x0008 #define PROCESS_VM_READ 0x0010

Oracle学习笔记1:win7 x64下安装Oracle10g

oracle 10g在win7x64下的安装: 第一次直接双击setup,出错了…… 可能是兼容性的问题,所以试着 右击setup-->属性-->兼容性-->勾上"以兼容模式运行这个程序"复选框,下拉列表选择了默认选择了Windows XP sp3 然后再双击运行,就可以正常安装了. 安装之初为所有用户设置了统一的口令 安装结束一定要注意进行口令管理,对scott这个常用的普通用户解锁.在这里可以为各个用户设置新的口令.常用到的用户可能有 sys, system, s

Win7(X64) 下安装PostgreSQL及postgis

最快捷径: 1. 从官网直接 下载postgresql-9.6.5-1-windows-x64-binaries.zip,解压,手动执行cmd,...安装完毕! 2. http://download.osgeo.org/postgis/windows/pg96/ ,挑选合适的版本,其它无可言. 注:BigSQL的PGC本意好,可网络不好,安装起来相当坑!

WIN7 x64下java 8的环境变量配置

Oracle官网下载JDK进行安装:我下载的是Java 8 JDK,地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 打开安装包,完成安装 配置环境变量:计算机右键-->属性-->高级系统设置-->环境变量 在系统变量处操作: (1)新建:JAVA_HOME C:\Program Files\Java\jdk1.8.0_144(2)新建:JRE_HOME C:\Pr

X64下MmIsAddressValid的逆向及内存寻址解析

标 题: [原创]X64下MmIsAddressValid的逆向及内存寻址解析 作 者: 普通朋友 时 间: 2015-10-21,20:03:52 链 接: http://bbs.pediy.com/showthread.php?t=205143 在内核编程时,经常会用到MmIsAddressValid来检测地址是否有效,结合之前学过的虚拟地址到物理地址之间的转化,所以发一篇对该函数的逆向以及代码还原,x86的资料论坛以及网络有很多了,所以这里楼主只谈一下Win7 x64下的MmIsAddre

也谈Theano在Win7 x64和Python 3.4下的安装

一.前言 2012年3月,与某老师交流的时候,初次得知Deep Learning的概念,当时,他还建议我研究GPU计算.回来后,认真研读了一些文件,也看到了deeplearning.net网站的内容,但是由于时间和精力的问题,没有深入研究.最近有点时间,重新捡起来,准备先搭建环境.看中了该网站推荐的Theano,于是按着说明安装下来. Theano的运行环境为Python,这种脚本语言我是第一次接触.仔细看了看发现实在是奇葩,Python竟然有2.x和3.x两个分支,而且2.x还拥有相当大的用户

VS2012在win7 64位机中x86和x64下基本类型的占用空间大小(转)

VS2012在win7 64位机中x86和x64下基本类型的占用空间大小 #include "stdafx.h" #include <windows.h> int _tmain(int argc, _TCHAR* argv[]) { int i = 0; i = sizeof(int); // x86:4 x64:4 i = sizeof(long); // x86:4 x64:4 i = sizeof(void*); // x86:4 x64:8 i = sizeof(s

WIN10 X64下通过TLS实现反调试

目录(?)[-] TLS技术简介 1 TLS回调函数 2 TLS的数据结构 具体实现及原理 1 VS2015 X64 release下的demo 2 回调函数的具体实现 21 使用IsDebuggerPresent检测调试器 22 使调DebugPort检测调试器 实际测试 1 测试直接执行 2 测试用调试器加载 总 结 1 TLS技术简介 Thread Local Storage(TLS),是Windows为解决一个进程中多个线程同时访问全局变量而提供的机制.TLS可以简单地由操作系统代为完成