难以理解汇编逻辑

Trouble understanding assembly logic

我对汇编比较陌生,正在尝试理解以下汇编程序转储(这是来自我正在尝试的常见 'binary bomb' 练习,以便更熟悉汇编)。基本前提是您必须通过检查程序集和设置断点来找到在没有 "triggering the bomb"(调用 explode_bomb 函数)的情况下成功退出程序所需的正确输入。这是用于教授 GDB 调试和汇编语法的常见练习。

据我了解,该程序首先使用 scanf 检查字符串输入并检查是否提供了 1 个参数。在设置断点并检查 eax 寄存器的值后,我能够看到我输入的输入值,所以我似乎应该寻找它与其他东西进行比较。然后程序移动一些东西并将 eax 寄存器的值与二进制值 0x52b = 1323 进行比较。但是,我尝试使用这个值作为我的输入但它不起作用所以我想知道我是否误解了背后的逻辑这个程序。

我将不胜感激 help/advise!

已更新(不知是否正确):

0x08048bd0 <+0>:     sub    [=10=]x2c,%esp
0x08048bd3 <+3>:     movl   [=10=]x0,0x1c(%esp)
0x08048bdb <+11>:    lea    0x1c(%esp),%eax
0x08048bdf <+15>:    mov    %eax,0x8(%esp)
0x08048be3 <+19>:    movl   [=10=]x804a644,0x4(%esp)
0x08048beb <+27>:    mov    0x30(%esp),%eax
0x08048bef <+31>:    mov    %eax,(%esp)
0x08048bf2 <+34>:    call   0x8048870 <__isoc99_sscanf@plt>
0x08048bf7 <+39>:    cmp    [=10=]x1,%eax
0x08048bfa <+42>:    je     0x8048c01 <phase_1+49>
0x08048bfc <+44>:    call   0x8049363 <explode_bomb>
0x08048c01 <+49>:    mov    0x1c(%esp),%eax
0x08048c05 <+53>:    lea    (%eax,%eax,2),%eax
0x08048c08 <+56>:    cmp    [=10=]x52b,%eax
0x08048c0d <+61>:    je     0x8048c14 <phase_1+68>
0x08048c0f <+63>:    call   0x8049363 <explode_bomb>
0x08048c14 <+68>:    add    [=10=]x2c,%esp
0x08048c17 <+71>:    ret  

在 x86 32 位中,参数根据 IA32 cdecl 调用约定在堆栈上传递(有关详细信息,请参阅 this wiki page)。

您的 phase_1 函数正在调用 sscanf(),在此处传递参数:

0x08048bdb <+11>:    lea    0x1c(%esp),%eax
0x08048bdf <+15>:    mov    %eax,0x8(%esp)
0x08048be3 <+19>:    movl   [=10=]x804a644,0x4(%esp)
0x08048beb <+27>:    mov    0x30(%esp),%eax
0x08048bef <+31>:    mov    %eax,(%esp)

简而言之,就是:

sscanf(esp + 0x30, 0x804a644, esp + 0x1c);

应该是这样的:

int var_on_stack;
sscanf(user_input, "%d", &var_on_stack); 
// user_input starts at esp + 0x30
// &var_on_stack == esp + 0x1c

第一个参数 (user_input) 可能作为参数传递给 phase_1 函数,它可能包含之前读取的数据。

0x804a644 是传递给 scanf() 的格式字符串的地址,我假设它类似于 "%d",因为此后该值被视为整数。您可以使用 x/s 0x804a644 检查地址 0x804a644 处的内容,以准确查看格式字符串的内容(并了解正在读取的变量的类型)。

之后,这两条指令:

0x08048c01 <+49>:    mov    0x1c(%esp),%eax
0x08048c05 <+53>:    lea    (%eax,%eax,2),%eax

从栈中取出扫描值放入eax,然后乘以3(即lea最后做eax = eax*2 + eax)。

完成后,将值与 0x52b 进行比较。因此需要输入0x52b/3,也就是1323/3,也就是441.