IsDebuggerPresent()
时间:2011-04-22 来源:qg
#include "stdafx.h"调试起来果然b为1部调试b为0 汇编部分代码大部分都是参考脱壳技术一文里的简单的就是检测进程环境块(PEB)中的BeingDebugged。 原文:
int _tmain(int argc, _TCHAR* argv[])
{ int b =0; _asm
{
push eax
mov eax, dword ptr fs:[18h]
mov eax,[eax+30h]
movzx eax, byte ptr [eax+2]
mov dword ptr [b],eax
pop eax
}
printf("%d",b);
return 0;
}
2.1 PEB.BeingDebugged Flag : IsDebuggerPresent()
最基本的调试器检测技术就是检测进程环境块(PEB)1中的BeingDebugged标志。kernel32!IsDebuggerPresent() API检查这个标志以确定进程是否正在被用户模式的调试器调试。
下面显示了IsDebuggerPresent() API的实现代码。首先访问线程环境块(TEB)2得到PEB的地址,然后检查PEB偏移0x02位置的BeingDebugged标志。
mov eax,
large fs: 18h
mov eax, [eax+30h]
movzx eax,
byte ptr [eax+2]
retn
除了直接调用IsDebuggerPresent(),有些壳会手工检查PEB中的BeingDebugged标志以防逆向分析人员在这个API上设置断点或打补丁。
示例
下面是调用IsDebuggerPresent() API和使用PEB.BeingDebugged标志确定调试器是否存在的示例代码。
;call kernel32!IsDebuggerPresent()
call [IsDebuggerPresent]
test eax,eax
jnz .debugger_found
;check PEB.BeingDebugged directly
Mov eax,dword
[fs:0x30] ;EAX = TEB.ProcessEnvironmentBlock
movzx eax,byte
[eax+0x02] ;AL = PEB.BeingDebugged
test eax,eax
jnz .debugger_found
由于这些检查很明显,壳一般都会用后面章节将会讨论的垃圾代码或者反—反编译技术进行混淆。
对策
人工将PEB.BeingDebugged标志置0可轻易躲过这个检测。在数据窗口中Ctrl+G(前往表达式)输入fs:[30],可以在OllyDbg中查看PEB数据。
另外Ollyscript命令"dbh"可以补丁这个标志。
dbh
最后,Olly Advanced3 插件有置BeingDebugged标志为0的选项。