1625-5 王子昂 总结《2018年3月6日》 【连续第521天总结】
A. 反调试技术(1)
B.
BeingDebugged
Win32API为程序提供了IsDebuggerPresent来判断自己是否处于调试状态,懒惰的程序员使用这个API来自欺欺人
实现源码为:
IsDebuggerPresent(VOID)
{
return NtCurrentPeb()->BeingDebugged;
}
这个函数读取了当前进程PEB中的BeingDebugged标志
PEB(Process Environment Block,进程环境块)是每个进程都拥有的一个结构,其中包含了大量的进程相关标志
它的地址存放在TEB(Thread Environment Block, 线程环境块)之中,而TEB的地址会被该线程的FS段寄存器存储
换句话说,该API只是通过内存中的一个标志位来判断进程是否被调试……调试器改内存是手到擒来的事情,甚至OD还有插件可以免去手工操作的繁琐。
因此使得这个API沦为鸡肋。。。
真的是这样吗?
才不会这么简单~
在PEB中的BeingDebugged被设为True后,还会有一些其他的变化产生。
- 加载时会将PEB中的NtGlobalFlag中的一个位改变,使其值为0x70,而正常状态下不是
- 在WRK中有一个宏也会随着NtGlobalFlag的改变而在RtlCreateHeap中用RtlDebugCreateHeap创建调试堆。这个调试堆中含有大量的标志(例如0xBAAD0F0D和0xFEEEFEEE等),而正常情况下这个地址中却没有有意义的数据。
单纯的修改BeingDebugged标志位而忘记清除其他痕迹时,经常会被有所防备的壳、反调等程序捕捉到,例如Themida

本文探讨了Windows程序如何使用IsDebuggerPresent API检测调试状态,但指出此API容易被调试器规避。文章深入介绍了PEB和TEB结构,以及BeingDebugged标志、NtGlobalFlag变化和调试堆的创建。作者提出通过在NtGlobalFlag改变前设BeingDebugged为False,以绕过调试检测,并描述了一种在系统断点处巧妙切换BeingDebugged状态的策略。

被折叠的 条评论
为什么被折叠?



