Aim: I want to take hex and ascii data (derived from a binary file using xxd) and use Objdump (or a suitable other tool that Linux comes with) to output the memory addresses / offsets, assembly code, and text data.

Currently I can get the offsets and assembly code, but not text strings alongside.

I used the following: objdump -D -b binary -mi386 -Maddr16,data16 <filename>

Should I need to use the -s switch?

  • Are you analyzing data from binaries that conform to a particular ABI or format (ELF, COFF, MACHO, etc)? – SYS_V Feb 12 '17 at 20:08
  • You will need a tool like IDA to automatically determine what is data and code in your binary. – Willem Hengeveld Feb 12 '17 at 20:37
  • I can't use IDA at this moment. I am looking for manual methods or those that come with common Linux distributions. – unseen_rider Feb 13 '17 at 0:25
  • Some py scripts by iirc dion mendel in the old honeynet sotm reversing challenges used objdump and could beautify the deadlisting here is a link to a tut that adapts them to analyze a simple binary see if that helps ( the contents concepts and thevinevitable assumptions are old so you may need a pitcher full of salt nearby ) reversing.be/article.php?story=2005030218170966 – blabb Feb 13 '17 at 3:39
  • @blabb the site you linked in previous comment is blacklisted by Firefox. Any other page you know? – unseen_rider Feb 14 '17 at 2:39

It is assumed here that Linux ELF32 binaries are being analyzed.

Code and data such as strings are stored in separate parts of ELF binaries.

  • To disassemble the parts containing code, use objdump -dj .text <binary_name>.
  • To examine hard-coded string data, use readelf -x .rodata <binary_name>

Instructions and Data are located in separate areas within ELF binaries

Currently I can get the offsets and assembly code, but not text strings alongside.

Code and hardcoded strings are not intermingled in x86 or x86-64 ELF binaries. When the compiler toolchain generates a binary, hardcoded strings are placed in a separate area of the binary from the executable code and are referenced/accessed by their virtual memory address. Here is a diagram by Ange Albertini of the how different sections are laid out in ELF binaries: Ange Albertini ELF

To make this more clear, below are visualizations of the Linux utilities ls, cat, mkdir and mv (accomplished via binvis.io). The solid blue areas consist of ASCII string data (the .rodata section, for example), and the large blocks of blue, white, red and black mixed together are regions that consist of executable code (the .text section, for example).

* ls cat mkdir mv

ls cat mkdir mv

As we can see from these visualizations, these binaries are organized in a similar fashion. Each binary has discrete areas, or sections, which contain different information. We can also see here that there are multiple areas (i.e. sections) containing ASCII string data, not just one.

Sections with executable instructions will not contain meaningful strings, only code. This can be observed directly by using the -s option with objdump when examining the .text section of the Linux date utility:

$ objdump -sj .text /bin/date
/bin/date:     file format elf64-x86-64

Contents of section .text:
 401af0 41574531 ff415645 31f64155 41544531  AWE1.AVE1.AUATE1
 401b00 e45589fd 534889f3 4881ecd8 00000048  .U..SH..H......H
 401b10 8b3ee8f9 530000be a1c84000 bf060000  .>..S.....@.....
 401b20 00e8bafe ffffbe87 944000bf 61944000  .........@..a.@.
 401b30 e83bfcff ffbf6194 4000e811 fcffffbf  .;....a.@.......
 401b40 102c4000 e8877800 00c64424 0f0048c7  .,@...x...D$..H.
 < snip >

In ELF binaries, the .text section holds the executable instructions of the program. The bytes the instructions are composed of are being treated as ASCII in this hexdump, so there are meaningless sequences of characters being printed.

Objdump will treat data as instructions and disassemble accordingly

objdump relies on an ELF binary's section headers to determine which sections of the binary contain code and which sections contain data. Only sections with instructions (.text, for example) should be disassembled using objdump.The -D argument to objdump will result in all sections of an ELF binary being disassembled, even non-code sections like .data and .rodata.

From the manual page:

-D

--disassemble-all

Like -d, but disassemble the contents of all sections, not just those expected to contain instructions.

This means that even if a section contained hardcoded strings (.dynstr, .shstrtab, .rodata, etc.) objdump would treat this data as instructions and dissasemble them accordingly.

Here is an example using /bin/date:

/bin/date:     file format elf64-x86-64


Disassembly of section .rodata:

0000000000409400 <.rodata>:
  409400:       01 00                   add    %eax,(%rax)
  409402:       02 00                   add    (%rax),%al
  409404:       74 69                   je     40946f <__sprintf_chk@plt+0x798f>
  409406:       6d                      insl   (%dx),%es:(%rdi)
  409407:       65 20 25 73 20 69 73    and    %ah,%gs:0x73692073(%rip)        # 73a9b481 <stderr+0x7348d131>
  40940e:       20 6f 75                and    %ch,0x75(%rdi)
  409411:       74 20                   je     409433 <__sprintf_chk@plt+0x7953>
  409413:       6f                      outsl  %ds:(%rsi),(%dx)
  409414:       66                      data16
  409415:       20 72 61                and    %dh,0x61(%rdx)
  409418:       6e                      outsb  %ds:(%rsi),(%dx)
  409419:       67 65 00 0a             add    %cl,%gs:(%edx)
  40941d:       52                      push   %rdx
  40941e:       65                      gs
  40941f:       70 6f                   jo     409490 <__sprintf_chk@plt+0x79b0>
  < snip >

It looks like there are instructions being disassembled, when in reality is data being treated as code:

$ readelf -x .rodata /bin/date
Hex dump of section '.rodata':
  0x00409400 01000200 74696d65 20257320 6973206f ....time %s is o
  0x00409410 7574206f 66207261 6e676500 0a526570 ut of range..Rep

Furthermore, the arguments -b binary result in objdump treating the binary as a blob with a single section, obliterating any distinction between code and data within the binary, resulting in the entire contents of the binary being treated as code.

Reference: the System V ABI section 4: "Object Files"

  • Ok, so what syntax should I use for just disassembling the code sections using objdump? – unseen_rider Feb 13 '17 at 9:34
  • objdump -d <file name>. The -d option results in only the sections expected to contain code to be disassembled. – SYS_V Feb 13 '17 at 14:20
  • 1
    In fact, read-only strings may be present in code sections too, especially on embedded platforms like ARM or MIPS – Igor Skochinsky Feb 13 '17 at 20:37
  • 1
    ARM linker can add special symbols like $d to mark data areas in code sections (though I think these are mostly used for jump tables and such) but I don't know if objdump makes use of them. Your answer is fine for the common case, you can just mention your assumptions at the beginning. – Igor Skochinsky Feb 13 '17 at 22:33
  • 1
    @unseen_rider a hexdump of an unstripped binary will include the contents of the .strtab section. This section contains strings corresponding to the symbols in the binary's symbol table (.symtab). Among these strings there will be function names. If the binary is dynamically linked then this holds true for the .dynstr section as well. The .dynstr section will be present in a dynamically linked binary even if the binary is stripped. – SYS_V Feb 14 '17 at 3:18

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.