这两天在研究TX的那根233B线程,虽然可以直接终止它达到调试器附加不闪退的效果,但是我并不想这么做。知道它做了什么不是更有趣嘛。
说下我的研究过程:
用windbg ->F6 ->附加TP游戏
会收到0xC0000005 异常,不用管它,游戏有VEH会自己接管,windbg ->Event Filters过滤掉0xC000005异常。
接着,收到了 80000002 异常,#~ 查看异常发生的线程,xxxx233B (很多人以为该线程自己触发int3 自己接管,其实并不是) gn ->游戏挂掉咯,因为游戏找不到异常处理函数。
这时候,我想知道游戏为何没有自己接管这个异常。
然后我便HOOK了 KiUserExceptionDispatcher(虽然游戏自己也HOOK了,但是可以在它Hook过后的地址再HOOK嘛~) ,过滤出来0x80000002 的异常,然后我用ollydbg下一个断,想看看它为何没有找到异常处理函数 (并不能条件断点,异常太多了,od会卡死)
走过150行VM代码(没有任何意义的VM) 然后进入了RtlDispatchException ,经过VEH 2个处理函数都不接管,在即将进入SEH的时候,没想到 test bl,0x3 这一句 直接跳过了SEH (bl是 PEB地址的最后2个字节,这里不明白为啥有这样一个判断) ,最后是UEF,看了下异常处理函数链,根本就没有UEF处理函数~~ 最后又走过了一大堆VM,ZwRaiseException ... 进程挂掉...
这时我便知道了,这个异常根本没有接管函数。。。
于是我便修改了int3地址的内存~!!!游戏没有挂掉,这说明了,在调试器没有附加的时候,这根线程根本不会所谓的"自己触发异常自己接管"
还有,要提一下,其实异常根本不是所谓的int 3,在ZwRaiseException下断,发现,它构造了假的异常信息。 返回调用ZwRaiseException的上一层,发现调用了ZwQueryInformationProcess 查询ProcessCookie ,判断是否查询成功,查询失败就
ZwRaiseException 构造一个假的异常地址 Code为 80000002的异常
于是我便HOOK ZwQueryInformationProcess 如果查询 ProcessCookie 返回EAX总等于0
好了windbg附加 游戏不出int3了 ,但是更加蛋疼的事情来了,触发了新的异常
来自 SSOPlatform.dll code c0000005 ,它也没有异常处理函数!!游戏挂了。。这个真有点束手无策了,因为游戏的VM段 不断有0xC0000005异常 自己接管,太混乱了
这时我便想知道 ,SSOPlatform.dll 触发的这个内存访问异常在没有调试器的时候会不会触发 既然它没有异常处理函数。。结果出来了,调试器不附加,这个地址 进程根本不会走
于是我便思考,为啥调试器附加的时候 会走这些地址触发异常呢? 我便GetThreadContext 233B线程的EIP,发现EIP在调试器没有的时候根本不动。。。
而EIP在哪里呢。。居然是 ZwWaitForSingleObject 那儿(add esp,4 应该是从内核等待信号出现后便会从这里开始走下去) 它等待的句柄是 一个EVENT。。它有信号了之后干嘛呢。。全是在vm里面,我跟了几分钟都没走出来 就不跟了。。。
总结如下:233B线程一直在等待一个事件的信号,当调试器附加的时候,事件便会变成有信号状态。然后触发它本不触发的异常。。异常也没有接管函数,导致了进程的挂掉。
我把进程所有的线程都挂起了,然后ollydbg附加游戏,只让233b 一根线程走,居然也等到到了信号。。。。。产生异常,,游戏挂掉
这时候问题来了 ,为何调试器一附加, 这个事件便会有信号? 是什么给了它信号。。

也许是一个未曾引起关注的反调试手段呢,假如它等待到了信号,触发到的不是异常,而是进行一些其他的猥琐手段,那么就更难受了。。

纯粹是为了研究 解惑。。。求高人帮助一下。。。中秋节快乐~
[培训]科锐逆向工程师培训第53期2025年7月8日开班!