IsDebuggerPresent()

最近因弄个加壳软件,但是还是脱壳界菜鸟的我,只有狂在网上找方式,看了脱壳的艺术一文,想验证下上面的方法。
简单写了个C++的asm
 
   
#include " stdafx.h "


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 ;
}
调试起来果然b为1部调试b为0
汇编部分代码大部分都是参考脱壳技术一文里的简单的就是检测进程环境块(PEB)中的 BeingDebugged。
 
原文:

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的选项。

你可能感兴趣的:(debugger)