3

I need to write a program (in c++), that among other things needs to know all functions of a given PE file. Basically, It's an equivalent of opening a binary with "r2 -A binary_name" and then entering afl command.

Is there a way to do it using radare2 c\c++ API(libr)? If yes, how?

2
  • Fwiw the lib files always appear to be missing in the windows package there is a small test file here that shows how to use the api but i could never build it because the r2 package doesnt have any lrbr.so or libr.a files github.com/radare/radare2-bindings/tree/master/c if you paste the code in lnto a text file in "r2\include\libr" and use mingw gcc -I. foo.c then mingw ld throws unreferenced r_bin_new() error because it cant find the lib file see if you can get them in in some nixy os
    – blabb
    Jun 26, 2017 at 12:39
  • I've actually run into the same problem under linux. And I have all radare library files under /usr/lib. However they are symlinks, and files they link to don't exist.
    – E. Fedorov
    Jun 26, 2017 at 23:25

1 Answer 1

3

r2pipe

The best programming interface to radare2 called r2pipe.

To quote from the project's Github page:

The r2pipe APIs are based on a single r2 primitive found behind r_core_cmd_str() which is a function that accepts a string parameter describing the r2 command to run and returns a string with the result.

r2pipe supports many programming languages including Python, NodeJS, Rust, C and others.


Writing the program

To use r2pipe you should first make sure you have radare2 installed. It is always recommended to use the latest version from git.

Install or update radare2 with the following steps:

$ git clone https://github.com/radare/radare2.git # clone radare2 if you didn't do it yet for some reason.
$ cd radare2
$ ./sys/install.sh

Now after radare2 is installed and updated let's move to write the C program to list all the functions of the binary. As you've mentioned in your question, it should be the equivalent for opening the binary with radare2, executing aaa to analyze the binary (which is actually r2 -A binary_name) and then execute afl to list all the functions.

First we should define a function that accepts r2 instance and command. This function will execute the command, print the results and free the resulting string.

#include <r_socket.h>                           

static void r2cmd(R2Pipe *r2, const char *cmd) {
        char *msg = r2p_cmd (r2, cmd);          
        if (msg) {                              
                printf ("%s\n", msg);           
                free (msg);                     
        }                                       
}  

After that, writing the main() function should be intuitive:

int main() {                                           
        R2Pipe *r2 = r2p_open ("r2 -q0 /bin/echo");
        if (r2) {                                  
                r2cmd (r2, "aaa");                 
                r2cmd (r2, "afl");                 
                r2p_close (r2);                    
                return 0;                          
        }                                          
        return 1;                                  
}   

We define an instance of r2 with the program we want to examine, and then use the function we just created to execute commands through radare2's interface. First we analyze the program using aaa and then we print the functions using afl.


Compiling

To compile the program using gcc we should execute the following command:

gcc list_functions.c -o list_functions $(pkg-config --cflags r_socket --libs r_socket)

References

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.