如何使用 Radare 2 打印寄存器的值

逆向工程 二元分析 雷达2 断点 快手
2021-06-20 15:59:09

我正在尝试解决这个ELF-Ptrace 挑战我用Radare 2. 这是我执行以打印汇编代码的命令。

radare2 ch3.bin
[0x080482f0]> aaa
[[anal.jmptbl] Missing cjmp bb in predecessor at 0x08057fca
[anal.jmptbl] Missing cjmp bb in predecessor at 0x08057f4a
[anal.jmptbl] Missing cjmp bb in predecessor at 0x0808fc43
[anal.jmptbl] Missing cjmp bb in predecessor at 0x0808fc23
[anal.jmptbl] Missing cjmp bb in predecessor at 0x0808fc63
[anal.jmptbl] Missing cjmp bb in predecessor at 0x0808fc83
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (aaft)
[x] Use -AA or aaaa to perform additional experimental analysis.

[0xf7f0b049]> pd 100 @ main
            ;-- main:
/ (fcn) sym.main 175
|   int sym.main (int argc, char **argv, char **envp);
|           ; var char *s @ ebp-0x16
|           ; var int var_ch @ ebp-0xc
|           ; var int var_4h @ ebp-0x4
|           ; arg int arg_4h @ esp+0x4
|           ; DATA XREF from entry0 (0x8048307)
|           0x080483f0      8d4c2404       lea ecx, [arg_4h]           ; sym._nl_current_LC_MONETARY
|           0x080483f4      83e4f0         and esp, 0xfffffff0
|           0x080483f7      ff71fc         push dword [ecx - 4]
|           0x080483fa      55             push ebp
|           0x080483fb      89e5           mov ebp, esp
|           0x080483fd      51             push ecx
|           0x080483fe      83ec14         sub esp, 0x14
|           0x08048401      c745f488280c.  mov dword [var_ch], str.ksuiealohgy ; 0x80c2888 ; "ksuiealohgy"
|           0x08048408      6a00           push 0                      ; void*data
|           0x0804840a      6a01           push 1                      ; ecx ; void*addr
|           0x0804840c      6a00           push 0                      ; pid_t pid
|           0x0804840e      6a00           push 0                      ; __ptrace_request request
|           0x08048410      e85b060100     call sym.ptrace
|           0x08048415      83c410         add esp, 0x10
|           0x08048418      85c0           test eax, eax
|       ,=< 0x0804841a b    791a           jns 0x8048436
|       |   0x0804841c      83ec0c         sub esp, 0xc
|       |   0x0804841f      6894280c08     push str.Debugger_detect___..._Exit ; 0x80c2894 ; "Debugger detect\u00e9 ... Exit" ; const char *s
|       |   0x08048424      e8a70e0000     call sym.puts               ; int puts(const char *s)
|       |   0x08048429      83c410         add esp, 0x10
|       |   0x0804842c      b801000000     mov eax, 1
|      ,==< 0x08048431      e9c3000000     jmp loc.080484f9
|      ||   ; CODE XREF from sym.main (0x804841a)
|      |`-> 0x08048436      83ec0c         sub esp, 0xc
|      |    0x08048439      68b0280c08     push 0x80c28b0              ; const char *s
|      |    0x0804843e      e88d0e0000     call sym.puts               ; int puts(const char *s)
|      |    0x08048443      83c410         add esp, 0x10
|      |    0x08048446      83ec0c         sub esp, 0xc
|      |    0x08048449      68f0280c08     push str.Bienvennue_dans_ce_challenge_de_cracking ; 0x80c28f0 ; "##        Bienvennue dans ce challenge de cracking        ##" ; const char *s
|      |    0x0804844e      e87d0e0000     call sym.puts               ; int puts(const char *s)
|      |    0x08048453      83c410         add esp, 0x10
|      |    0x08048456      83ec0c         sub esp, 0xc
|      |    0x08048459      6830290c08     push 0x80c2930              ; const char *s
|      |    0x0804845e      e86d0e0000     call sym.puts               ; int puts(const char *s)
|      |    0x08048463      83c410         add esp, 0x10
|      |    0x08048466      b86e290c08     mov eax, str.Password_:     ; 0x80c296e ; "Password : "
|      |    0x0804846b      83ec0c         sub esp, 0xc
|      |    0x0804846e      50             push eax
|      |    0x0804846f      e8ec0a0000     call sym.__printf
|      |    0x08048474      83c410         add esp, 0x10
|      |    0x08048477      a19c540e08     mov eax, dword obj.stdin    ; obj._IO_stdin ; [0x80e549c:4]=0x80e5080 obj._IO_2_1_stdin
|      |    0x0804847c      83ec04         sub esp, 4
|      |    0x0804847f      50             push eax                    ; FILE *stream
|      |    0x08048480      6a09           push 9                      ; 9 ; int size
|      |    0x08048482      8d45ea         lea eax, [s]
|      |    0x08048485      50             push eax                    ; char *s
|      |    0x08048486      e8050b0000     call sym.fgets              ; char *fgets(char *s, int size, FILE *stream)
|      |    0x0804848b      83c410         add esp, 0x10
|      |    0x0804848e      8d0597840408   lea eax, loc._notng         ; 0x8048497
|      |    0x08048494      40             inc eax
\      |    0x08048495      ffe0           jmp eax
       |    ;-- _notng:
       |    ; DATA XREF from sym.main (0x804848e)
       |    0x08048497      b88a55ea8b     mov eax, 0x8bea558a
       |    0x0804849c      45             inc ebp
       |    0x0804849d      f4             hlt
       |    0x0804849e      83c004         add eax, 4
       |    0x080484a1      8a00           mov al, byte [eax]
       |    0x080484a3      38c2           cmp dl, al
       |,=< 0x080484a5 b    753d           jne 0x80484e4
       ||   0x080484a7      8a55eb         mov dl, byte [ebp - 0x15]
       ||   0x080484aa      8b45f4         mov eax, dword [ebp - 0xc]
       ||   0x080484ad      83c005         add eax, 5
       ||   0x080484b0      8a00           mov al, byte [eax]
       ||   0x080484b2      38c2           cmp dl, al
      ,===< 0x080484b4      752e           jne 0x80484e4
      |||   0x080484b6      8a55ec         mov dl, byte [ebp - 0x14]
      |||   0x080484b9      8b45f4         mov eax, dword [ebp - 0xc]
      |||   0x080484bc      40             inc eax
      |||   0x080484bd      8a00           mov al, byte [eax]
      |||   0x080484bf      38c2           cmp dl, al
     ,====< 0x080484c1 b    7521           jne 0x80484e4
     ||||   0x080484c3      8a55ed         mov dl, byte [ebp - 0x13]
     ||||   0x080484c6      8b45f4         mov eax, dword [ebp - 0xc]
     ||||   0x080484c9      83c00a         add eax, 0xa
     ||||   0x080484cc      8a00           mov al, byte [eax]
     ||||   0x080484ce      38c2           cmp dl, al
    ,=====< 0x080484d0 b    7512           jne 0x80484e4
    |||||   0x080484d2      83ec0c         sub esp, 0xc
    |||||   0x080484d5      687a290c08     push str.Good_password      ; 0x80c297a ; "\nGood password !!!\n"
    |||||   0x080484da      e8f10d0000     call sym.puts               ; int puts(const char *s)
    |||||   0x080484df      83c410         add esp, 0x10
   ,======< 0x080484e2      eb10           jmp 0x80484f4
   ||||||   ; CODE XREFS from loc._notng (+0xe, +0x1d, +0x2a, +0x39)
   |```-`-> 0x080484e4 b    83ec0c         sub esp, 0xc
   |   |    0x080484e7      688e290c08     push str.Wrong_password.    ; 0x80c298e ; "\nWrong password.\n"
   |   |    0x080484ec      e8df0d0000     call sym.puts               ; int puts(const char *s)
   |   |    0x080484f1      83c410         add esp, 0x10
   |   |    ; CODE XREF from loc._notng (+0x4b)
   `------> 0x080484f4      b800000000     mov eax, 0
|- loc.080484f9 8
|   loc.080484f9 ();
|      |    ; var int var_4h @ ebp-0x4
|      |    ; CODE XREF from sym.main (0x8048431)
|      `--> 0x080484f9      8b4dfc         mov ecx, dword [var_4h]
|           0x080484fc      c9             leave
|           0x080484fd      8d61fc         lea esp, [ecx - 4]
\           0x08048500      c3             ret
            0x08048501      90             nop
            0x08048502      90             nop
            0x08048503      90             nop
            0x08048504      90             nop
            0x08048505      90             nop
            0x08048506      90             nop
            0x08048507      90             nop
            0x08048508      90             nop
            0x08048509      90             nop
            0x0804850a      90             nop
            0x0804850b      90             nop

我可以看到指令中有一个反调试技术0x0804841a,我可以绕过它,放置一个断点并即时修改 eip 地址。我也可以看到打印Good Password之前有几个测试!!! 我把所有我需要的断点:

[0x00000000]> ood
[0x080482f0]> db 0x0804841a
[0x080482f0]> db 0x080484a5
[0x080482f0]> db 0x80484e4
[0x080482f0]> db 0x080484c1
[0x080482f0]> db 0x080484d0
[0x080482f0]> dc
child stopped with signal 28
[+] SIGNAL 28 errno=0 addr=0x00000000 code=128 ret=0
[0x080482f0]> dc
hit breakpoint at: 804841a
[0x0804841a]> dr eip=0x08048436
0x0804841a ->0x08048436
[0x0804841a]> dc
############################################################
##        Bienvennue dans ce challenge de cracking        ##
############################################################

Password : badpassword 
hit breakpoint at: 80484a5
[0x080484a5]> dr eip=0x080484a7
0x080484a5 ->0x080484a7
[0x080484a5]> dc
hit breakpoint at: 80484e4
[0x080484a5]> dr eip=0x080484b6
0x080484e4 ->0x080484b6
[0x080484a5]> dc
hit breakpoint at: 80484c1
[0x080484a5]> dr eip=0x080484c3
0x080484c1 ->0x080484c3
[0x080484a5]> dc
hit breakpoint at: 80484d0
[0x080484a5]> ptr axt
[0x080484a5]> dr
eax = 0x080c2879
ebx = 0x00000000
ecx = 0xffffffff
edx = 0x080e6515
esi = 0x08048bc0
edi = 0x08048b20
esp = 0xffe51480
ebp = 0xffe51498
eip = 0x080484d0
eflags = 0x00000297
oeax = 0xffffffff

现在,在这一点上(以及对于每个有条件的先前测试),我想打印堆栈或地址的值以准确查看比较的内容。我的问题是我无法理解在第一个测试中比较了什么值,例如:

   |    ; DATA XREF from sym.main (0x804848e)
   |    0x08048497      b88a55ea8b     mov eax, 0x8bea558a
   |    0x0804849c      45             inc ebp
   |    0x0804849d      f4             hlt
   |    0x0804849e      83c004         add eax, 4
   |    0x080484a1      8a00           mov al, byte [eax]
   |    0x080484a3      38c2           cmp dl, al
   |,=< 0x080484a5      753d           jne 0x80484e4

我想我用了一个糟糕的方法来解决这个挑战,因为我修改了每个 eip 最后打印出Good Password!!!,我看不到堆栈上的密码或其他东西。我使用命令pxr @ espal的内容是dl什么?

我也尝试生成源代码,Snowman但它对我没有帮助:

void fun_804849e(void** ecx) {
    signed char dl2;
    struct s2421* eax3;
    int32_t ebp4;
    int32_t ebp5;
    int32_t ebp6;
    int32_t ebp7;
    int32_t ebp8;
    int32_t ebp9;
    int32_t v10;
    int32_t v11;
    int32_t v12;
    int32_t v13;
    int32_t v14;
    int32_t v15;

    if (dl2 != eax3->f4 || (*reinterpret_cast<signed char*>(ebp4 - 21) != (*reinterpret_cast<struct s2422**>(ebp5 - 12))->f5 || (*reinterpret_cast<signed char*>(ebp6 - 20) != (*reinterpret_cast<struct s2423**>(ebp7 - 12))->f1 || *reinterpret_cast<signed char*>(ebp8 - 19) != (*reinterpret_cast<struct s2424**>(ebp9 - 12))->f10))) {
        _IO_puts(ecx, "\nWrong password.\n", v10, v11, v12, __return_address());
    } else {
        _IO_puts(ecx, "\nGood password !!!\n", v13, v14, v15, __return_address());
    }
}
1个回答

在radare2 中打印注册表值非常简单。

所有寄存器

您可以使用dr以下方法打印所有通用寄存器

[0x55bea3305070]> dr
rax = 0x55bea3305070
rbx = 0x00000000
rcx = 0x7fd7ee4f7578
rdx = 0x7ffd63b54428
r8 = 0x7fd7ee4f8be0
r9 = 0x7fd7ee4f8be0
r10 = 0x00000001
r11 = 0x00000000
r12 = 0x55bea3306ae0
r13 = 0x7ffd63b54410
r14 = 0x00000000
r15 = 0x00000000
rsi = 0x7ffd63b54418
rdi = 0x00000001
rsp = 0x7ffd63b54338
rbp = 0x55bea33176f0
rip = 0x55bea3305070
rflags = 0x00000246
orax = 0xffffffffffffffff

伸缩

您可以获得更多信息,使用drrwhich 还将对寄存器执行伸缩:

[0x55bea3305070]> drr
   rax 0x55bea3305070      (.text) (/usr/bin/ls) rip program R X 'push r15' 'ls'
   rbx 0x0                 r15
   rcx 0x7fd7ee4f7578      (/usr/lib/libc-2.28.so) rcx library R W 0x7fd7ee4f8be0 -->  (/usr/lib/libc-2.28.so) r9 library R W 0x0 -->  r15
   rdx 0x7ffd63b54428      rdx stack R W 0x7ffd63b54b6d -->  stack R W 0x622f3d4c4c454853 (SHELL=/bin/bash) -->  ascii
    r8 0x7fd7ee4f8be0      (/usr/lib/libc-2.28.so) r9 library R W 0x0 -->  r15
    r9 0x7fd7ee4f8be0      (/usr/lib/libc-2.28.so) r9 library R W 0x0 -->  r15
   r10 0x1                 rdi
   r11 0x0                 r15
   r12 0x55bea3306ae0      (.text) (/usr/bin/ls) r12 program R X 'endbr64' 'ls'
   r13 0x7ffd63b54410      r13 stack R W 0x1 -->  rdi
   r14 0x0                 r15
   r15 0x0                 r15
   rsi 0x7ffd63b54418      rsi stack R W 0x7ffd63b54b65 -->  stack R W 0x736c2f6e69622f (/bin/ls) -->  ascii
   rdi 0x1                 rdi
   rsp 0x7ffd63b54338      rsp stack R W 0x7fd7ee35d223 -->  (/usr/lib/libc-2.28.so) library R X 'mov edi, eax' 'libc-2.28.so'
   rbp 0x55bea33176f0      (.text) (/usr/bin/ls) rbp program R X 'endbr64' 'ls'
   rip 0x55bea3305070      (.text) (/usr/bin/ls) rip program R X 'push r15' 'ls'
    cs 0x33                ascii
rflags 1PZI                rflags
  orax 0xffffffffffffffff  orax
    ss 0x2b                ascii
fs_base 0x7fd7ee336740      (unk1) R W 0x7fd7ee336740
gs_base 0x0                 r15
    ds 0x0                 r15
    es 0x0                 r15
    fs 0x0                 r15
    gs 0x0                 r15

特定的寄存器

您可以使用 打印特定的寄存器dr <reg>

[0x55bea3305070]> dr rax
0x55bea3305070

寄存器aldl分别是寄存器 EAX 和 EDX 的低 8 位。

[0x55bea3305070]> dr rax
0x55bea3305070
[0x55bea3305070]> dr eax
0xa3305070
[0x55bea3305070]> dr al
0x00000070



[0x55bea3305070]> dr rdx
0x7ffd63b54428
[0x55bea3305070]> dr edx
0x63b54428
[0x55bea3305070]> dr dl
0x00000028

进一步阅读

我建议阅读radare2book,更具体地说,是关于Registers章节