rackme 反汇编 - 这些局部变量是否初始化过?

逆向工程 拆卸 调试 雷达2 快手
2021-06-29 11:26:18

我正在开发一个crackme,目标是找到给定程序的有效密码。我正在使用radare2 对程序进行逆向工程。为此,我需要输入一个密码,强制该程序绕过所有条件跳转(jne's, jle's, jg's )。

到目前为止,我只得出结论,密码必须是 4 个字符长,最低 8 位是 0x79,或 ASCII 字符“y”(如果我错了,请纠正我)。下面给出了前 N 个反汇编字节(直到我卡住了):

root@kali:~/Exploit_Class_NSL/Week1/Exercise4# r2 -AAAA example4 
[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] Enable constraint types analysis for variables
[0x00401080]> pdf @main
            ;-- main:
/ (fcn) sym.main 201
|   sym.main (int argc, char **argv, char **envp);
|           ; var int local_20h @ rbp-0x20
|           ; var int local_14h @ rbp-0x14
|           ; var int local_5h @ rbp-0x5
|           ; var int local_4h @ rbp-0x4
|           ; var int local_3h @ rbp-0x3
|           ; var int local_2h @ rbp-0x2
|           ; arg int argc @ rdi
|           ; arg char **argv @ rsi
|           ; DATA XREF from entry0 (0x40109d)
|           0x00401162      55             push rbp
|           0x00401163      4889e5         mov rbp, rsp
|           0x00401166      4883ec20       sub rsp, 0x20
|           0x0040116a      897dec         mov dword [local_14h], edi  ; argc
|           0x0040116d      488975e0       mov qword [local_20h], rsi  ; argv
|           0x00401171      488d3d8c0e00.  lea rdi, qword str.enter_the_password: ; 0x402004 ; "enter the password: "
|           0x00401178      b800000000     mov eax, 0
|           0x0040117d      e8cefeffff     call sym.imp.printf         ; int printf(const char *format)
|           0x00401182      488b15c72e00.  mov rdx, qword [obj.stdin__GLIBC_2.2.5] ; obj.__TMC_END ; [0x404050:8]=0
|           0x00401189      488d45fb       lea rax, qword [local_5h]
|           0x0040118d      be05000000     mov esi, 5
|           0x00401192      4889c7         mov rdi, rax
|           0x00401195      e8c6feffff     call sym.imp.fgets          ; char *fgets(char *s, int size, FILE *stream)
|           0x0040119a      488d45fb       lea rax, qword [local_5h]
|           0x0040119e      4889c7         mov rdi, rax
|           0x004011a1      e89afeffff     call sym.imp.strlen         ; size_t strlen(const char *s)
|           0x004011a6      4883f804       cmp rax, 4                  ; 4
|       ,=< 0x004011aa      7559           jne 0x401205
|       |   0x004011ac      0fb645fb       movzx eax, byte [local_5h]
|       |   0x004011b0      3c79           cmp al, 0x79                ; 'y' ; 121
|      ,==< 0x004011b2      7554           jne 0x401208
|      ||   0x004011b4      0fb645fc       movzx eax, byte [local_4h]
|      ||   0x004011b8      0fbed0         movsx edx, al
|      ||   0x004011bb      0fb645fd       movzx eax, byte [local_3h]
|      ||   0x004011bf      0fbec0         movsx eax, al
|      ||   0x004011c2      01d0           add eax, edx
|      ||   0x004011c4      3dda000000     cmp eax, 0xda               ; 218
|     ,===< 0x004011c9      7540           jne 0x40120b
|     |||   0x004011cb      0fb645fd       movzx eax, byte [local_3h]
|     |||   0x004011cf      3c6c           cmp al, 0x6c                ; 'l' ; 108
|    ,====< 0x004011d1      7e3b           jle 0x40120e

在 0x004011b4 是我开始卡住的地方。

|      ||   0x004011b4      0fb645fc       movzx eax, byte [local_4h]
|      ||   0x004011b8      0fbed0         movsx edx, al
|      ||   0x004011bb      0fb645fd       movzx eax, byte [local_3h]
|      ||   0x004011bf      0fbec0         movsx eax, al
|      ||   0x004011c2      01d0           add eax, edx
|      ||   0x004011c4      3dda000000     cmp eax, 0xda               ; 218
|     ,===< 0x004011c9      7540           jne 0x40120b

是局部变量local_3hlocal_4h以往任何时候都初始化?如果是这样,如何?应该如何自行解决这个问题?

我试着玩弄各地具有不同功能的R2一样afvde [ ]等,但还没有得到任何地方呢。

任何提示表示赞赏。谢谢!

2个回答

是的,它们被初始化,尽管是间接的。

看看这个片段:

   0x00401189      488d45fb       lea rax, qword [local_5h]
   0x0040118d      be05000000     mov esi, 5
   0x00401192      4889c7         mov rdi, rax
   0x00401195      e8c6feffff     call sym.imp.fgets ; char *fgets(char *s, int size, FILE *stream)

这里我们调用fgets函数,将local_5has的地址s和值 5 as传递给它size这意味着最多可以将 5 个字节(包括终止零)读入从 开始的内存local_5h,即local_4hlocal_3h是检索到的字符串的第二个和第三个字符。

我会说它们是在局部作用域的堆栈上初始化的,作为函数的局部变量。我的想法是查看存储在本地堆栈上的数据。我不确定这是否是您正在寻找的答案。我希望这有帮助。