這個程式在之前就逆向過了,這裡主要學習它使用的3種反調試技巧。
技巧1: PEB中的BeingDebugged位,如果目前程序正在被調試,該位會被置1。

首先用OD調試,尋找到該程序的PEB位置:
檢視一下PEB的内容, 發現其中Beingdebugged位不是1,這是由于Ollydbg内部插件導緻的。
可以換用windbg來調試檢視BeingDebugged的位置, 看見了吧這裡就顯示為1了表示正在被調試。
技巧2: PEB中的ProcessHeap字段判斷
該字段内有名為Flags或者ForceFlags的标志。如果其不為0則代表是正在被調試。這裡判斷的是ForceFlags的。該字段在不同作業系統内,位于PEB.ProcessHeap的偏移不同。如下圖所示偏移了0x10這個程式當時使用的是XP,但是在Win7中該偏移就是0x44處。
還有Flags在XP内偏移是0xC處,Win7在0x40處。和ForceFlags該标志判斷的手段不是檢查是否為0。而是通過Flags 或上2來判斷。
技巧3: PEB中的NtGlobalFlag标志
該标志位于PEB偏移0x68處。如果該值為0x70就代表正在被調試,顯然這裡檢驗成功。
技巧4: TLS回調函數
一般程式是不會使用TLS功能的,也就是說其PE裡不會有TLS節。因為在進入主函數前會先執行TLS回調是以TLS經常用于反調試。其通過FindWindow函數尋找OLLYDBG視窗來達到反調試目的
但是現在Ollydbg非常強大,直接斷在了TLS調試函數前是以這種手段目前也失去了效果。
為了繼續調試下去,我們選擇忽視後進入了另一個函數
技巧5: OutputDebugString反調試
這個函數是用于調試狀态輸出的,如果說在非調試狀态下運作該函數會調用失敗, GetLastError()會傳回一個錯誤碼,如果說調試器正在運作,該函數不會有錯誤碼,可以先調用SetLastError()設定一個錯誤碼,然後調用OutputDebugString(), 如果調用後錯誤碼改變則代表正在調試(因為執行失敗,設定了失敗錯誤碼)
技巧6: QueryPerformanceCounter()或GetTickCount(), rdtsc指令檢測時間
如果是CPU執行代碼速度會很快,但如果是人為調試則會花去不少時間,這裡利用了這個特性,計算一段代碼執行所用時間,如果超出0x4B0則代表是調試狀态。這裡調用了GetTickCount()
這裡使用了rdtsc彙編指令來計算時間。該指令會傳回一個64位值到edx:eax。計算兩次間隔即可
(完)