魔弑神 发表于 2021-9-27 10:38

Windows 基于调试器引擎缺陷引发的调试陷阱

本帖最后由 魔弑神 于 2021-9-27 10:40 编辑

众所周知在AMD64环境上,32的程序,我们可以使用CS段切换至x64环境,可以执行x64指令 0x33段选择器(天门) - 恶意软件技术 (malwaretech.com)

当然切换环境后,也是能在调试器里正常工作的,如果手动中断在环境里,调试器引擎可能需要支持x64指令,否则无法正常工作

那么我们正常运行,应该怎么样才能被检测呢, 这就要说个特殊的指令,int3int 3 (KiBreakpointTrap)

为什么说是特殊呢,因为配合切cs可以达到出其不意的效果

在正常环境下 切cs后使用int3,会得到一个STATUS_BREAKPOINT异常,如果没有注册异常接管,会崩溃。

如果在不支持(x64引擎)的调试器里运行,则什么都不会发生,但STATUS_BREAKPOINT异常依旧会有,内核会分发这个异常 但调试器好像不会接收到这个异常,程序正常工作

至于为什么会发生这个情况 一个是调试器汇编引擎的问题,(可能)以及int3的特性 ContextFrame.Rip -= 1; ,两个集中一起就会发生这种情况

当然像ICEBP UD2等指令不会发生这种情况

push 0x33
call Label1
Label1:
add dword , 0x05
retf
int3
call Label2
Label2:
mov dword , 0x00000023
add dword , 0x0D
retf

测试调试器: x32dbg,ollydbg,windbg。 都会引发这种情况

关于反制的方法目前有更换调试器引擎
内核处理要判断cs环境
(SegCs & 0xfff8)== 3 * 16 && WoW64Process != NULL
即可

更新内容:其实就是内核分发异常的时候没有判断wow64执行x64代码,从而没有对齐堆栈地址,引发后续的一系列问题
x64 Rsp =Rsp ;
wow64 Rsp =Rsp & 0xfffffff0UI64;


欢迎评论探究,我只是大概的分析

来自我博客的一篇文章

魔弑神 发表于 2021-9-28 20:58

本帖最后由 魔弑神 于 2021-9-28 21:11 编辑

无瑕黑心肠 发表于 2021-9-28 20:36
也就是说不管是在哪个环境,都会触发STATUS_BREAKPOINT异常,最终都会回到你注册的异常去接管处理,那这个 ...
调试环境下 int3不会触发你注册的异常,但是内核异常正常分发,只是你r3接收不到这个异常而已
正常环境 就正常int3异常

你可以看int3内核的异常分发 我文章最后说了是什么问题引发的这种情况

无瑕黑心肠 发表于 2021-9-28 20:36

也就是说不管是在哪个环境,都会触发STATUS_BREAKPOINT异常,最终都会回到你注册的异常去接管处理,那这个调试陷阱指的是哪个地方?
还是说在调试环境下,调试器会抛弃这个异常,从而导致你的异常接管没接收这个STATUS_BREAKPOINT异常?

penz 发表于 2021-9-27 12:58

注意了,谢谢

schip 发表于 2021-9-27 15:31

这个很细节,学习了

luckysky 发表于 2021-9-27 18:35

某游戏就是这样做内存crc校验

longling 发表于 2021-9-27 22:25

谢谢楼主分享      

cjc3528 发表于 2021-9-28 08:48

这块内容不是很懂,来学习下,谢谢分享

hszt 发表于 2021-9-28 10:09

有例子吗,自己写了一个,编译后正常都不能执行

魔弑神 发表于 2021-9-28 10:55

hszt 发表于 2021-9-28 10:09
有例子吗,自己写了一个,编译后正常都不能执行

正常本身就不能执行,因为会触发INT3异常,你必须注册异常处理,接管这个异常就行了

wangxiaohu104 发表于 2021-9-28 20:37

大佬,好厉害,学习了
页: [1] 2
查看完整版本: Windows 基于调试器引擎缺陷引发的调试陷阱