首页 > 代码库 > 反调试技术- IsDebuggerPresent,原理 与 反反调试

反调试技术- IsDebuggerPresent,原理 与 反反调试

IsDebuggerPresent 这个函数可以用在程序中,检测当前程序是否正在被调试,从而执行退出等行为,达到反调试的作用。


1、IsDebuggerPresent 这个函数从汇编的角度看,就是一下三句代码。下面依次来分析这三句代码的原理。

75593789 K>  64:A1 18000000  mov     eax, dword ptr fs:[18]
7559378F     8B40 30         mov     eax, dword ptr [eax+30]
75593792     0FB640 02       movzx   eax, byte ptr [eax+2]
75593796     C3              retn


2、第一句:

mov     eax, dword ptr fs:[18]

将地址fs:[18]处的四个字节的数据放到eax中。


如图所示,再载入程序之后,可以看到 fs 寄存器的值为 0x7EFDD000。对应的我们到数据窗口查看。


可以看到 fs:[0] 对应的地址就存放的四个字节的数据是 0x0018FFC4 。它指向的SEH链的结尾, 

指令中fs:[18]处的代码给了eax,  定位到对应的位置。  其对应的数据是: 0x7EFDD000。

此处的数据和 fs 寄存器的值是一样的,即 记录了FS段寄存器在内存中的镜像地址”。

3、第二句:

mov     eax, dword ptr [eax+30]
这个时候是将偏移30字节的四个字节的数据放到eax中。可以发现对应的数据: 0x7EFDE000。

继续定位到对应的位置。

4、第三句:

movzx   eax, byte ptr [eax+2]
movzx 用于将较小值拷贝到较大值中。   即将0x7EFDE000 + 2 偏移 的一个字节的数据放到eax中,其他位置补充0.


发现对应的数据是1,于是程序就返回了。接着程序就根据返回值是否是1来判断是否正在调试中。从而躲过调试。

5、对应的反反调试方法也很简单,只要锁定到fs寄存器对应的位置修改这个特殊的数据就好了。


=====================================================================================================================

收集到的FS寄存器的相关资料,觉得整理的不错。

FS寄存器指向当前活动线程的TEB结构(线程结构)
偏移  说明
000  指向SEH链指针
004  线程堆栈顶部
008  线程堆栈底部
00C  SubSystemTib
010  FiberData
014  ArbitraryUserPointer
018  FS段寄存器在内存中的镜像地址
020  进程PID
024  线程ID
02C  指向线程局部存储指针
030  PEB结构地址(进程结构)
034  上个错误号


关于SEH链, 一些程序会透过 SetUnhandledExceptionFilter( ) 来设定 thread 的最高层异常处理 (代替 windows 提供的那一个错误信息),再制造异常,来达到扰乱调试的效果。

参考资料:

http://blog.sina.com.cn/s/blog_721d9f340100nkw5.html

http://download.csdn.net/detail/ls1160/7675159