这个文件的密码是什么?我无法用radare2或gdb弄明白

逆向工程 拆卸 x86 反编译
2021-06-27 11:42:22

这是二进制文件。https://drive.google.com/file/d/1ywN60yZYIhPPRyZMGbQudZRYoLYBhkeJ/view?usp=sharing

我能够找出一些程序集,但无法获得正确的密码。我知道它是由空格分隔的两个整数。

编辑:通过使用该命令,ps @ str.d__d您将获得%d %d. 它位于地址0x0804853f

EDIT2:我发现使用了多个局部变量:

var int local_2ch @ ebp-0x2c 
var int local_20h @ ebp-0x20 
var int local_1ch @ ebp-0x1c 
var unsigned int local_18h @ ebp-0x18 
var int local_14h @ ebp-0x14 
var int local_10h @ ebp-0x10
var int canary @ ebp-0xc
var int local_4h @ ebp-0x4 
arg int arg_4h @ esp+0x4 
1个回答

这是您如何做到的。常见的东西:r2 file; aaa; pdf@sym.main

您可以看到要scanf推送到堆栈的参数

|           0x08048537      8d45e4         lea eax, [local_1ch]
|           0x0804853a      50             push eax
|           0x0804853b      8d45e0         lea eax, [local_20h]
|           0x0804853e      50             push eax
|           0x0804853f      6855860408     push str.d__d               ; 0x8048655 ; "%d %d" ; const char *format
|           0x08048544      e887feffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)

让我们重命名当地人。

[0x080484eb]> afv?
Usage: afv  [rbs]
| afvr[?]                       manipulate register based arguments
| afvb[?]                       manipulate bp based arguments/locals
| afvs[?]                       manipulate sp based arguments/locals
| afv*                          output r2 command to add args/locals to flagspace
| afvR [varname]                list addresses where vars are accessed (READ)
| afvW [varname]                list addresses where vars are accessed (WRITE)
| afva                          analyze function arguments/locals
| afvd name                     output r2 command for displaying the value of args/locals in the debugger
| afvn [new_name] ([old_name])  rename argument/local
| afvt [name] [new_type]        change type for given argument/local
| afv-([name])                  remove all or given var

[0x080484eb]> afvn input_1 local_20h
[0x080484eb]> afvn input_2 local_1ch
[0x080484eb]> pdf@sym.main

现在看起来像

|           0x08048537      8d45e4         lea eax, [input_2]
|           0x0804853a      50             push eax
|           0x0804853b      8d45e0         lea eax, [input_1]
|           0x0804853e      50             push eax
|           0x0804853f      6855860408     push str.d__d               ; 0x8048655 ; "%d %d" ; const char *format
|           0x08048544      e887feffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)

有一个正确/不正确的检查

|       `-> 0x08048579      837de800       cmp dword [local_18h], 0
|       ,=< 0x0804857d      7412           je 0x8048591
|       |   0x0804857f      83ec0c         sub esp, 0xc
|       |   0x08048582      685b860408     push str.Correct            ; 0x804865b ; "Correct!" ; const char *s
|       |   0x08048587      e824feffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x0804858c      83c410         add esp, 0x10
|      ,==< 0x0804858f      eb10           jmp 0x80485a1
|      ||   ; CODE XREF from main (0x804857d)
|      |`-> 0x08048591      83ec0c         sub esp, 0xc
|      |    0x08048594      6864860408     push str.Incorrect          ; 0x8048664 ; "Incorrect!" ; const char *s
|      |    0x08048599      e812feffff     call sym.imp.puts           ; int puts(const char *s)
|      |    0x0804859e      83c410         add esp, 0x10

如果local_18h是 1/0,则将正确/不正确分别打印到标准输出。重命名local_18h为,final_flag因为它决定了最终输出。

[0x0804852b]> afvn final_flag local_18h

一些常量被加载到局部变量中。记住/重命名它们以在代码中遵循。

|           0x0804850f      c745e8010000.  mov dword [final_flag], 1
|           0x08048516      c745ec2a0000.  mov dword [local_14h], 0x2a ; '*' ; 42
|           0x0804851d      c745f0390500.  mov dword [local_10h], 0x539 ; 1337

final_flag最初为 1(真)。就在输入之后,有一个检查设置final_flag为 0(false)。

|           0x0804854c      8b45ec         mov eax, dword [const_2a]
|           0x0804854f      35280a0000     xor eax, 0xa28
|           0x08048554      89c2           mov edx, eax
|           0x08048556      8b45e0         mov eax, dword [input_1]
|           0x08048559      39c2           cmp edx, eax
|       ,=< 0x0804855b      7407           je 0x8048564
|       |   0x0804855d      c745e8000000.  mov dword [final_flag], 0
|       |   ; CODE XREF from main (0x804855b)

这可以大致翻译为:

if const_2a^0xa28 != input_1:
    final_flag = False

传递这个 input_1 = const_2a^0xa28

>>> 0x2a^0xa28
2562

input_2 的类似检查

|       `-> 0x08048564      8b45f0         mov eax, dword [const_539]
|           0x08048567      f7d0           not eax
|           0x08048569      89c2           mov edx, eax
|           0x0804856b      8b45e4         mov eax, dword [input_2]
|           0x0804856e      39c2           cmp edx, eax
|       ,=< 0x08048570      7407           je 0x8048579
|       |   0x08048572      c745e8000000.  mov dword [final_flag], 0

这可以大致翻译为:

if ~const_539 != input_2:
    final_flag = False

传递这个 input_2 = ~const_539

>>> ~0x539
-1338

最后

./part2
Enter the password: 2562 -1338
Correct!