特定のオブジェクト・ファイルのためにこれを行うには2つの方法があります。
gcc
から-ffunction-sections
オプションは、コンパイルされたsourcefileの各機能について別々のELFセクションを作成することを指示します。
- シンボルテーブルには、セクション名、開始アドレス、および指定された関数のサイズが含まれます。
--start-address
/--stop-address
引数を使用してobjdump
に入力することができます。
最初の例は:
$ readelf -S t.o | grep ' .text.'
[ 1] .text PROGBITS 0000000000000000 00000040
[ 4] .text.foo PROGBITS 0000000000000000 00000040
[ 6] .text.bar PROGBITS 0000000000000000 00000060
[ 9] .text.foo2 PROGBITS 0000000000000000 000000c0
[11] .text.munch PROGBITS 0000000000000000 00000110
[14] .text.startup.mai PROGBITS 0000000000000000 00000180
これは-ffunction-sections
してコンパイルされていて、4つの機能、foo()
、私のオブジェクト・ファイル内のbar()
、foo2()
とmunch()
があります。私はそうのように、それらを別々に分解することができます
$ objdump -w -d --section=.text.foo t.o
t.o: file format elf64-x86-64
Disassembly of section .text.foo:
0000000000000000 <foo>:
0: 48 83 ec 08 sub $0x8,%rsp
4: 8b 3d 00 00 00 00 mov 0(%rip),%edi # a <foo+0xa>
a: 31 f6 xor %esi,%esi
c: 31 c0 xor %eax,%eax
e: e8 00 00 00 00 callq 13 <foo+0x13>
13: 85 c0 test %eax,%eax
15: 75 01 jne 18 <foo+0x18>
17: 90 nop
18: 48 83 c4 08 add $0x8,%rsp
1c: c3 retq
他のオプションは、(nm
は、シンボルテーブルエントリダンプ)このように使用することができます。この場合は
$ nm -f sysv t.o | grep bar
bar |0000000000000020| T | FUNC|0000000000000026| |.text
$ objdump -w -d --start-address=0x20 --stop-address=0x46 t.o --section=.text
t.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000020 <bar>:
20: 48 83 ec 08 sub $0x8,%rsp
24: 8b 3d 00 00 00 00 mov 0(%rip),%edi # 2a <bar+0xa>
2a: 31 f6 xor %esi,%esi
2c: 31 c0 xor %eax,%eax
2e: e8 00 00 00 00 callq 33 <bar+0x13>
33: 85 c0 test %eax,%eax
35: 75 01 jne 38 <bar+0x18>
37: 90 nop
38: bf 3f 00 00 00 mov $0x3f,%edi
3d: 48 83 c4 08 add $0x8,%rsp
41: e9 00 00 00 00 jmpq 46 <bar+0x26>
を、-ffunction-sections
オプションはを持っていませんしたがって、関数の開始オフセットはゼロではなく、別のセクションにはありません(ただし、.text
)。
オブジェクトファイルを逆アセンブルするとき、オブジェクトファイル、call
ターゲット(だけでなく、グローバル変数のアドレス)で解決されていない、これは、あなたが望む正確何ではありません...しかし
を用心 - ここでは、foo
がprintf
を呼び出すことはできません。これは、バイナリレベルでの解像度がリンク時にのみ発生するためです。アセンブリのソースは、そこにcall printf
を持っています。このcallq
がprintf
に実際にあるという情報は、(それがリンカーによって「パッチを適用」されるオブジェクトファイルに場所を示し、いわゆるリロケーションセクションに'S)オブジェクトファイルであるが、コードとは別に。ディスアセンブラはこれを解決できません。
一部のIDEでは、ブレークポイントを設定し、その関数によって生成されたアセンブリコードを表示できます。これは*逆アセンブリウィンドウと呼ばれています。それはあなたが探しているものを行うはずです - あなたはIDEを使用していますか? – Aaron
私は(最適化を使って)コンパイルしてから逆アセンブルすることを好みますが、コンパイラが外部アドレスなどのために不完全な命令をいくつか残していることを理解する必要がありますが、-Sを使用するよりもIMOを読む方が簡単です。 gcc -O2 -c hello.c -o hello.o、objdump -D hello.o –
ここに行きます:http://gcc.godbolt.org/機能を貼り付け、コンパイラを選択すると非常に便利です。 – harold