0x01 PEB 简介
PEB(Process Environment Block,进程环境块)是存放进程信息的结构体,尺寸非常大,其大部分内容都已被文档化。其中与我们的反调试有较大关系的成员有:
+0x002 BeingDebugged : UChar
+0x00c Ldr : Ptr32 _PEB_LDR_DATA
+0x018 ProcessHeap : Ptr32 Void
+0x068 NtGlobalFlag : Uint4B
0x02 成员介绍
一、BeingDebugged
进程处于调试状态时,PEB.BeingDebugged 成员的值设为 1。在非调试状态下为 0,在 Kernelbase.dll 中存在 API IsDebuggerPresent(),可以检测该成员值。其汇编形式为
mov eax,dword ptr fs:[0x30] ;将PEB地址放入eax中
movzx eax,byte ptr ds:[eax+0x2] ;BeingDebugged 地址偏移为0x2
破解方法:进入相应的内存地址处,直接修改值。OD 内也有插件 Strong OD 可以直接帮忙修改。
二、Ldr
调试进程时,其堆内存区域中会出现一些特殊标识,表明它正处于被调试状态。最醒目的是:未使用的堆内存区域全部填充着0xEEFEEEFE,利用这一特征可判断是否处于被调试状态。
PEB.Ldr 是指向 _PEB_LDR_DATA 结构体指针, _PEB_LDR_DATA 恰好是在堆内存中创建的。检测 _PEB_LDR_DATA 是否是0xEEFEEEFE 即可判断是否处于被调试,汇编的调用形式和上面的相差不多。
破解方法:将其中的 0xEEFEEEFE 覆写为 null 即可。
三、ProcessHeap
PEB.ProcessHeap 指向 HEAP 结构体。HEAP 结构体中与反调试有关的有两个:Flags、ForceFlags。这两个字段的值会受调试器的影响(非调试是值分别为2、0),同时其位置也会受 windows 版本影响而有不同。
其值的获取既可以从 PEB 结构中获取,也可以从 GetprocessHeap()API 中获取
破解方法:将 HEAP.Flags 重新修改为2 ,HEAP.ForceFlags 修改为0
四、NtGlobalFlag
调试进程时,PEB.NtGlobalFlag 会被置为 0x70,该字段在32 位机器上,位于 0x68 ,在64位机器上,位于 0xBC。
NtGlobalFlag 0x70是下列Flags进行bit OR(位或)运算的结果
FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)
破解方法:手动修改标志位的值;在 Ollydbg 中使用 strong od 插件;在 Windbg 禁用调试堆的方式启动程序 (windbg -hd program.exe)