6

そのため、objdump ユーティリティを使用して、アセンブリから制御フロー グラフを作成しようとしていますが、問題が発生しています。基本的に、分岐が発生し、ターゲット アドレスが相対である場合はいつでも、次の基本ブロックの開始位置を知る方法がわかりません。よくわからないので、例を追加します。私のプログラムが objdump 出力を調べていて、最初の基本ブロックの開始アドレスを記録したとします。次に、相対アドレッシングを使用してジャンプ先の適切なアドレスを指すジャンプ コマンドをヒットします。最初の基本ブロックの終了がすぐそこにあることはわかっていますが、次の基本ブロックの開始の正しいアドレスを取得するにはどうすればよいですか? 誰でも提供できるガイダンスは大歓迎です。私はせいぜいx86の初心者であり、この1週間、これに頭を悩ませてきました。

4

1 に答える 1

4

質問を理解していると仮定すると、これで始められるかもしれません。相対ジャンプは PC ベースです。

d: eb 04 jmp 13 

0xEB は、8 ビットの即値に基づく相対ジャンプのオペコードです。命令のアドレスは objdump 出力にあり、この場合は d または 0xD です。これは 2 バイトの命令です (x86 は可変長です)。出力で宛先アドレスが何であるかがわかります。この場合は jmp 13 です。したがって、objdump 出力で 13 とコロンで始まる行を探すことが、次のコードのチャンクの始まりです。

そのアドレスがどのように計算されるかを理解するため。pc は、命令のフェッチを開始するときに 0xD にあり、2 バイトかかるため、この命令を実行する準備ができているとき、pc は 0xD+2 = 0xF にあります。オフセットは 0x4 なので、0xF+0x4 = 0x13 が宛先アドレスです。

20:75 ed jne f

後ろ向きも同様です。pc + バイト数 = 0x20+2 = 0x22. 0xED は符号付きの数値であり、負であるため、0xED を 0xFFFFFFF...FFFFED に符号拡張しますが、アドレス レジスタは大きくなります。0x22+0xFFFFFF...FFFED を追加すると、宛先アドレスが 0x0F になります。0xED を反転して 1 を追加して無効にすることもできます。~0xED = 0x12、0x12+1 = 0x13。したがって、0xED は 0x13 を減算することを意味します。0x22-0x13=0x0F。

ここにさらにいくつかあります。それぞれの場合で、objdump 出力で探すことができるターゲットアドレスを提供します。

その値を計算する方法を理解するため。同じ話で、0x400A81 のオペコードから開始します。この場合、可変長命令に 6 バイトかかります。したがって、PC を実行する準備が整うまでに、PC は 0x400A81+6 = 0x400A87 になります。オフセットは 0x107 なので、条件が満たされた場合、宛先アドレスは 0x400A87 + 0x107 = 0x400B8E になります。

これらは、順次コードではなく、より大きなプログラムから抽出されたものであり、孤立した例のコレクションにすぎないことに注意してください。

  400a81: 0f 8f 07 01 00 00 jg 400b8e
  400a8f: 0f 8f e6 00 00 00 jg 400b7b
  400a9d: 0f 8f c5 00 00 00 jg 400b68
  400aab: 0f 8f a4 00 00 00 jg 400b55
  400ab9: 0f 8f 83 00 00 00 jg 400b42
  401d76: 0f 8f 31 01 00 00 jg 401ead
于 2010-11-30T04:47:25.967 に答える