I am struggling with a stripped binary, and I would like to visualize the main() function with the VVV command (ascii-art CFG representation).

Usually, the steps are the following:

  1. #> r2 ./crackme (run radare2 on the crackme).
  2. [0x00005430]> aaa (start the analysis of the binary).
  3. s main (seek to the address of main).
  4. VVV (switch to the CFG view of the binary).

enter image description here

Unfortunately, my crackme is stripped (including the main() function). I can see the address of the main() function thanks to the first argument of the __libc_start_main() function. But, I always end-up with the following error message:

      Not in a function. Type 'df' to define it here

--press any key--

How can I work around this problem. For example, I first tried to add my own symbols on the binary to mark the start of the main() function, but I miserably failed... Any idea ?


Here is my attempt to add a flag to the binary:

#> r2 ./ch23.bin 
[0x000083b8]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[ ] 
[aav: using from to 0x8000 0x8e64
Using vmin 0x8000 and vmax 0x10880
aav: using from to 0x8000 0x8e64
Using vmin 0x8000 and vmax 0x10880
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[ ] [*] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan))
[0x000083b8]> pdf
            ;-- section_end..plt:
            ;-- section..text:
/ (fcn) entry0 44
|   entry0 ();
|           ; UNKNOWN XREF from 0x00008018 (unk)
|           ; UNKNOWN XREF from 0x00008c18 (unk)
|           0x000083b8      00b0a0e3       mov fp, 0                   ; [14] va=0x000083b8 pa=0x000003b8 sz=800 vsz=800 rwx=--r-x .text
|           0x000083bc      00e0a0e3       mov lr, 0
|           0x000083c0      04109de4       pop {r1}
|           0x000083c4      0d20a0e1       mov r2, sp
|           0x000083c8      04202de5       str r2, [sp, -4]!
|           0x000083cc      04002de5       str r0, [sp, -4]!
|           0x000083d0      10c09fe5       ldr ip, [0x000083e8]        ; [0x83e8:4]=0x8664
|           0x000083d4      04c02de5       str ip, [sp, -4]!
|           0x000083d8      0c009fe5       ldr r0, [0x000083ec]        ; [0x83ec:4]=0x8470
|           0x000083dc      0c309fe5       ldr r3, [0x000083f0]        ; [0x83f0:4]=0x8668
\           0x000083e0      e5ffffeb       bl sym.imp.__libc_start_main; int __libc_start_main(func main, int argc, char **ubp_av, func init, func fini, func rtld_fini, void *stack_end);
[0x000083b8]> f main @ 0x8470
[0x000083b8]> s main
[0x00008470]> VVV
... miserable fail ...
  • Out of curiosity, what methods/techniques were used in the unsuccessful attempt to add symbols to the binary? – julian Apr 18 '17 at 16:42
  • Can you share the binary? I am unable to reproduce this error when analyzing non-PIE binutils or IOLI crackme0x09 – julian Apr 18 '17 at 17:38
  • 1
    I added an edit to the question. Hope this is enough (yes, this is ARM... not my best... but I'm learning!). – perror Apr 18 '17 at 18:00

I know it's been over a year since you've asked this question, but I thought in the interest of anyone else who may have come across this question like me, I would field an answer.

There are a few ways I've found to get radare2 to properly analyze the newly defined function:

  1. Seek to the address you would like to define the function at

  2. Type 'V' to enter hexdump mode

  3. Type 'd' then 'f' to define the function at that point

  4. Now you can press 'V' again and you will get a properly rendered control flow graph

The other way I found avoids visual mode, which is preferable for scripting:

  1. Define the function as you did using a command like 'f main @ 0x8470', with main being the function name and 0x8470 being the address, of course.

  2. Run the command 'af main', where main is the name of the function just defined.

  3. Voila! Your newly created function is now analyzed.

I have tried both of these methods on an executable I'm analyzing which has the same problem you're describing, and both provided the same results.

| improve this answer | |

I finally got the answer to my old question !

So, basically Ian Kerr answer got most of it right, it was just missing a few bits of information. I will try to gather everything in this answer.

Let say that we are going through a stripped binary, no symbol in sight and radare2 with us:

#> r2 ./crackme
[0x0804876c]> pd
    ;-- entry0:
       ;-- section..text:
       ;-- eip:
       0x08048680      31ed           xor ebp, ebp
       0x08048682      5e             pop esi
       0x08048683      89e1           mov ecx, esp
       0x08048685      83e4f0         and esp, 0xfffffff0
       0x08048689      54             push esp
       0x0804868b      6830880408     push 0x8048830
       0x08048690      6840880408     push 0x8048840
       0x08048695      51             push ecx
       0x08048696      56             push esi
       0x08048697      686c870408     push main          ; 0x804876c
       0x0804869c      e87fffffff     call sym.imp.__libc_start_main
       0x080486a1      f4             hlt
[0x08048680]> f sym.main @ 0x804876c
[0x08048680]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x08048680]> s sym.main
[0x0804876c]> pdf
            ; DATA XREF from entry0 @ 0x8048697
            ;-- sym.main:
┌ 96: int main (int argc, char **argv, char **envp);
│           ; var char *var_20h @ esp+0x4
│           ; var int32_t var_8h @ esp+0x1c
│           0x0804876c      55             push ebp

To sum-up, you need:

  1. To find the address of the function you want to add. Here, we found main() thanks to __libc_start_main() at 0x804876c.

  2. To set a symbol tagged with sym. in order to be recognized by radare2 as a symbol:

    f sym.main @ 0x804876c

  3. To perform an analysis of the new symbol with aaa.

  4. Then, to switch the focus to this symbol: s sym.main

  5. Finally, you can run pdf or VV as usual.


| 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.