反调试:IsDebuggerPresent
前言:一个反调试IsDebuggerPresent的CreackMe
IsDebuggerPresent函数的了解:
IsDebuggerPresent
作用
确定调用进程是否由用户模式的调试器调试。
语法
BOOL WINAPI IsDebuggerPresent(void);
参数
该函数没有参数
返回值
如果当前进程运行在调试器的上下文,返回值为非零值。
如果当前进程没有运行在调试器的上下文,返回值是零。
IsDebuggerPresent函数检测调试过程:
1、直接加载入OD,观察是否具有IsDebuggerPresent的windows api函数,来验证反调试是不是使用的是IsDebuggerPresent,发现确实存在
2、利用IsDebuggerPresent进行下断点,然后运行程序F9,然后单步走
关键的第一个api函数,PostQuitMessage
,其作用是发送结束消息
然后我们继续单步走,最后来到第二个关键的api 结束进程的函数ExitProcess
IsDebuggerPresent函数防调试的绕过
1、载入OD,进行IsDebuggerPresent api函数的断点,然后用户返回到执行代码,同时也可以发现返回值为00000001,不为0,所以IsDebuggerPresent判断为调试中,就会结束进程
2、分析汇编代码可知如下,那么让下面的je跳转进行跳转就可以了,那么直接修改jmp 进行无条件跳转,再F9
3、成功绕过
IsDebuggerPresent反调试的原理:
1、重新载入OD进行分析,运行程序,断下点来到如下
7C81F424 > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18] ; 将7FFDD018地址中的值7FFDD00赋值给eax
7C81F42A 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30] ; 将7FFDD30的地址的机器码7FFDE000赋值给eax
7C81F42D 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2] ; 将7FFDE02的第一字节机器码赋值给eax,这里的第一字节的机器码也就是01
7C81F431 C3 RETN ; 那么返回值中的eax值也就是01,判断为被调试,结束程序
2、那么也就是将eax中的值改为00000000,所以就可以绕过了