王者至尊 发表于 2013-7-31 22:12:00

谈谈最新TP的PASS方法,已过所有钩子,两种不同的清零。

仅献给广海,转载请声明出处
本文仅供学习研究,请勿用于商业目的,如用于商业目的,本文笔者一律不负责
正文:
不知道TP更新了,今天又见到久违的蓝精灵。
实在太菜,不得不膜拜某些大牛的手法。
由于我知识量实在太少了,下面的对付手法仅献给同我一样的菜鸟使用,高手笑过吧,别喷。。
(╯▽╰)
注:以下未加以说明的全部采用绕过的方式。如果上次可以直接还原的这次估计不可以了
新的TP
NtOpenProcess特征不变,过的方法不变
NtReadVirtualMemory 照样是头部HOOK
NtWriteVirtualMemory 照样是头部HOOK
NtOpenThread 特征不变,过的方法不变
KeAttachProcess 照旧
KeStackAttachProcess 照旧
NtDebugActiveProcess 未见HOOK
PsSuspendThread新增的
nt!PsSuspendThread:
8063849d 6a18            push    18h
8063849f 6870f55280      push    offset nt!ObWatchHandles+0x784 (8052f570)
806384a4 e8cab9eaff      call    nt!_SEH_prolog (804e3e73)
806384a9 33f6            xor   esi,esi
806384ab 8975e4          mov   dword ptr ,esi
806384ae 64a124010000    mov   eax,dword ptr fs:
806384b4 8b7d08          mov   edi,dword ptr
806384b7 3bf8            cmp   edi,eax
806384b9 7538            jne   nt!PsSuspendThread+0x4c (806384f3)
806384bb 8975fc          mov   dword ptr ,esi
806384be 57            push    edi
806384bf e8dd2aecff      call    nt!KeSuspendThread (804fafa1)
806384c4 8945e4          mov   dword ptr ,eax
806384c7 8975dc          mov   dword ptr ,esi
806384ca 834dfcff      or      dword ptr ,0FFFFFFFFh
806384ce e99e000000      jmp   nt!PsSuspendThread+0xc0 (80638571)
806384d3 90            nop
806384d4 90            nop
806384d5 90            nop
806384d6 90            nop
806384d7 90            nop
806384d8 8b45ec          mov   eax,dword ptr
806384db 8b00            mov   eax,dword ptr
806384dd 8b00            mov   eax,dword ptr
806384df 8945e0          mov   dword ptr ,eax
806384e2 33c0            xor   eax,eax
806384e4 40            inc   eax
806384e5 c3            ret
806384e6 90            nop
806384e7 90            nop
806384e8 90            nop
806384e9 90            nop
806384ea 90            nop
806384eb 8b65e8          mov   esp,dword ptr
806384ee 8b75e0          mov   esi,dword ptr
806384f1 ebd7            jmp   nt!PsSuspendThread+0x2d (806384ca)
806384f3 8d8f34020000    lea   ecx,
806384f9 e8768cf3ff      call    nt!ExAcquireRundownProtection (80571174)
806384fe 84c0            test    al,al
80638500 746a            je      nt!PsSuspendThread+0xbb (8063856c)
80638502 33c0            xor   eax,eax
80638504 40            inc   eax
80638505 848748020000    test    byte ptr ,al
8063850b 754d            jne   nt!PsSuspendThread+0xa9 (8063855a)
8063850d 8945fc          mov   dword ptr ,eax
80638510 57            push    edi
80638511 e88b2aecff      call    nt!KeSuspendThread (804fafa1)
80638516 8945e4          mov   dword ptr ,eax
80638519 8975dc          mov   dword ptr ,esi
8063851c 834dfcff      or      dword ptr ,0FFFFFFFFh
80638520 eb25            jmp   nt!PsSuspendThread+0x96 (80638547)
80638522 90            nop
80638523 90            nop
80638524 90            nop
80638525 90            nop
80638526 90            nop
80638527 8b45ec          mov   eax,dword ptr
8063852a 8b00            mov   eax,dword ptr
8063852c 8b00            mov   eax,dword ptr
8063852e 8945d8          mov   dword ptr ,eax
80638531 33c0            xor   eax,eax
80638533 40            inc   eax
80638534 c3            ret
80638535 90            nop
80638536 90            nop
80638537 90            nop
80638538 90            nop
80638539 90            nop
8063853a 8b65e8          mov   esp,dword ptr
8063853d 8b75d8          mov   esi,dword ptr
80638540 834dfcff      or      dword ptr ,0FFFFFFFFh
80638544 8b7d08          mov   edi,dword ptr
80638547 f6874802000001test    byte ptr ,1
8063854e 740f            je      nt!PsSuspendThread+0xae (8063855f)
80638550 57            push    edi
80638551 e8144debff      call    nt!KeForceResumeThread (804ed26a)
80638556 8365e400      and   dword ptr ,0
8063855a be4b0000c0      mov   esi,0C000004Bh
8063855f 8d8f34020000    lea   ecx,
80638565 e8e68bf3ff      call    nt!ExReleaseRundownProtection (80571150)
8063856a eb05            jmp   nt!PsSuspendThread+0xc0 (80638571)
8063856c be4b0000c0      mov   esi,0C000004Bh
80638571 8b450c          mov   eax,dword ptr
80638574 85c0            test    eax,eax
80638576 7405            je      nt!PsSuspendThread+0xcc (8063857d)
80638578 8b4de4          mov   ecx,dword ptr
8063857b 8908            mov   dword ptr ,ecx
8063857d 8bc6            mov   eax,esi
8063857f e82ab9eaff      call    nt!_SEH_epilog (804e3eae)
80638584 c20800          ret   8
原型
同样的
0x8063849D    |    B8 B0E622B2    |    mov eax, B222E6B0    |         
0x806384A2    |    FFE0    |    jmp eax    |         
XP下获取函数地址方法(我这个比较逊)
首先从SSDT索引号254获取到NtSuspendThread的地址
然后往下第三个CALL就是PsSuspendThread了
读取位移量
然后当前指令地址+位移量+5获取到地址
然后
直接把这个NtSuspendThread(不是PsSuspendThread) 的CALL HOOK掉吧
OD挂起线程只会通过NtSuspendThread不用其他的
应该不用怕PsSupendThread不只这个地方调用
有个问题就是
模拟PsSuspendThread头部时
push    offset nt!ObWatchHandles+0x784
这个参数怎么解决
关键就是获取这个ObWatchHandles了
偏移0x784在XP下万年不变
没事我们找其他地方入手
看看头部没被HOOK的NtSuspendThread:吧
nt!NtSuspendThread:
806385eb 6a20            push    20h
806385ed 6888f55280      push    offset nt!ObWatchHandles+0x79c (8052f588)
806385f2 e87cb8eaff      call    nt!_SEH_prolog (804e3e73)
806385f7 33db            xor   ebx,ebx
806385f9 895dfc          mov   dword ptr ,ebx
806385fc 64a124010000    mov   eax,dword ptr fs:
80638602 8945d0          mov   dword ptr ,eax
80638605 8a8040010000    mov   al,byte ptr
好吧,看到了一个羞涩的少女等待着我们的侵犯。。
通过NtSuspendThread:的头部获取offset nt!ObWatchHandles+0x79c
然后-0x79c
最后+0x784
然后就是我们要模拟push 的值了
(原本想通过NtOpenThread的头部获取的,但是发现虽然我真机上ObWatchHandles的值相同,但是虚拟机上的不一样,虚拟机上就NtSuspendThread:和PsSuspendThread的ObWatchHandles的值相同,果然是好基友。。)
NtDebugActiveProcess这里面我没去看,反正我用原来的写法不蓝
DbgkpPostFakeProcessCreateMessages 同上,都是没去看的东西,节省点时间
DbgPostFakeModuleMessages同上
DbgkpSendApiMessage同上(现在基本都在排错了,节省时间)
(dbg开头的估计没HOOK,因为我的写法比较通用,所以没HOOK照样不蓝)
硬件断点处理是一样的
清零,好吧,我根本没指望它不蓝,额果断蓝了。
没事,先别搞它
NtProtectVirtualMemory
对抗方法SSDT HOOK
这次依旧是那个push的值的问题(说实话以前处理NtReadVirtualMemory时push一个错误的值都不会怎么样。。。)

