如何使用radare2将函数符号添加到剥离的可执行文件中?

逆向工程 拆卸 雷达2
2021-06-30 10:02:00

我正在努力处理剥离的二进制文件,我想main()使用VVV命令(ascii-art CFG 表示)来可视化该函数

通常,步骤如下:

  1. #> r2 ./crackme (在crackme 上运行radare2)。
  2. [0x00005430]> aaa (开始分析二进制文件)。
  3. s main(寻找 的地址main)。
  4. VVV (切换到二进制文件的 CFG 视图)。

在此处输入图片说明

不幸的是,我的crackme 被剥离了(包括main()功能)。由于main()函数的第一个参数,我可以看到函数的地址__libc_start_main()但是,我总是以以下错误消息结束:

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

--press any key--

我该如何解决这个问题。例如,我首先尝试在二进制文件上添加我自己的符号来标记main()函数的开始,但我很惨地失败了......知道吗?

编辑

这是我向二进制文件添加标志的尝试:

#> 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 ...
2个回答

我知道你问这个问题已经一年多了,但我想为了其他像我一样遇到这个问题的人的利益,我会回答。

我发现有几种方法可以让radare2 正确分析新定义的函数:

  1. 寻找你想定义函数的地址

  2. 输入“V”进入十六进制转储模式

  3. 键入 'd' 然后键入 'f' 以在该点定义函数

  4. 现在您可以再次按“V”,您将获得正确呈现的控制流图

我发现的另一种方法是避免可视化模式,这对于脚本编写更可取:

  1. 像使用“f main @ 0x8470”这样的命令一样定义函数,当然,main 是函数名,0x8470 是地址。

  2. 运行命令 'af main',其中 main 是刚刚定义的函数的名称。

  3. 瞧!现在分析您新创建的函数。

我已经在我正在分析的可执行文件上尝试了这两种方法,该文件具有您所描述的相同问题,并且都提供了相同的结果。

我终于得到了我的老问题的答案!

所以,基本上 Ian Kerr 的回答大部分是正确的,只是缺少一些信息。我将尝试在此答案中收集所有内容。

假设我们正在通过一个剥离的二进制文件,没有任何符号,并且与我们一起使用radare2:

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

总而言之,您需要:

  1. 查找要添加的函数的地址。在这里,我们在 0x804876c找到了main()感谢__libc_start_main()

  2. 要设置标记为 的符号sym.以便radare2 将其识别为符号:

    f sym.main @ 0x804876c

  3. 使用 对新符号进行分析aaa

  4. 然后,将焦点切换到此符号: s sym.main

  5. 最后,您可以运行pdfVV如常。

享受!