在 x86 程式集的例程中,如果代碼包含指向兩個有效地址之間的有效地址的跳轉,會發生什么情況?這是一個人工示例:
0x0001: mov ...
0x0005: add ...
0x0009: jmp 0x0003
此外,我如何在本地機器或在線上進行類似的實驗?我檢查了在線 x86 編輯器,如https://defuse.ca/online-x86-assembler.htm#disassembly,但它不允許我放置像“0x0001”這樣的指令地址。
uj5u.com熱心網友回復:
沒有“有效”或“無效”地址之類的東西。每個地址都可以跳轉到,如果對應的頁面被映射,則執行。
那么當你在指令之間跳轉時會發生什么?好吧,處理器不知道您打算從哪里開始和結束指令。它只是執行它看到的位元組。此代碼將與您期望的不同,因為 CPU 嘗試將其他指令的中間部分決議為操作碼。
您的具體示例不足以讓我說出指令的結果。也許您可以提供一個完整的示例(包括機器代碼),以便我給出更好的解釋。
uj5u.com熱心網友回復:
CPU 將在目標地址處開始解碼指令。
您在反匯編中看到的指令流(當使用類似 的工具時objdump)只是對程式可執行位元組的一種解釋,假設有一個給定的起點。
碰巧“跳到指令的中間”是一種混淆技術,有時被惡意軟體用來隱藏線性掃描反匯編程式(如objdump)的程式語意。更復雜的反匯編程式將嘗試跟隨這些“未對齊”的跳轉,但這可能是不可能的,這取決于靜態/動態確定什么可以/不能確定。
Linn 和 Debray的論文“對可執行代碼進行混淆以提高對靜態反匯編的抵抗力”更詳細地討論了這一點。
請參閱第 3.2 節“垃圾插入”。您描述的場景是他們所說的“部分或完全重疊指令”,即對位元組流的不同解釋可以為重疊地址范圍提供不同的匯編指令。
uj5u.com熱心網友回復:
我最近在 codegolf 的“在 x86/x64 機器代碼中打高爾夫球的技巧”中添加了一個關于跳過指令的技巧。您會發現這些是有意應用到先前指令的一部分。而且不僅僅是為了混淆。這是該答案的全文:
跳過指令
跳過指令是與一個或多個后續操作碼組合的操作碼片段。后續操作碼可用于與前置跳過指令不同的入口點。使用跳過指令代替無條件短跳轉可以節省代碼空間,速度更快,并設定諸如NC(無進位)之類的附帶狀態。
我的示例都是針對 16 位實/虛擬 86 模式的,但是這些技術中有很多可以類似地用于 16 位保護模式,或者 32 位或 64 位模式。
參考我的 ACEGALS 指南:
11:跳過指令
常量 __TEST_IMM8、__TEST_IMM16 和 __TEST_OFS16_IMM8 被定義為這些指令的相應位元組串。它們可用于跳過適合以下 1、2 或 3 個位元組的后續指令。但是,請注意,它們修改了標志暫存器,包括始終設定 NC。16 位偏移量加 16 位立即測驗指令不包括在這些用途中,因為它可能訪問段中偏移量 0FFFFh 處的字。此外,所提供的 __TEST_OFS16_IMM8 應僅用于 86M,以避免訪問超出段限制的資料。在使用這些常量之一的 db 指令之后,應在括號中列出跳過的指令。
86 模式在 lmacros1.mac 323cc150061e (2021-08-29 21:45:54 0200) 中定義:
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/338679.html
