x86 反彙編/偵錯程式檢測
您可能會驚訝地發現,正在執行的程式實際上可以檢測到附加的使用者模式偵錯程式。此外,也存在檢測核心模式偵錯程式的方法,儘管使用的方法在很大程度上取決於試圖檢測的偵錯程式。
本主題與本書的敘述無關,大多數讀者可以將本節視為可選內容。
Win32 API 包含一個名為“IsDebuggerPresent”的函式,如果程式正在被除錯,它將返回布林值 true。以下程式碼片段將詳細說明此函式的一般用法
if(IsDebuggerPresent())
{
TerminateProcess(GetCurrentProcess(), 1);
}
當然,在反彙編程式碼中很容易發現 IsDebuggerPresent() 函式的用法,並且熟練的逆向工程人員只需修補程式碼以刪除此行。對於 OllyDbg,有很多可用的外掛可以隱藏偵錯程式,使其無法被此 API 和許多其他 API 檢測到。
程序環境塊儲存 IsDebuggerPresent 查詢以確定其返回值的值。為了避免懷疑,一些程式設計師直接從 PEB 訪問該值,而不是呼叫 API 函式。以下程式碼片段顯示瞭如何訪問該值
mov eax, [fs:0x30]
mov al, [eax+2]
test al, al
jne @DebuggerDetected
在 Windows 32 位和 64 位 Win <XP?, 7, 8.1 和 10 上。
有一個名為 _KUSER_SHARED_DATA 的結構,它在偏移量 0x2D4 處包含一個名為 'KdDebuggerEnabled' 的欄位,如果 KDM 處於活動狀態,則將其設定為 0x03,否則設定為 0x00。
該結構的基地址在不同的 Windows 版本中是靜態的(0x7FFE0000),即使 < XP 也是如此。
該欄位由核心不斷更新,最後兩位設定為 '11'。
以下彙編指令將在 32 位和 64 位應用程式中都能正常工作
cmp byte ptr ds:[7FFE02D4], 3
je @DebuggerDetected
這有很多優點。 已知的資料來源。
偵錯程式可以在程式碼中設定斷點,因此可以停止程式執行。程式可以透過監控系統時鐘來檢測到這一點。如果指令之間經過的時間過長,則可以確定程式被停止並正在進行分析(儘管並非總是如此)。如果程式花費的時間過長,則程式可以終止。
請注意,在搶佔式多執行緒系統(例如現代 Windows 或 Linux 系統)中,系統會從您的程式切換到執行其他程式。這稱為執行緒切換。如果系統有許多執行緒要執行,或者某些執行緒佔用處理器時間過長,您的程式可能會檢測到長時間延遲,並錯誤地確定程式正在被除錯。
SoftICE 是一種本地核心偵錯程式,因此,它不像使用者模式偵錯程式那樣容易檢測到。IsDebuggerPresent API 函式無法檢測到 SoftICE 的存在。
要檢測 SoftICE,可以使用多種技術
- 搜尋 SoftICE 安裝目錄。如果安裝了 SoftICE,則使用者可能是駭客或逆向工程人員。
- 檢測 int 1 的存在。SoftICE 使用中斷 1 進行除錯,因此,如果安裝了中斷 1,則 SoftICE 正在執行。
OllyDbg 是一款流行的 32 位使用者模式偵錯程式。不幸的是,最近的幾個版本(包括最新版本(v1.10))在處理 Win32 API 函式 OutputDebugString() 時存在漏洞。 [1] 試圖阻止其程式被 OllyDbg 除錯的程式設計師可以利用此漏洞使偵錯程式崩潰。作者從未釋出過修復程式,但有非官方版本和外掛可用於保護 OllyDbg 免受利用此漏洞的攻擊。