在調試一些病毒程式的時候,可能會碰到一些反調試技術,也就是說,被調試的程式可以檢測到自己是否被調試器附加了,如果探知自己正在被調試,肯定是有人試圖反彙編啦之類的方法破解自己。為了了解如何破解反調試技術,首先我們來看看反調試技術。
一、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;
// 程序的PEB
// 控制堆操作函數的工作方式的标志位
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
四、查詢程序堆的一些标志位
這個方法是第三個方法的變種,隻要程序被調試,程序在堆上配置設定的記憶體,在配置設定的堆的頭資訊裡,ForceFlags這個标志位會被修改,是以可以通過判斷這個标志位的方式來反調試。因為程序可以有很多的堆,是以隻要檢查任意一個堆的頭資訊就可以了,是以這個方法貌似很強大,例子如下:
bool HeapFlagsApproach()
// 程序的堆,我們随便通路了一個堆,下面是預設的堆
mov eax, [eax + 18h]
// 檢查ForceFlag标志位,在沒有被調試的情況下應該是
mov eax, [eax + 10h]
未完待續
本文轉自 donjuan 部落格園部落格,原文連結: http://www.cnblogs.com/killmyday/archive/2011/05/31/2063891.html ,如需轉載請自行聯系原作者