I'm dealing with a large executable, for which I do not have sources (long story).
I'd like to extract the binary code of several functions from it -- and try to call them from my own program. The functions I'm looking for were all compiled from the same source-file (using gcc on Linux), if it matters.
I can see the function's binary code using objdump. Is there any way I could convince the tool to dump a functions' binary code -- with nothing else and without disassembling?
Basically, if the C-file, where the functions were defined, was called foo.c, I want to get foo.o (I'd actually prefer foo.So, but that's not going to exist in an executable). Can it be done with objdump, readelf or some such?
The functions are self-contained, if it matters.
Thanks!
Can it be done with objdump, readelf or some such?
Sure: you can write out the bytes that comprise the function using GDB. Example:
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
Note that the contents of foo.o is exactly the code bytes of foo.
I want to get foo.o
That part unfortunately is impossible: the relocation records have all been resolved. If foo() calls bar(), the bar
will not appear anywhere in the code, only its address.
Now, if the functions need are all leaf (don't call any other ones), and don't reference any global data, then the byte sequence you now know how to dump can be used to reconstruct a linkable foo.o, like so:
{ 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