反调试总结
目錄
PEB:
函數檢測:
數據檢測:
PEB:
?利用PEB結構體信息可以判斷當前進程是否處于被調試狀態。其中與反調試密切相關的成員。
+0x002 BeingDebugged : UChar 調試標志
+0x00c Ldr : Ptr32 _PEB_LDR_DATA 進程加載模塊鏈表
+0x018 ProcessHeap : Ptr32 Void
+0x068 NtGlobalFlag : Uint4B
函數檢測:
sDebuggerPresent():?
函數檢測就是通過 Windows 自帶的公開或未公開的函數直接檢測程序是否處于調試狀態。最簡單的調試器檢測函數是 I
IsDebuggerPresent():API獲取PEB.BeingDebugged的值來判斷是否處于被調試狀態。進程處于被調試狀態時,PEB.BeingDebugged的值被設置為1,反之為0.
方法一:
我們如何通過此類反調試:首先查看其匯編形式
?將這里的jnz改為jz,我們就可以順利通過,再次反編譯結果如下 。
方法二:用OD將PEB.BeingDebugged 改為0.
PEB的結構指針存儲在TEB中,fs:[0x18]存儲著TEB結構指針,fs:[0x30]存儲著PEB結構指針。
Ctrl+G跳轉到fs:[0x30]處。PEB的首地址為0x314000,跳轉到fs:[0x30]+2處,也就是BeingDebugged,ctrl+E組合鍵修改為“00”.
?原理定位peb
pbDebuggerPresent
BOOL WINAPI CheckRemoteDebuggerPresent(_In_ HANDLE hProcess,_Inout_ PBOOL pbDebuggerPresent );如果?hProcess?句柄表示的進程處于調試上下文,則設置?pbDebuggerPresent?變量被設置為?TRUE,否則被設置為?FALSE。
方法:直接修改isDebuggerPresent的值或修改跳轉條件來繞過。?
NtQueryInformationProcess:
NTSTATUS WINAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle,_In_ PROCESSINFOCLASS ProcessInformationClass,_Out_ PVOID ProcessInformation,_In_ ULONG ProcessInformationLength,_Out_opt_ PULONG ReturnLength );第二個參數?ProcessInformationClass?給定了需要查詢的進程信息類型。當給定值為?0(ProcessBasicInformation)或?7(ProcessDebugPort)時,就能得到相關調試信息,返回信息會寫到第三個參數?ProcessInformation?指向的緩沖區中。
?ProcessDebugPor:
未公開的ntdll的NtQueryInformationProcess()函數接受一個信息類的參數用于查詢.?ProcessDebugPort(7)是其中的一個信息類.進程處于調試狀態時,系統就會為他分配一個調試端口。ProcessInformationClass參數設置為?ProcessDebugPor(0x7)時,調用NtQueryInformationProcess()函數就能獲取調試端口。若進程處于非調試狀態,則變量dwDebugPort的值設置為0,反之為1。
ProcessDebugObjectHandle:
Windows XP 引入了debug對象, 當一個調試會話啟動, 會同時創建一個debug對象以及與之關聯的句柄. 我們可以使用ProcessDebugObjectHandle (0x1e)類來查詢這個句柄的值
ProcessDebugFlags:
檢測Debug Flags(調試標志)的值也可以判斷進程是否處于被調試狀態。函數的第二個參數設置為ProcessDebugFlags(Ox1F)時,調用函數后通過第三個參數即可獲取調試標志的值:若為0,則進程處于被調試狀態;若為1,則進程處于非調試狀態。
ZwSetInformationThread:
利用ZwSetInformationThread()API,被調試者可將自身從調試器中分離出來。ZwSetInformationThread()函數是一個系統原生APl ( System Native API),顧名思義,它是用來為線程設置信息的。該函數擁有2個參數,第一個參數ThreadHandle用來接收當前線程的句柄,第二個參數ThreadInformationClass表示線程信息類型,若其值設置為ThreadHideFrom-Debugger(Ox11),調用該函數后,調試進程就會被分離出來。ZwSetInformationThread()API不會對正常運行的程序
數據檢測:
調試進程時,PEB.NtGlobalFlagd的值會被設置為0x70.
?我的方法是attach匯編
?方法二:用OD的CommandLine插件
在判斷前下斷點,打開CommandLine插件用dump fs:[30]+0x68dump 出NtGlobalFlag的內容
右鍵選擇Binary->Fill with 00's將值0x70替換為0x00即可.、
時間差檢測:
GetTickCount會返回啟動到現在的毫秒數, 循環里光是sleep(1)就進行了 100 次, 也就是 100 毫秒. 兩次得到的時間作差如果大于 1000 毫秒, 時差明顯大于所耗的時間, 也就間接檢測到了調試.
我們可以通過修改判斷的時間來跳過這個反調試。?
ETC:
我們應用反調試技術的目的在于防止程序遭受逆向分析。不必非得為此費力判斷自身進程是否處于被調試狀態。一個更簡單、更好的方法是,判斷當前系統是否為逆向分析專用系統(非常規系統),若是,則直接停止程序。這樣就出現了各種各樣的反調試技術,這些技術都能從系統中輕松獲取各種信息(進程、文件、窗口、注冊表、主機名、計算機名、用戶名、環境變量等)。這些反調試技術通常借助Win32API獲取系統信息來具體實現。
例如:
BOOL CheckDebug() {if (FindWindowA("OllyDbg", 0)){return 0;}return 1; } 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: 花指令记录
- 下一篇: D3ctf-D3MUG(u3d