软件中会使用各类手段防止Craker调试程序,为此咱们必须了解常见的反调试技术的原理及规避方法。数组
调试器:OllyDbgide
环境:win7 64位真机函数
首先咱们打开这个程序,是能够正常打开的post
使用OD载入目标程序,点击F9运行,左上角一开始是显示“暂停”,F9之后变为显示:已终止。也没弹窗,直接终止了。换言之用户打开就能正常运行,用调试器打开就会自动退出。为何呢?ui
由于有IsDebuggerPresent函数在检测调试器,若是检测到正在调试就会退出。如何证明呢 你能够直接bp IsDebuggerPresent,发现确实能断下;也能够打开函数列表,或者按下ctrl+n查看,发现的确有这个函数。插件
肯定用户是否在用调试器,是的话返回非零值。返回0就表示没有被调试。debug
在段首下断,断下,Ctrl+f9执行到段尾,大部分函数的返回值基本上都在eax里,此时EAX非零指针
看到,第二行执行了IsDebuggerPresent,以后第5行跳过了后面的获取文本框里的消息GetDlgItem,换言之是跳过了程序的正常的执行顺序。调试
执行关键跳后即将执行postquitmessage提交/发送退出信息,看来程序立刻就要退出了。以下图blog
而后执行会执行ExitProcess,程序退出。那么这个IsDebuggerPresent究竟执行了什么呢
Mov eax,dword ptr fs:[18]
Mov eax,dword ptr ds:[eax+30]
Movz eax byte ptr ds:[eax+2]
Retn
这四行代码是关键, 把这四行代码,复制到EP(程序入口点),运行后eax也是1 是一个非零数。为了避免让人找到这个函数,不少人直接把这三行代码写入程序了,没法用bp IsDebuggerPresent来下断,很是的隐蔽不易被发现。那么 这四行代码 是什么意思呢?
在S标志位的右边,有一个寄存器FS,在命令窗口输入? fs[18],OD会在命令窗口旁边显示出FS【18】里的值是 7ffdf000 。 数据窗口跟随7ffdf000,他指向一个结构体,这个结构体里包含了不少程序运行的关键信息
那么fs[18]是什么?就是以7ffdf000开始,指针向高位移动加18个字节,数字相似于数组里的下表索引。而后以他为新的地址,再向高地址读取4字节长度,内容是7ffdf000。因此FS[18]就是FS也就是FS[0]自己
所以执行第一行后eax里的值是7ffdf000
第二行:7ffdf000+0x30=7ffdf030,把里面的内容赋值给eax,这里
Mov eax,dword ptr ds:[eax+30] 这句话等价于mov eax, dword ptr ds: fs[30]
那么 fs[30] 里面的内容是什么呢?7ffd4002,这个数每次载入都会变。可是0x30这个偏移量不会变
第三行
Movz eax byte ptr ds:[eax+2],2这个偏移量也不会变
以7ffd4002为地址,取一字节内容,内容是01。 这个内容就是isdebuggerpresent的返回值。
其实,这个返回值,本质上是一个,以FS寄存器里的内容为基址,一级偏移加0x30,二级偏移加0x2的二级指针。
那么 只要把这个返回值从非零值改成零就能够绕过反调试了。
下面介绍如何经过插件自动过检测。
1把插件dll放到plugin文件夹下
2打开OD,在OD主界面点击插件-HidenDebugger-option,勾选isdebuggerpresent。
3从新载入,EBX里的值就是FS:【30】,此时为7ffd9000.跟一下里面的 7ffdE000 ,来到7ffdE000+2处, 在数据窗口中观察到值为0,可见插件生效了,检测就过了。再次打开OD,就能正常调试了。