反调试技术
在調試一些病毒程序的時候,可能會碰到一些反調試技術,也就是說,被調試的程序可以檢測到自己是否被調試器附加了,如果探知自己正在被調試,肯定是有人試圖反匯編啦之類的方法破解自己。為了了解如何破解反調試技術,首先我們來看看反調試技術。
一、Windows API方法
Win32提供了兩個API, IsDebuggerPresent和CheckRemoteDebuggerPresent可以用來檢測當前進程是否正在被調試,以IsDebuggerPresent函數為例,例子如下:
?
BOOL ret = IsDebuggerPresent(); printf("ret = %d\n", ret);?
破解方法很簡單,就是在系統里將這兩個函數hook掉,讓這兩個函數一直返回false就可以了,網上有很多做hook API工作的工具,也有很多工具源代碼是開放的,所以這里就不細談了。?
二、查詢進程PEB的BeingDebugged標志位 當進程被調試器所附加的時候,操作系統會自動設置這個標志位,因此在程序里定期查詢這個標志位就可以了,例子如下:?
bool PebIsDebuggedApproach() { char result = 0; __asm { ?? ? ?// 進程的PEB地址放在fs這個寄存器位置上 mov eax, fs:[30h] ??// 查詢BeingDebugged標志位 mov al, BYTE PTR [eax + 2]? mov result, al } return result != 0; }?
三、查詢進程PEB的NtGlobal標志位? 跟第二個方法一樣,當進程被調試的時候,操作系統除了修改BeingDebugged這個標志位以外,還會修改其他幾個地方,其中NtDll中一些控制堆(Heap)操作的函數的標志位就會被修改,因此也可以查詢這個標志位,例子如下:?
bool PebNtGlobalFlagsApproach() { int result = 0; __asm { ?? ? ?// 進程的PEB mov eax, fs:[30h] ??// 控制堆操作函數的工作方式的標志位 mov eax, [eax + 68h] ??// 操作系統會加上這些標志位FLG_HEAP_ENABLE_TAIL_CHECK,? ??// FLG_HEAP_ENABLE_FREE_CHECK and FLG_HEAP_VALIDATE_PARAMETERS, ??// 它們的并集就是x70 ??// ??// 下面的代碼相當于C/C++的 ??// ? ? eax = eax & 0x70 and eax, 0x70 mov result, eax } return result != 0; }?
四、查詢進程堆的一些標志位 這個方法是第三個方法的變種,只要進程被調試,進程在堆上分配的內存,在分配的堆的頭信息里,ForceFlags這個標志位會被修改,因此可以通過判斷這個標志位的方式來反調試。因為進程可以有很多的堆,因此只要檢查任意一個堆的頭信息就可以了,所以這個方法貌似很強大,例子如下:?
bool HeapFlagsApproach() { int result = 0; __asm { ?? ? ?// 進程的PEB mov eax, fs:[30h] ?? ? ?// 進程的堆,我們隨便訪問了一個堆,下面是默認的堆 mov eax, [eax + 18h] ??// 檢查ForceFlag標志位,在沒有被調試的情況下應該是 mov eax, [eax + 10h] mov result, eax } return result != 0; }?
參考資料:http://www.symantec.com/connect/articles/windows-anti-debug-reference?
未完待續總結
- 上一篇: JMP指令转换公式推导
- 下一篇: 反调试技术二