1

So I'm taking a class where I am given a single object file and need to reverse engineer it into c++ code. The command I'm told to use is "gdb assignment6_1.o" to open it in gdb, and "disass main" to see assembly code.

I'm also using "objdump -dr assignment6_1.o" myself since it outputs a little more information.

The problem I'm running into, is that using objdump, I can see that the program is trying to access what I believe is a variable or maybe a string, ".rodata+0x41". There are multiple .rodata's, that's just one example.

Is there a command or somewhere I can look to see what that's referencing? I also have access to the "Bless" program.

Below is a snippet of the disassembled code I have.

  a3:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # aa <main+0x31>
                        a6: R_X86_64_PC32       .rodata+0x41
  aa:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # b1 <main+0x38>
                        ad: R_X86_64_PC32       _ZSt4cout-0x4
  b1:   e8 00 00 00 00          callq  b6 <main+0x3d>
                        b2: R_X86_64_PLT32      _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc-0x4
  b6:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # bd <main+0x44>
                        b9: R_X86_64_PC32       .rodata+0x53
  bd:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # c4 <main+0x4b>
                        c0: R_X86_64_PC32       _ZSt4cout-0x4
  c4:   e8 00 00 00 00          callq  c9 <main+0x50>
                        c5: R_X86_64_PLT32      _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc-0x4
  c9:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # d0 <main+0x57>
                        cc: R_X86_64_PC32       .rodata+0x5e
  d0:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # d7 <main+0x5e>
                        d3: R_X86_64_PC32       _ZSt4cout-0x4
  d7:   e8 00 00 00 00          callq  dc <main+0x63>
                        d8: R_X86_64_PLT32      _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc-0x4
  dc:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # e3 <main+0x6a>
                        df: R_X86_64_PC32       .rodata+0x6e
  e3:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # ea <main+0x71>
                        e6: R_X86_64_PC32       _ZSt4cout-0x4
  ea:   e8 00 00 00 00          callq  ef <main+0x76>
                        eb: R_X86_64_PLT32      _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc-0x4```
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Troutt025
  • 55
  • 4
  • Does this answer your question? [How can I examine contents of a data section of an ELF file on Linux?](https://stackoverflow.com/questions/1685483/how-can-i-examine-contents-of-a-data-section-of-an-elf-file-on-linux) – Brian61354270 Jun 07 '22 at 22:27
  • 1
    It's not a linked executable, so the addresses in the machine code are just placeholders. Actually linking it with `g++ -g foo.o -o foo` might give you something easier to work with. Maybe GDB's `x` command will still work on an object file, given the right address, but without linking there is no well-defined absolute address for anything, or for .rodata relative to .text. – Peter Cordes Jun 07 '22 at 22:30
  • Try `objdump -s`. – fuz Jun 07 '22 at 22:54
  • I'm voting "no, there is no way to see the contents of memory from an object file". The expression `.rodata+0x41` could refer to memory location whose value is initialized or set at runtime. Thus, the program would need to be executed to find out the value of the specified location. – Thomas Matthews Jun 07 '22 at 23:13
  • 2
    @Thomas, the "ro" in ".rodata" stands for "read-only". – prl Jun 08 '22 at 00:27
  • `objdump` is not the right tool here. You can see in that listing that it is showing instruction and relocations (fixups) interleaved without really applying them (`objdump` is mostly for dumping). It's better to stick with `gdb` or a real tool for RE, like IDA Free (which will also demangle the names and show the strings). You can see what's at `.rodata+0x41` by dumping `.rodata` (that's what `objdump` is for) and using a hex viewer but that's tiresome and error prone. BTW, you will find a null-terminated string there, since `std::ostream& <<(std::ostream&, char const*)` is called next. – Margaret Bloom Jun 08 '22 at 08:15
  • @Brian, so that did give me the contents of .rodata, which is mainly strings. Which is great, since now I know what specific string some of the rodata's are referencing. But other rodata's are not shown there for some reason. I'm assuming that they're variables, and based on what I've read elsewhere, I can't see what the variables are. So it does answer my question. Also, thank you everyone else for the helpful comments. – Troutt025 Jun 08 '22 at 18:03

1 Answers1

2

Is there a way to see what's inside a ".rodata+(memory location)" in an object file?

Sure. Both objdump and readelf can dump contents of any section.

Example:

// x.c
#include <stdio.h>

int foo() { return printf("AA.\n") + printf("BBBB.\n"); }

gcc -c x.c
objdump -dr x.o

...
   9:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 10 <foo+0x10>
                        c: R_X86_64_PC32        .rodata-0x4
...
  1f:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 26 <foo+0x26>
                        22: R_X86_64_PC32       .rodata+0x1
...

Note that because the RIP used in these instructions is the address of the next instruction, the actual data we care about is at .rodata+0 and .rodata+5 (in your original disassembly, you care about .rodata+45, not .rodata+41).

So what's there?

 objdump -sj.rodata x.o

x.o:     file format elf64-x86-64

Contents of section .rodata:
 0000 41412e0a 00424242 422e0a00           AA...BBBB...

or, using readelf:

readelf -x .rodata x.o

Hex dump of section '.rodata':
  0x00000000 41412e0a 00424242 422e0a00          AA...BBBB...

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thank you for the answer! I can see most of the .rodata info now. But what I seem to be missing is that while some of the rodata's are visible, there are a few that don't seem to have strings attached to them. Are these variables that aren't visible in rodata? Or am I missing something? – Troutt025 Jun 08 '22 at 18:46
  • @Troutt025: There could be `0` padding for alignment between some things in `.rodata`. Note that C strings are variable length, so you have to look all the way to a `0` byte, and then see what's after that, if you're trying to account for everything in `.rodata`. Of course, the source could have something like `const int foo[] = {1,2,3};` which would go in `.rodata` without making any asm that referenced the address, but would have a name in the symbol table so other object files can link against it. Check with `nm` or`readelf` for symbol names. – Peter Cordes Jun 08 '22 at 19:02