I have an elf executable. I found a string (awesome string) in my .rodata section:

$ mb-readelf -p 10 a.out

String dump of section '.rodata':
  [     0]  Hello world
  [  ab12]  awesome string

Here are the sections:

$ readelf -S a.out
There are 27 section headers, starting at offset 0x10150:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [10] .rodata           PROGBITS        00004fc8 00a030 001394 00   A  0   0  4

So the address of awesome string is 00004fc8 + ab12 = 14ada

I want to know which functions are using this awesome string. How can I know who references the address 14ada?

  • using what ? your code? / a decent disassembler / how are you looking most decent disassembler will cross reference the string – blabb Jul 24 at 17:38

It cannot be solved in all cases.

Some string (start) is not referenced in the whole text at all, even if you turned on all optimizations. Let's see the following example.

#define _FILE strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__

_FILE will point the filename instead of the full path, however, the compiled elf will contain the whole __FILE__ string (the whole path) (See more details here.)

In this case, .rodata will be seen like this:

$ readelf -p 10 a.out

String dump of section '.rodata':
  [     0]  Hello world
  [  ab12]  /your/build/folder/awesome.c

While the text will not refer the 0xab12 anywhere, because _FILE points to 0xab25 (the start of the awesome.c) and the text will refer to this 0xab25 adress.

A workaround can be that checking all offsets of a given string.


The following solution works with MicroBlaze GCC, but the solution approach is general, so it can be applied to all architecture.

Find a known string in rodata. (A string with known usage. For example print a Hello world message at the beginning of the main.) Check out the compiled assembly. MicroBlaze GCC uses the strings in printf as following:

00000100 <main>:
     1ec:       b0000000        imm     0
     1f0:       30a09fc8        addik   r5, r0, -24632  // This is the HELLO WORLD
     1f4:       31000004        addik   r8, r0, 4
     1f8:       11330000        addk    r9, r19, r0
     1fc:       b9f45a58        brlid   r15, 23128      // 6954 <printf>

So this compiler refers the addresses as 16 bit signed values.

To get the referring code line, convert the 0xfada (the absolute address of the awesome string) to 16 bit signed integer -1318 and search (grep) for this value in the disassembled text.

| improve this answer | |

As i commented a decent disassembler will already do this for you

here is sample output for a random awesome string in a random binary using radare2

radare2 on cdb.exe from windbg in win7 x86 

grepping  for some awesome string 
[0x00416870]> iz~deb
006 0x00018280 0x00419080  12  26 (.data) utf16le debugger.chm  <<<< an awesome string 

printing crossrefs

[0x00416870]> axg @0x419080
- 0x00419080
  - 0x00413cfe fcn 0x00413c6c fcn.00413c6c
  - 0x00413c6c fcn 0x00413c6c fcn.00413c6c
    - 0x00416755 ???
  - 0x00413d17 fcn 0x00413c6c fcn.00413c6c
  - 0x00413d2b fcn 0x00413c6c fcn.00413c6c
  - 0x00413d38 fcn 0x00413c6c fcn.00413c6c
 looking at the listed cross refs
[0x00416870]> pd1@0x413cfe
|           0x00413cfe      6880904100     push str.debugger.chm       ; 0x419080 ; u"debugger.chm"
[0x00416870]> pd1@0x413d17
|           0x00413d17      6880904100     push str.debugger.chm       ; 0x419080 ; u"debugger.chm"
[0x00416870]> pd1@0x413d2b
|           0x00413d2b      66a380904100   mov word str.debugger.chm, ax ; [0x419080:2]=100 ; u"debugger.chm"
[0x00416870]> pd1@0x413d38
|           0x00413d38      b980904100     mov ecx, str.debugger.chm   ; 0x419080 ; u"debugger.chm"
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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