由於靜態反逆向技術有很多種類型,今天將會演示幾項常見的反逆向技術。
以下都在 Win10 上執行。
本文章使用原始碼與成果位於
https://github.com/Dinlon5566/IT_Reverse_Engineering/tree/main/Dx28
首先,PEB
裡面會記載著程序的各種狀態,裡面有很多參數助於我們判斷是否在 Debugger 中。
https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb
其中就包含著是否為 Debugger 狀態的 BeingDebugged,而在程式中可以透過 IsDebuggerPresent()
輕鬆地得知程式是否在 Debugger 狀態。
這份程式利用 IsDebuggerPresent()
來判斷是否為 Debugger 模式。
#include <iostream>
#include <Windows.h>
int main()
{
if (IsDebuggerPresent()) {
printf("Is Debuger mode!");
return 0;
}
MessageBoxA(0,"Hello world","Dinlon",NULL);
}
那為了反制這個技術,來探討 IsDebuggerPresent()
是甚麼運行的 :
0x401040
這個位置 Call 了 IsDebuggerPresent()
0x401048
若判斷為正常執行則跳到 0x40105A 繼續運行
IsDebuggerPresent()
函數位置。可以看到這個函式十分簡單,就是引用了 FS
暫存器 +30 的位置得到 PEB
位置,然後再取用 PEB +2
就有 BeingDebugged
的值了。不過說著簡單,來看實際的位置吧。
FS
的位置。+30 的位置是 0x3C5030
,取一個 DWORD
就是 0x003C2000
。PEB
的位置。
PEB
看到了 PEB+2
的數值是 1 ,代表是 Debugger 模式。把它改成 0x00
,然後運行。
成功解除。
透過觀察 PEB
的 0x68
位置也可以查出是否在 debugger 中,若是符合已條件 :
FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)
值將會是 0x70
,此時就查的出程式是運行在反編譯器中的 。
#include <iostream>
#include <Windows.h>
DWORD isDebuger()
{
__asm
{
mov eax, fs: [0x30]
movzx eax, dword ptr[eax + 0x68]
}
}
int main()
{
if (isDebuger()) {
printf("Is Debuger mode!");
return 0;
}
MessageBoxA(0, "Hello world", "Dinlon", NULL);
}
反制方法 : 跟上面一樣,把 PEB + 0x68
變成 0 就好了。
下面的就不是透過 PEB 來進行檢查了。
透過這個函數可以知道程序是否在被遠程 Debugger 中。
#include <iostream>
#include <Windows.h>
BOOL isCRDP() {
BOOL dbg;
if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &dbg) && dbg) {
return 1;
}
return 0;
}
int main()
{
if (isCRDP()) {
printf("Is Debuger mode!");
return 0;
}
MessageBoxA(0, "Hello world", "Dinlon", NULL);
}
反制方法 : 由於改變他引用的數值過於麻煩,我會選擇 Hook 這個 API 直接把他忽略。