常見反除錯手段及其規避方法(一)-IsDebuggerPresent
軟體中會使用各種手段防止Craker除錯程式,為此我們必須瞭解常見的反除錯技術的原理及規避方法。
偵錯程式:OllyDbg
環境:win7 64位真機
首先我們開啟這個程式,是可以正常開啟的
使用OD載入目標程式,點選F9執行,左上角一開始是顯示“暫停”,F9以後變為顯示:已終止。也沒彈窗,直接終止了。換言之使用者開啟就能正常執行,用偵錯程式開啟就會自動退出。為什麼呢?
因為有IsDebuggerPresent函式在檢測偵錯程式,如果檢測到正在除錯就會退出。如何證實呢 你可以直接bp IsDebuggerPresent,發現確實能斷下;也可以開啟函式列表,或者按下ctrl+n檢視,發現的確有這個函式。
確定使用者是否在用偵錯程式,是的話返回非零值。返回0就表示沒有被除錯。
在段首下斷,斷下,Ctrl+f9執行到段尾,大部分函式的返回值基本上都在eax裡,此時EAX非零
看到,第二行執行了IsDebuggerPresent,之後第5行跳過了後面的獲取文字框裡的訊息GetDlgItem,換言之是跳過了程式的正常的執行順序。
執行關鍵跳後即將執行postquitmessage提交/傳送退出資訊,看來程式馬上就要退出了。如下圖
然後執行會執行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,就