在 MASM 中,我總是插入一個獨立的中斷指令
00007ff7`63141120 cc int 3
但是,用 MSVC DebugBreak函式替換該指令會生成
KERNELBASE!DebugBreak:
00007ff8`6b159b90 6690 xchg ax,ax
00007ff8`6b159b92 cc int 3
00007ff8`6b159b93 c3 ret
我很驚訝在 break 指令之前看到 xchg 指令
xchg ax,ax
正如另一篇 SO 文章所述:
實際上,xchg ax,ax 正是MS 拆解“66 90”的方式。66 是運算元大小覆寫,因此它應該對 ax 而不是 eax 進行操作。但是,CPU 仍將其作為 nop 執行。這里使用 66 前綴使指令大小為兩個位元組,通常用于對齊目的。
與大多數編譯器一樣,MSVC 將函式與 16 位元組邊界對齊。
問題xchg 指令的目的是什么?
uj5u.com熱心網友回復:
MSVC 在函式開頭的任何單位元組指令之前生成 2 位元組 nop(ret空函式除外)。我試過__halt, _enable,_disable內在函式并看到了相同的效果。
顯然是為了打補丁。/hotpatchoption 為 x86 提供了相同的更改,并且/hotpatch在 x64 上無法識別 option。根據/hotpatch檔案,這是預期的行為(強調我的):
因為指令在 ARM 架構上總是兩個位元組或更大,并且因為x64 編譯總是被視為好像已經指定了 /hotpatch,所以當你為這些目標編譯時你不必指定 /hotpatch;
所以熱補丁支持對于x64是無條件的,其結果在DebugBreak實作中可見。
見這里:https : //godbolt.org/z/1G737cErf
請參閱有關為什么需要進行熱修補的帖子:為什么 Windows 功能都以毫無意義的 MOV EDI、EDI 指令開頭?. 看起來目前的hotpatching足夠聰明,可以使用任何兩個位元組或更多的指令,不僅如此MOV EDI, EDI,它仍然不能使用單位元組指令,因為可能在指令指標指向第二條指令的確切時刻寫入雙位元組向后跳轉.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/339446.html