(测试结果:push一个N+1奇葩的数值照样可行)
这次可以在mov eax,Bxxxxxxx
             Jmp eax
这里获取Bxxxxxxx这个地址
然后来到这个地址,往下数个字节后可以读到push的值



怪异现象:过完上面一堆钩子后,开GAME
之后再开OD随便附加,不附加指定GAME居然也能附加不成功(╮(╯_╰)╭我又不搞你)
NtDebugActiveProcess中第二个CALL
call    nt!ObReferenceObjectByHandle
中的参数的结构中的几个成员被清零了
具体的成员:有个指针参数指向ObjectType结构,该结构下还有一个结构
+0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER(这个结构的地址固定不变,所以可以方便的执行清零)
具体被清零的成员为
OBJECT_TYPE_INITIALIZER的成员
+0x008 GenericMapping   : _GENERIC_MAPPING
   +0x018 ValidAccessMask: Uint4B
   +0x01c SecurityRequired : UChar
这3个出问题了(应该是这3个,反正是OBJECT_TYPE_INITIALIZER的成员)
全被清零了
自己下断自行对抗吧
对抗方法:让它获取到错误的地址
以下转自看雪thenight的文章

b =*(*(tpbase+0x44a74));
c=b+0x78;
//xp 2k3为0x78   win7win8为+0x44
*c=0x1f000f;

b+=8;
*a =b;
* (tpbase+0x44a74) =a;



上面的不管你a,b,c定义成指针还是int都会非法寻址的,想用的加N个强制转换吧如果编译器比较奇葩还容易蓝,估计是个伪代码,内联汇编会比较好受点好吧
按照上面代码来看+8,结果转移清到一个不应该为0的东西去了
不知道有没有事情
所以大家用下面的代码吧,转移+76没问题,下面是3个成员全恢复的代码

       __asm
       {
            //esi作为TP+0x44a74,edi作为b+0x78,eax,ebx存储临时的值
            //各个成员的值你们自己确定XP和WIN7是不是一样的
            pushad
            pushfd
            mov esi,tpbase
            cmp tpbase,0
            je over
            add esi,0x44a74
            mov eax,
            mov ObjectTypeAddr,eax
            mov eax,;b
            movOldObjectTypeValue,eax
            lea edi,
            mov dword ptr ,00020001h
            add edi,4
            mov dword ptr ,00020002h
            add edi,4
            mov dword ptr ,00120000h
            add edi,4
            mov dword ptr ,001f000fh
            add edi,4
            mov dword ptr ,001f000fh
            add eax,76
            mov esi,
            mov ,eax
over:
            popfd
            popad
       }
      
改一个 3个都不会被清到,原理:其他几个都是通过这里计算出来的

计算方法就是xor add了当然,清零还没有过完。因为这里改了不止影响到TP额
(好吧,看雪发帖的那家伙肯定没测试撒。没事,小错误,我们原谅它)不过没事,解决还是很简单
HOOK NtCreateDebugObject(SSDT号33) , NtWaitForDebugEvent(269) NtDebugActiveProcess(57) NtDebugContinue (58)就行
(它们会采用push [存储结构地址的地址]HOOK修改成正确的值就行)仅对附加有效,想调试游戏时顺便用打开的方式调试别的东西的同学,小心蓝瓶
这里自己分析下打开方式什么时候调用到这个结构就行,下访问断点即可当然需要使用剥离进程这东西的同学,还得继续。。。哦~~
当然还有更暴力的做法(仅是本人YY),暴力搜索push [存储结构地址的地址]
暴力搜索上面这样的指令,然后开辟个全局变量存储正确的值然后全部修改成push [我们的全局变量]
同时记录被修改的地方,存放在一个动态数组里面(以便卸载时恢复)这样应该也可行,而且由于它的特征:重复性
这一点可以让我们写个很通用的PASS方式。是否可行等我有空再测试吧- - 大家喜欢自己去测试这个绝对好用
NtCreateDebugObject(33) , NtWaitForDebugEvent(269) NtDebugActiveProcess(57) NtDebugContinue (58)
反正这四个用到的都是push [存储结构地址的地址]这样的格式,估计其他的也是╮(╯▽╰)╭哎,糟糕,我用了hook的方式,没有早点想到额。。
还有注意,PASS清零这个地方PASS一次直至重启之前都有影响(也就是过一次就不用过第二次)所以卸载时需要恢复         


       __asm      
      {
            pushad
            pushfd               
            mov esi,ObjectTypeAddr
            mov eax,            
            sub eax,76
            mov ,eaxover:
            popfd               
            popad
       }
想搞定内核线程来对抗以上清零的,不管是直接结束,还是HOOKKIREADYTHREAD都不行,

估计R3和R0的线程有通讯,自己基友太久没消息,发疯起来会给你0x64的


你要正面对抗敏感区域也行,不过效验有点伤。


另外要提前把定时器对象取消掉(定时器时间周期5s ,5s真男人?)
这个枚举到就KeCancelTimer
还有一个IO TIMER
枚举到就IoStopTimer
系统回调爱禁止不禁止,这个版本我不弄它,枚举上面那两个就够我受的了
Debugport清零,TP这次异常的水啊。
大家自己想吧,有很多个方法,比如对付那个镜像copy啊,还有之类的,当然我说的这是最复杂的方法。因为HOOK这个东西要过滤太多东西了。
大家自己对抗吧,非常的简单。不要想复杂,什么都去尝试下就行


吐槽:TP的跳转真风骚,跟调试他的GAME的关键地方一样累+_+
事实上不用去管跳转,分析要用到而已,过的时候不用用到

最后关于附加网络连接中断的问题,听说OD附加时会自动恢复一些R3钩子
所以游戏检测代码被修改,于是掉线,过掉代码检测就好

andy03 发表于 2013-8-1 00:24:32

没这么复杂。。。走我自己内核,

1433784648 发表于 2013-8-1 09:45:46

支持看流星社区         支持看流星社区
页: [1]
查看完整版本: 谈谈最新TP的PASS方法,已过所有钩子,两种不同的清零。