アセンブリ関数を読み取るためにgdbデバッガーを使用しています。
アセンブリでは、次の指示があります。mov 0xc(%rsp),%eax
jmpq *0x402390(,%rax,8)
メモリ位置_*0x402390
_には、値_0x8e
_があります。レジスタraxには、この特定の関数の2番目の整数入力があります(変数yを使用できます)。
分析から、この関数は3つの変数_(x, y, z)
_を取り、それらはそれぞれメモリロケーション_(rsp)
_、_(rsp + 8)
_、_(rsp + 12)
_にあることがわかりました。
jmpq *0x402390(,%rax,8)
で何が行われているのか知りたいと思います。 _(0x8e + rax*8)
_の命令にジャンプしていますか?もしそうなら、どのようにしてその命令が何と呼ばれるかを知ることができますか?
これは、関数phase_3のアセンブラコードの完全なダンプです。
GAS-manual から:
次の形式のIntel構文間接メモリ参照
_section:[base + index*scale + disp]
_aT&T構文に変換されます
_section:disp(base, index, scale)
_ここで、baseおよびindexはオプションの32ビットのベースおよびインデックスレジスタ、dispはオプションのディスプレイスメント、およびスケールで、1、2、4、および8の値を取り、indexを乗算してオペランドのアドレスを計算します。
( https://sourceware.org/binutils/docs/as/i386_002dMemory.html#i386_002dMemory )
したがって、jmpq *0x402390(,%rax,8)
をINTEL構文に変換できます:jmp [RAX * 8 + 0x402390]。これは「間接的な」ジャンプです。アドレス[RAX * 8 + 0x402390]は、jmp
のターゲットになるアドレスです。次のステップは、0x402390 + xにあるアドレスの数と、そのアドレスが使用されるかどうかを決定することです。
爆弾ラボでしょ?
この操作jmpq *0x402390(,%rax,8)
は、次の場所に保存されている絶対アドレスに直接ジャンプするためのものです。
_8 * %rax + 0x402390
_
Gdbで_x/16gx 0x402390
_を実行する場合(_0x402390
_で始まる16進数の16の「巨大な単語」を検査)、アドレステーブルは次のようになります:(私は別のラボを持っているので、あなたのもの)
_ 0x402880: 0x0000000000400fee 0x000000000040102b
0x402890: 0x0000000000400ff5 0x0000000000400ffc
0x4028a0: 0x0000000000401003 0x000000000040100a
0x4028b0: 0x0000000000401011 0x0000000000401018
_
これらのすべてのアドレスはすべて、jmpq *0x402390(,%rax,8)
の直後の単一のmov
操作を指します。
エントリごとに8バイトのコードテーブルにジャンプします。これは、switch caseステートメントの最適化のようなものです。 jmpqの直後に一連の7バイトシーケンスがあり、jmpqの分岐先のコード(402390から始まる)が画像に表示されていないため、少し混乱します。