Beingdebugged
Win32API为程序提供了IsDebuggerPresent来判断自己是否处于调试状态,懒惰的程序员使用这个API来自欺欺人
这个函数读取当前进程peb中的BeingDebugged标志
+0x002 beingDebugged
+0X068 NtGlobalFlag
而peb储存在TEB(Thread Environment Block)
windows在调入进程,创建线程时,使得fs:0指向当前线程的TEB
TEB的结构
+0x030 processEnvironmentBlock
这里给出一个简化版的isdebuggerpresent
move eax , fs:[0x30]
movzx eax ,byte ptr [eax+2]
当然也可以用NtQueryInformationProcess获得PEB(不过这是后话了。。)
NtGlobalFlag
不要以为把这函数nop掉就没事了。。。好戏才刚刚开始
看到BeingDebugged被设为TRUE,NtGlobalFlag会有所变化
调试时NtGlobalFlag被设为0x70,平时则是0x00
Heap Magic
在WRK中有一个宏也会随着NtGlobalFlag的改变而在RtlCreateHeap中用RtlDebugCreateHeap创建调试堆。这个调试堆中含有大量的标志(例如0xBAAD0F0D和0xFEEEFEEE等),而正常情况下这个地址中却没有有意义的数据。(如果题目出得贱的化,可能会检测这里)
顺便提一句Themida壳会检测这里,防止被调试
从源头解决BeingDebugged
一切祸根来源与系统设置了一个BeingDebugged,只要改写这个值,就可以当作无事发生
但是如果把BeingDebugged设为False,之后不会在系统断点处触发中断了。因此还需要有技巧的设置:创建进程并调用WaitForDebugEvent后,在第一次LOAD_DLL_DEBUG_EVENT发生时,BeingDebugged=False,在第二次LOAD_DLL_DEBUG_EVENT时将BeingDebugged=True,之后会
停在系统断点
DebugEventCode | Count | PEB.BeingDebugged |
---|---|---|
LOAD_DLL_DEBUG_EVENT | 0 | FALSE |
LOAD_DLL_DEBUG_EVENT | 1 | TRUE |
LOAD_DLLDEBUG_EVENT | 0 | FALSE |