1

ソースがない大きな実行可能ファイルを扱っています(長い話)。

そこからいくつかの関数のバイナリコードを抽出したいのですが、自分のプログラムからそれらを呼び出してみてください。私が探している関数は、重要な場合は、すべて同じソースファイルからコンパイルされました(Linuxではgccを使用)。

objdumpを使用して関数のバイナリコードを確認できます。関数のバイナリコードをダンプするようにツールを説得する方法はありますか?他に何もせずに、分解することもありませんか?

基本的に、関数が定義されているCファイルがfoo.cと呼ばれる場合、foo.oを取得したいと思います(実際にはfoo.Soを好みますが、実行可能ファイルには存在しません)。objdump、readelfなどで実行できますか?

重要な場合、関数は自己完結型です。

ありがとう!

4

1 に答える 1

5

objdump、readelfなどで実行できますか?

もちろん、GDBを使用して関数を構成するバイトを書き出すことができます。例:

cat t.c
int foo() { return 42; }
int main() { return foo(); }

gcc t.c
gdb -q ./a.out

(gdb) disas/r foo
Dump of assembler code for function foo:
   0x00000000004004c4 <+0>:  55              push   %rbp
   0x00000000004004c5 <+1>:  48 89 e5        mov    %rsp,%rbp
   0x00000000004004c8 <+4>:  b8 2a 00 00 00  mov    $0x2a,%eax
   0x00000000004004cd <+9>:  c9              leaveq 
   0x00000000004004ce <+10>: c3              retq   
End of assembler dump.

(gdb) dump memory foo.o 0x00000000004004c4 0x00000000004004ce+1
(gdb) quit

od -tx1 foo.o
0000000 55 48 89 e5 b8 2a 00 00 00 c9 c3
0000013

foo.oの内容は、正確にfooのコードバイトであることに注意してください。

foo.oを取得したい

残念ながら、その部分は不可能です。再配置レコードはすべて解決されました。foo()がbar()を呼び出す場合bar、はコードのどこにも表示されず、そのアドレスのみが表示されます。

これで、必要な関数がすべてリーフであり(他の関数を呼び出さない)、グローバルデータを参照しない場合、ダンプする方法がわかっているバイトシーケンスを使用して、リンク可能なfoo.oを再構築できます。それで:

{ echo -e "foo:\n\t.byte\t\c";
  od -tx1 foo.o | cut -c9- |
    sed -e '/^ *$/d' -e 's/^/0x/' -e 's/ /,0x/g'; } > foo1.s

cat foo1.s 
foo:
    .byte   0x55,0x48,0x89,0xe5,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3

gcc -c foo1.s
objdump -d foo1.o

foo1.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 2a 00 00 00          mov    $0x2a,%eax
   9:   c9                      leaveq 
   a:   c3                      retq

QED

于 2013-01-13T03:24:01.257 に答える