軟件中會使用各類手段防止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,就能正常調試了。