次のオペコードを使用して短いジャンプを実行したいとします。
[〜#〜] eb [〜#〜][〜#〜] cb [〜#〜]またはJMP rel8
「ジャンプショート、RIP = RIP + 8ビットの変位符号を64ビットに拡張」
(ここで、CBはバイトです符号付き値[〜#〜] eip [〜#〜]レジスタの方向に関連する相対オフセットを表します)
多分常にオフセットはoffset + 2になるでしょう。この短いジャンプの実行時間(基準方向)のEIPは2バイト命令のベースですが、加数 常に発生
eb 30 = jmp 0x00000032(+30)
eb e2 = jmp 0xffffffe4(-30)
次に、fe + 2がまたは[〜#〜] eip [〜#〜]であるため、EIPは意図的に同じ方向にすることができます。
eb fe = jmp 0x00000000
overoffsetが負の数であるにもかかわらず、分岐していたのは驚くべきことです。しかしIntelには言及がない(多分3000ページのため)。
Intel®64 and IA-32 Architectures Software Developer’s Manual:Vol。 2A 3-42
ジャンプ範囲が–128〜+127に制限されているニアジャンプ現在から EIP値。
次に、3つの可能性について考えます。
rel8
は、次の命令のメモリアドレスを基準にしています。2つの実行可能ファイルを作成して逆アセンブルすることで簡単に確認できます。
@label:
jmp @label
nop
これは次のように逆アセンブルされます(ndisasmを使用すると、16ビット、32ビット、64ビットのコードで同じです)。
EBFE jmp short 0x0
90 nop
次に、別の実行可能ファイル:
jmp @label
@label:
nop
EB00 jmp short 0x2
90 nop
したがって、rel8
は常にjmp
の後の次の命令に関連してエンコードされます。ただし、逆アセンブラー(少なくともndisasm
およびudcli
)は、jmp
命令自体に対して相対的に表示します。これにより、混乱が生じる可能性があります。
ショートジャンプかどうかにかかわらず、常にdestination - (source + sizeof(instruction))
です。
つまり、_dst - end_of_jmp
_
あなたの場合(ショートジャンプ)、sizeof(instruction)
は2です。
この追加の背後にある理由は、CPUが命令フェッチステージを実行すると、命令ポインタが分岐の後に来る命令をすでに指しているという事実によるものです。 rel8またはrel32ブランチの変位は、そのEIP/RIP値を基準にしています。
ジャンプショートは、ジャンプ命令(長さ2バイト)のendに相対的なEIPを取り、符号拡張されてEIPに追加される1バイトのオペランドを取ります。