这可能有一个简单的解决方案,但我在任何地方都找不到。
$> ./be1 11 AAAAA


但是,如何使用radare2做到这一点?

#1 楼

雷达2当前不标记argvargc。但是,实现起来应该并不复杂。

尽管arde2没有标记这些参数,但是通过检查寄存器可以很容易地看到它们。让我们一步一步做。

假设我们有以下程序:给它。就这么简单。

让我们在gcc中对其进行编译,并使用radare2标志以-d在调试模式下将其打开,并向其传递一个参数:

$ cat example.c

#include <stdio.h>

int main(int argc, char *argv[]) {

   printf( "argv[1]: %s\n", argv[1]);

   return 0;
}


让我们使用aa快速分析程序:

$ gcc example.c -o example.elf
$ r2 -d example.elf ABCDEFGH
Process with PID 104 started...
= attach 104 104
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
 -- Nothing to see here. Move along.
[0x7f3c8f000c30]> 


现在,让我们执行程序直到到达main()。为此,我们可以使用maindb main处设置断点,然后继续执行直到使用dc程序到达断点为止。或者,我们可以简单地使用dcu [addr] -一个非常好的命令,它将继续执行直到特定的地址。

radare2在main处停止了程序的执行。大!让我们继续打印函数:

[0x7f3c8f000c30]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)


如您所知,在GCC编译程序中,在main的条目中,edi将保存argcrsi(指针在堆栈上)将保存argv

我们可以这样打印它们的地址:因为参数是文件名和“ ABCDEFGH”,所以它是argc。指针edi0x2)的地址是argv。为了打印rsi0x7ffff02302b8)的内容,我们可以简单地使用以下命令:

[0x7f3c8f000c30]> dcu main
Continue until 0x00400526 using 1 bpsize
hit breakpoint at: 400526


* argv用于在当前块中打印字符串。由于此时我们知道rsi等于2,因此我们可以忽略输出第二行下方的任何内容。

Radee2还为您提供使用psb的寄存器伸缩。这样,您可以轻松查看argc指向的位置:

[0x00400526]> pdf
            ;-- main:
            ;-- rax:
            ;-- rip:
╭ (fcn) sym.main 51
│   sym.main ();
│           ; var int local_10h @ rbp-0x10
│           ; var int local_4h @ rbp-0x4
│           ; DATA XREF from 0x0040044d (entry0)
│           0x00400526      55             push rbp
│           0x00400527      4889e5         mov rbp, rsp
│           0x0040052a      4883ec10       sub rsp, 0x10
│           0x0040052e      897dfc         mov dword [local_4h], edi
│           0x00400531      488975f0       mov qword [local_10h], rsi
│           0x00400535      488b45f0       mov rax, qword [local_10h]
│           0x00400539      4883c008       add rax, 8
│           0x0040053d      488b00         mov rax, qword [rax]
│           0x00400540      4889c6         mov rsi, rax
│           0x00400543      bfe4054000     mov edi, str.argv_1_:__s    ; 0x4005e4 ; "argv[1]: %s\n"
│           0x00400548      b800000000     mov eax, 0
│           0x0040054d      e8aefeffff     call sym.imp.printf         ; int printf(const char *format)
│           0x00400552      b800000000     mov eax, 0
│           0x00400557      c9             leave
╰           0x00400558      c3             ret


您可以看到,drr的值是rsi,它指向堆栈上的地址(rsi)包含ascii字符串“ ./example.elf”。 0x7ffff1a56ab8是雷达的内部grep。

评论


哇,谢谢,这就是我想要的一切,还有更多。再次感谢!

– Corey
18年4月25日在16:04

#2 楼

info命令包含所有传递给radare2的参数,您也可以使用内部grep来找到它

:\>radare2 -Q -c "i~ref" -d cmdlnargs.exe firstarg secarg thirdarg
Spawned new process with pid 6032, tid = 3196
r_sys_pid_to_path: Cannot get module filename.= attach 6032 3196
bin.baddr 0x01330000
Using 0x1330000
Spawned new process with pid 872, tid = 2512
r_sys_pid_to_path: Cannot get module filename.asm.bits 32
referer  dbg://cmdlnargs.exe firstarg secarg thirdarg


在rade内部执行而不是在外壳上执行相同的命令

:\>radare2 -d cmdlnargs.exe firstarg secarg thirdarg
Spawned new process with pid 5356, tid = 2704
r_sys_pid_to_path: Cannot get module filename.= attach 5356 2704
bin.baddr 0x01330000
Using 0x1330000
Spawned new process with pid 5296, tid = 6036
r_sys_pid_to_path: Cannot get module filename.asm.bits 32
 -- Are you still there?
[0x779d70d8]> i~ref
referer  dbg://cmdlnargs.exe firstarg secarg thirdarg
[0x779d70d8]> q
Do you want to quit? (Y/n) y
Do you want to kill the process? (Y/n) y

:\>