簡體   English   中英

即使修補了指令,當使用INT 3(0xCC)軟件斷點時,調試器如何保證正確性?

[英]How do debuggers guarantee correctness when using INT 3 (0xCC) software breakpoint even though an instruction was patched?

我讀過INT 3(0xCC)用於軟件斷點。

它由(例如)調試器通過覆蓋存儲器中的實際程序代碼來設置。

我還讀到INT 3是一個“陷阱”而非“故障”異常,這意味着堆棧上的地址是INT3指令后面的指令地址。

如果未重新執行修補的指令,調試器如何保證正確性?

當您想在斷點觸發后繼續執行時,您有兩種可能:斷點只應該觸發一次,或者它應該是持久性的。 如果它只應該觸發一次,你用斷點指令恢復你覆蓋的原始值,手動調整地址到該指令的地址(記住,不管那里有什么指令, 執行的是你的單字節斷點,所以調整總是微不足道的。 然后你繼續執行。

如果它應該是一個持久性斷點,那么就會增加一個皺紋:在繼續執行之前,在堆棧中的標志中設置單步(也就是陷阱)位。 這意味着只有設置了斷點的一條指令才會執行,那么你將再次獲得一個斷點中斷。 您可以通過將剛剛修補的int 3字節恢復到原始指令的第一個字節來響應,然后(再次)繼續執行。

這已經有一段時間了,因為我已經深入研究了這種東西,但假設你是正確的,以下地址被推入堆棧,調試器可以彈出返回地址並使用它來找出斷點的位置(返回地址減1,因為INT 3指令長一個字節)[編輯]。

換句話說,調試器不一定需要返回堆棧上的地址。 它可以恢復原始指令,然后在原始位置執行它。 如果斷點要保持設置,它可以使用標志中的“陷阱位”僅執行一條指令 - 原始的一條指令 - 在生成另一個陷阱之前(我認為是INT 3); 然后可以在繼續正確執行之前重新建立INT 3指令。

但是,大多數情況下,調試器在一個他們不直接處理陷阱的系統下運行; 例如,他們可能會發出信號告訴他們陷阱發生的位置。 很可能他們仍然需要從陷阱地址中找出“真實”地址(即INT 3指令的地址),因為操作系統無法做到這一點。

如果涉及多個線程,事情也變得復雜; 在這種情況下,恢復原來的“就地”指令可能會導致斷點被另一個線程擊中。 一種解決方案可能是在恢復指令之前停止所有其他線程(並在之后再次啟動它們)。

通常的解決方案是讓調試器修改堆棧上的地址(並恢復被陷阱覆蓋的指令),因此它會執行修補的指令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM