如何从已编译的ELF可执行文件中提取一些函数(无需反汇编)?

时间:2013-01-12 05:52:19

标签: elf objdump readelf

我正在处理一个大型可执行文件,我没有源代码(长篇故事)。

我想从中提取几个函数的二进制代码 - 并尝试从我自己的程序中调用它们。我正在寻找的函数都是从相同的源文件(在Linux上使用gcc)编译的,如果重要的话。

我可以使用objdump查看函数的二进制代码。有没有什么方法可以说服工具转储函数的二进制代码 - 没有别的东西而且没有反汇编?

基本上,如果定义函数的C文件被称为foo.c,我想得到foo.o(我实际上更喜欢foo.So,但这不会存在于可执行文件中) 。可以用objdump,readelf或其他一些方法完成吗?

如果重要的话,这些功能是独立的。

谢谢!

1 个答案:

答案 0 :(得分: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将不会出现在代码中的任何位置,只会出现在地址中。

现在,如果函数需要全部为leaf(不调用任何其他函数),并且不引用任何全局数据,那么您现在知道如何转储的字节序列可用于重建可链接的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