Baffling objdump
objdump is one of the most widley adopted linear disassembler, which often gives a significant help during initial binary analysis. A linear disassmbling algorithm, as opposed to a recursive one, is faster but also more prone to errors, as it only weeps through the file sections one instruction at a time, instead of inspecting every conditional statement.
Here, I would like to give a simple demo of how easily objdump can be confused, by filling the binary with instructions in the rdata section and strings in the text section.
With the aid of C’s inline-assembly, we can inject a the string “W00T” (in hex \x57 \x30 \x30 \x54) inside the text section.
void main(){
__asm__(
".section .text;"
"1: .string \"W00T\";"
);
}
We can inspect the the resulting dead listing’s text section with objdump.
# objdump -D -j .text test_text | grep -A10 "<main>:"
0000000000001125 <main>:
1125: 55 push %rbp
1126: 48 89 e5 mov %rsp,%rbp
1129: 57 push %rdi
112a: 30 30 xor %dh,(%rax)
112c: 54 push %rsp
112d: 00 90 5d c3 66 2e add %dl,0x2e66c35d(%rax)
1133: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
113a: 00
113b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
The 0x57 0x30 0x30 0x54 values can be quickly spotted and, with no surprise, objdump trasnslates them as instructions, instead of data. A similar and diametrical goal can be achieved by targeting the rdata section and inserting an instruction into it:
void main(){
__asm__(
".section .rdata;"
"xchg %eax,%eax;"
".section .text;"
);
}
# objdump -D -j .rdata test_rdata
test_data: file format elf64-x86-64
Disassembly of section .rdata:
0000000000000000 <.rdata>:
0: 87 c0 xchg %eax,%eax
As we can see, we have been able to insert an instruction inside the .rdata section. It is worth mentioning that, after entering the .rdata, we have to restore execution to the original .text section by declaring it.
Since objdump is made to produce deadlisting (static output from a disassembler), it is not the perfect tool to analyze strings. Readelf (or though, can be quite helpful when parsing an ELF in search for strings.
# readelf -x .rodata test_rdata
Hex dump of section '.rodata':
0x00002000 01000200 ....
# readelf -x .text test_text
Hex dump of section '.text':
[..snip..]
0x00001120 e97bffff ff554889 e5573030 5400905d .{...UH..W00T..]
0x00001130 c3662e0f 1f840000 0000000f 1f440000 .f...........D..
0x00001140 41574989 d7415649 89f64155 4189fd41 AWI..AVI..AUA..A
0x00001150 544c8d25 c02c0000 55488d2d c02c0000 TL.%.,..UH.-.,..
0x00001160 534c29e5 4883ec08 e893feff ff48c1fd SL).H........H..
0x00001170 03741b31 db0f1f00 4c89fa4c 89f64489 .t.1....L..L..D.
0x00001180 ef41ff14 dc4883c3 014839dd 75ea4883 .A...H...H9.u.H.
0x00001190 c4085b5d 415c415d 415e415f c30f1f00 ..[]A\A]A^A_....
0x000011a0 c3 .
These tools can be combined during the initial binary analysis phase, in order to verify and spot any intentionally misplaced portion of code or data