3

The disassembly at the entry point looks like this:

 :   ;-- entry0:
        :   ;-- _mainCRTStartup:
        :   ;-- eip:
        :   0x004014e0      83ec0c         sub esp, 0xc
        :   0x004014e3      c70598534000.  mov dword [0x405398], 0     ; [0x405398:4]=0
        :   0x004014ed      e86e020000     call sym.___security_init_cookie
        :   0x004014f2      83c40c         add esp, 0xc
        `=< 0x004014f5      e986fcffff     jmp sym.___tmainCRTStartup
            0x004014fa      90             nop
            0x004014fb      90             nop
            0x004014fc      90             nop
            0x004014fd      90             nop
            0x004014fe      90             nop
            0x004014ff      90             nop
            ;-- ___gcc_register_frame:
            0x00401500      a130304000     mov eax, dword [0x403030]   ; [0x403030:4]=0
            0x00401505      85c0           test eax, eax
        ,=< 0x00401507      7443           je 0x40154c
        |   0x00401509      55             push ebp
        |   0x0040150a      89e5           mov ebp, esp
        |   0x0040150c      83ec18         sub esp, 0x18
        |   0x0040150f      c70424004040.  mov dword [esp], str.libgcj_13.dll ; section..rdata
        |                                                              ; [0x404000:4]=0x6762696c ; "libgcj-13.dll"
        |   0x00401516      ff151c614000   call dword [sym.imp.KERNEL32.dll_GetModuleHandleA] ; 0x40611c ; "Lb" ; HMODULE GetModuleHandleA(LPCSTR lpModuleName)
...

When I do an af it only finds function at entry0. Why is it not able to find the other functions that follow? For example, the functions at 0x004014ed, 0x00401516.

2
  • 1
    I think you are looking for aaf.
    – bart1e
    Commented Apr 8, 2021 at 15:38
  • I want to know the logic that af applies to find functions. If I do af @ main it seems to find a lot more. So why not at the entry point. Commented Apr 8, 2021 at 16:33

1 Answer 1

4

I want to know the logic that af applies to find functions.

Well... you can read exactly that logic. Radare2 is open source.

In particular, the r_core_anal_fcn called on line 4243 is the "core" workhorse which goes looking at the actual instructions, creating and crosslinking basic blocks, reconstructing local variables and function arguments signature, etc. Where does it start looking from? The addr argument. What gets passed in there? Line 4225, ut64 addr = core->offset;. The af logic starts from the current address, the one you change by seeking with the s command (which is the same when set via temporary seek af @ 0x1234).

See, you can find out a lot from just 1 page of C code. Locating that page can be hard, if you're not strong at navigating big C codebases, but here you go I found it for you.

Why is it not able to find the other functions that follow?

af doesn't "find" functions, it starts exactly where you tell it to (see above). Well, except with e anal.calls=1 — then it analyses recursively. Or with e anal.hasnext=1, then it assumes that the just-analysed function will be followed by another one.

If I do af @ main it seems to find a lot more.

Let's look at the entrypoint-main relation.

First of all, main is written by your program's author. Far not always: people will use all kinds of stubs, and frameworks, and languages — but let me assume the simplest case for a moment.

The entrypoint code is never written by your program's author. I'm oversimplifying again; rather extreme counterexamples would be programs coded in manual assembly, or r2 eggs. But virtually always, the code at entrypoint is placed there by a compiler — thus, written by a totally different person than your program's author. For that reason, it's marginally less interesting than main. Further, it's usually very generic, contains nothing specific to your program, and therefore boring & useless. Better start analysis at main or higher.

Relatedly, entrypoint logic doesn't reference main directly, for reasons of having to be generic. There'll be indirections. Simple/naive analysis (i.e. skipping call rax) won't traverse those indirections — so, af @ entry0 won't reach main.

Why is it not able to find the other functions that follow? For example, the functions at 0x004014ed, 0x00401516.

As suggested in comments and explained above, aaf is more suited to analyze all functions. afr will deal with recursive functions. You can also seek around and define them manually one-by-one (that's quite a bit faster in the visual mode: switch with V, cycle to disasm view with p, and then df to define function).

Make sure to explore the built-in help af?, a?, aa? etc. Also see https://book.rada.re. Reading the source can ultimately provide every possible answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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