10

I made a simple hello world program, and put it in radare2. I then ran the pc command, which displayed C output. The output was this:

#define _BUFFER_SIZE 256
const uint8_t buffer[256] = {
  0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x10, 0x48, 0x8d,
  0x3d, 0x3b, 0x00, 0x00, 0x00, 0xc7, 0x45, 0xfc, 0x00, 0x00,
  0x00, 0x00, 0xb0, 0x00, 0xe8, 0x0d, 0x00, 0x00, 0x00, 0x31,
  0xc9, 0x89, 0x45, 0xf8, 0x89, 0xc8, 0x48, 0x83, 0xc4, 0x10,
  0x5d, 0xc3, 0xff, 0x25, 0x80, 0x00, 0x00, 0x00, 0x4c, 0x8d,
  0x1d, 0x71, 0x00, 0x00, 0x00, 0x41, 0x53, 0xff, 0x25, 0x61,
  0x00, 0x00, 0x00, 0x90, 0x68, 0x00, 0x00, 0x00, 0x00, 0xe9,
  0xe6, 0xff, 0xff, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
  0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x01, 0x00,
  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00,
  0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x8b, 0x0f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x10, 0x00,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

The issue is that I do not know how to properly use this output (compile it, use it, etc). If anybody can help please do. Thanks!

7
  • 1
    It will only print the current location as a c-style array. You can use this if you want to use the buffer in your code...
    – mrexodia
    Apr 21, 2017 at 1:58
  • 1
    @mrexodia please consider reformulating the content of your comment as an answer for the sake of other people with similar questions.
    – Nordwald
    Apr 21, 2017 at 7:50
  • @mrexodia yeah I know, but I don't know how to use the buffer... Apr 21, 2017 at 11:56
  • Neither do I, why do you want a C buffer?
    – mrexodia
    Apr 21, 2017 at 12:12
  • @mrexodia I was wondering how to use it... Apr 21, 2017 at 21:46

2 Answers 2

20

The pc command will output n bytes from the current seek (s) as a C array, where n is the Block size (b) or the length mentioned in the command.

The output is then can be used to, for example, manipulate the array outside of radare2, build a shellcode, decrypt a buffer and so on.

Let's demonstrate it with a simple example.
Here's a tiny HelloWorld.c program:

#include  <stdio.h>

void main()
{
        printf("Hello, World!\n");
}

Let's compile it with gcc HelloWorld.c -o HelloWorld and open it with radare2 r2 -A HelloWorld

Now let's seek to main and print the function:

[0x00400400]> s main
[0x004004d7]> pdf
            ;-- main:
/ (fcn) sym.main 17
|  sym.main ();
|           ; DATA XREF from 0x0040041d (entry0)
|       0x004004d7      55             push rbp
|       0x004004d8      4889e5         mov rbp, rsp
|       0x004004db      bf74054000     mov edi, str.Hello__World_ ; "Hello, World!"
|       0x004004e0      e80bffffff     call sym.imp.puts          ; int puts(const char *s)
|       0x004004e5      90             nop
|       0x004004e6      5d             pop rbp
\       0x004004e7      c3             ret

As I said, just a simple Hello World program :)

Now, instead of printing the disassembly let's print only the hex bytes of the function using pxf:

0x004004d7  5548 89e5 bf74 0540 00e8 0bff ffff 905d  UH...t.@.......]
0x004004e7  c3

These are the hex-bytes which represent the function.
To the final part, using bf sym.main let's define the current Block size to be as the size of main, and then print the C-array using pc:

[0x004004d7]> bf sym.main
[0x004004d7]> pc
#define _BUFFER_SIZE 17
const uint8_t buffer[17] = {
  0x55, 0x48, 0x89, 0xe5, 0xbf, 0x74, 0x05, 0x40, 0x00, 0xe8,
  0x0b, 0xff, 0xff, 0xff, 0x90, 0x5d, 0xc3
};

You can easily see that the array is structured from the hex bytes we printed before, from 0x55 (push rbp) to 0xc3 (return). That's it.

Let's say for example that you disassembled a program and spotted a XOR encrypted data and you want to dump it to a C program and manipulate it there. In such case you need to seek to the offset of the encrypted data (s <addr>), define the block size to be the length of the data (b 150) and then dump it as a C-array using pc (or as a python array using pcp).


Decompilation
Some people expect the pc command to be a decompilation of the program to C. If you want to decompile a function to C in radare you can use one of the following ways:

The pdc command to print C-like syntax:

function sym.main () {
    loc_0x4004d7:

     //DATA XREF from 0x0040041d (entry0)
       push rbp                 
       rbp = rsp                
       edi = str.Hello__World ; "Hello, World!"                                                                       
       int puts(const char * s : 0x00400574 = Hello, World!)                                    
       pop rbp                  

}

Use r2dec - a plugin to radare that can produce a pseudo-C output
Use radeco - a radare decompiler tool based on radeco-lib.
Use r2snowman - radare2 plugin which integrates the snowman decompiler.

4

I wanted to expand on MegaBeets awesome answer. I don't see the point of pdc. It seems more wrong and less high-level.

pdf is awesome for my use cases. If I want something high level, I'll use pdd with r2dec. You can install it with r2pm -i r2dec.

[0x0000063a]> pdd
/* r2dec pseudo C output */
#include <stdint.h>

void main (void) {
    puts ("Hello, World!");
}

For more information see

Your Answer

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

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