Radare2 C 输出

逆向工程 C 雷达2
2021-06-26 09:24:03

我做了一个简单的hello world程序,放到radare2中。然后我运行了pc显示 C 输出命令。输出是这样的:

#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
};

问题是我不知道如何正确使用此输出(编译它、使用它等)。如果有人可以帮忙,请做。谢谢!

2个回答

pc命令将从当前搜索 ( ) 中输出n个字节s作为 C 数组,其中n是块大小 ( b) 或命令中提到的长度。

然后,输出可用于,例如,在radare2 外部操作阵列、构建shellcode、解密缓冲区等。

让我们用一个简单的例子来演示它。
这是一个小小的 HelloWorld.c 程序:

#include  <stdio.h>

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

让我们gcc HelloWorld.c -o HelloWorld用radare2编译并打开它r2 -A HelloWorld

现在让我们寻找main并打印函数:

[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

正如我所说,只是一个简单的 Hello World 程序 :)

现在,我们不打印反汇编,而是使用pxf以下命令仅打印函数的十六进制字节

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

这些是表示函数的十六进制字节。
最后一部分,使用bf sym.main让我们将当前块大小定义为 的大小main,然后使用 打印 C 数组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
};

你可以很容易地看到这个数组是由我们之前打印的十六进制字节构成的,从 0x55 ( push rbp) 到 0xc3 ( return)。而已。

例如,假设您反汇编了一个程序并发现了一个 XOR 加密数据,并且您想将其转储到 C 程序并在那里对其进行操作。在这种情况下,您需要寻找加密数据 ( s <addr>)的偏移量,将块大小定义为数据的长度 ( b 150),然后将其转储为 C 数组 using pc(或作为 python 数组 using pcp)。


反编译
有些人期望该pc命令是将程序反编译为 C。如果您想在radare 中将函数反编译为 C,您可以使用以下方法之一:

pdc打印类 C 语法命令:

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                  

}

使用r2dec- 一个可以产生伪 C 输出的雷达插件
使用radeco- 一个基于 radeco-lib 的雷达反编译工具。
使用r2snowman-radare2 插件,它集成了雪人反编译器。

我想扩展 MegaBeets 很棒的答案。我不明白的地步pdc好像错的多,高级的少。

pdf对我的用例来说很棒。如果我想要一些高级别的东西,我将pdd与 r2dec 一起使用您可以使用r2pm -i r2dec.

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

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

有关更多信息,请参阅