3

I have an elf file, and I would like to know if it's possible to get some infos about, where an variable (string) is used in the executable.

If I print out the strings of the .elf I find an interesting string, and I would like to know, in which function it is used, is this somehow possible?

Thank you!

Manuel
  • 613
  • 1
  • 6
  • 20

1 Answers1

5

Let's consider the following example:

test.c

#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    char *str_a = "a";
    char *str_abc = "abc";

    printf("%s\n", str_a);
    printf("%s\n", str_abc);

    exit(EXIT_SUCCESS);
}

Let's compile it: gcc -Wall -pedantic-errors -o ~/test ~/test.c.

This will produce the file called test.

Let's examine .rodata section: readelf -x .rodata ./test.

This output is as follows:

Hex dump of section '.rodata':
  0x00400610 01000200 61006162 6300              ....a.abc.

The starting address 0x00400610 is displayed. The four dots are displayed before the first string constant and thus the address of the string a will be 0x00400614. Skipping a and a null byte (delimiter) skips 2 bytes, and the address of abc will be 0x00400616. So, at this point, the two addresses are known.

Next, let's perform objdump -M intel -d ./test.

Here is the listing of main within .text section:


    0000000000400546 <main>:
      400546:   55                      push   rbp
      400547:   48 89 e5                mov    rbp,rsp
      40054a:   48 83 ec 20             sub    rsp,0x20
      40054e:   89 7d ec                mov    DWORD PTR [rbp-0x14],edi
      400551:   48 89 75 e0             mov    QWORD PTR [rbp-0x20],rsi
      400555:   48 c7 45 f8 14 06 40    mov    QWORD PTR [rbp-0x8],0x400614
      40055c:   00 
      40055d:   48 c7 45 f0 16 06 40    mov    QWORD PTR [rbp-0x10],0x400616
      400564:   00 
      400565:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
      400569:   48 89 c7                mov    rdi,rax
      40056c:   e8 9f fe ff ff          call   400410 <puts@plt>
      400571:   48 8b 45 f0             mov    rax,QWORD PTR [rbp-0x10]
      400575:   48 89 c7                mov    rdi,rax
      400578:   e8 93 fe ff ff          call   400410 <puts@plt>
      40057d:   bf 00 00 00 00          mov    edi,0x0
      400582:   e8 b9 fe ff ff          call   400440 <exit@plt>
      400587:   66 0f 1f 84 00 00 00    nop    WORD PTR [rax+rax*1+0x0]
      40058e:   00 00

So, it is quite clear from the listing how the two strings are put on the screen. The listing mentions the two addresses found above - they are highlighted.

So, all in all, you may examine .rodata section, find the location address of a particular string and then just grep for the address found within .text section.

  • What a great answer! I've got the address of my string now, that works fine. If I try to read the .text section, it seems that I have no absolute reference to the memory. Example output: 14045fc4: 40 1e 00 18 bne cr7,14045fdc <_init+0x19a4c> So I need to know e.g. on which address "_init" is located. But there are thousands of relative addresses. Is there an elegant way to find it, even though of this reference? – Manuel Oct 04 '17 at 22:07
  • Is this impossible, to dig futher into this file, as it is stripped to much? What I would like to end up if possible: Find out the location of the function. Get the arguments of the function. Read the arguments which are called from the program and in the end - change the arguments to call the function with different ones. Is this somehow ever possible, or is this just a dream ;)? – Manuel Oct 07 '17 at 07:04