題:
檢測硬件斷點
Trey
2017-10-14 07:31:55 UTC
view on stackexchange narkive permalink

由於軟件斷點硬件斷點不同,它確實會更改代碼,因此編寫一種對自身執行校驗和的程序作為反調試器技術相對容易。是否可以對硬件斷點執行類似的操作?

是的,您可以獲取上下文並檢查/修改/使調試寄存器dr7 dr6等無效
一 回答:
Megabeets
2017-10-14 23:42:16 UTC
view on stackexchange narkive permalink

這是一個非常好的問題,因為該主題不如用於檢測軟件斷點的反調試技術那麼受歡迎。既然您沒有提到該體系結構,我們就必須牢記,正如其名稱所暗示的那樣,硬件斷點取決於您所運行的硬件,因此,這種斷點的實現在每個體系結構之間是不同的。由於我們無法涵蓋所有架構,因此在此假設我正在談論Windows上的英特爾x86架構

簡而言之,答案是。基本上有兩種檢測硬件斷點的常用方法:

  1. 使用線程的上下文訪問調試寄存器
  2. 創建 SEH(結構化異常處理) ,然後引發異常並訪問調試寄存器
  3. ol>

    為了理解每種方法,我們應該首先了解什麼是硬件斷點以及(簡而言之)它是如何工作的。

    硬件斷點

    x86 體系結構中,調試器使用一組調試寄存器來應用硬件斷點。存在8個調試寄存器來控制調試過程,範圍從 DR0 DR7 。這些寄存器不能從 ring3 特權訪問,而只能從CPL0(當前特權級別,ring0)訪問。因此,在以任何其他特權級別執行時嘗試讀取或寫入調試寄存器都會導致一般性保護錯誤。調試寄存器允許調試器在訪問內存以進行讀寫時中斷程序的執行並將控制權轉移給它。

    x86調試寄存器

  • DR0-線性斷點地址0
  • DR1-線性斷點地址1
  • DR2-線性斷點地址2
  • DR3-線性斷點地址3

  • DR4-保留。未由Intel

  • DR5定義-保留。英特爾未定義

  • DR6-斷點狀態

  • DR7-斷點控制

DR0-DR3存儲斷點的線性地址。存儲的地址可以與物理地址相同,或者需要將其轉換為物理地址。 DR6 指示激活了哪個斷點。 DR7 通過以下訪問模式定義斷點激活模式: read write execute

檢測硬件斷點

方法一-ThreadContext Win API

下面的示例基於 this中的示例CodeProject上的文章。對示例進行註釋以描述每段代碼:

  bool IsHWBreakpointExists(){//此結構是函數的關鍵,並且是CONTEXT ctx; ZeroMemory(&ctx,sizeof(CONTEXT)); // CONTEXT結構是一個in / out參數,因此我們必須//設置標誌,以便Get / SetThreadContext知道要設置或獲取的內容。 ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; //獲取線程的句柄HANDLE hThread = GetCurrentThread(); //獲取寄存器if(GetThreadContext(hThread,&ctx)== 0)返回false;如果((ctx.Dr0)||(ctx.Dr1)||(ctx.Dr2)||(ctx.Dr3)){返回true; } else {返回false; }}  

方法2-SEH
操縱調試寄存器的SEH方法更為普遍,並且更容易在Assembly中實現,如圖所示在以下示例中,再次從CodeProject中獲取:

  ClrHwBpHandler proto .safeseh ClrHwBpHandlerClearHardwareBreakpoints proc假定fs:nothing push offset ClrHwBpHandler push fs:[0] mov dword ptr fs:[0],esp;設置SEH xor eax,eax div eax;導致異常彈出字ptr fs:[0];在這裡繼續執行,添加esp,4 retClearHardwareBreakpoints endpClrHwBpHandler proc xor eax,eax
mov ecx,[esp + 0ch];這是堆棧mov dword ptr [ecx + 04h],eax上的CONTEXT結構; Dr0 mov dword ptr [ecx + 08h],eax; Dr1 mov dword ptr [ecx + 0ch],eax; Dr2 mov dword ptr [ecx + 10h],eax; Dr3 mov dword ptr [ecx + 14h],eax; Dr6 mov dword ptr [ecx + 18h],eax; Dr7添加雙字ptr [ecx + 0b8h],2;我們在EIP上加2以跳過div eax retClrHwBpHandler endp  

參考文獻:



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...