gpt4 book ai didi

c - 无法理解汇编逻辑

转载 作者:行者123 更新时间:2023-12-04 10:15:45 26 4
gpt4 key购买 nike

我对汇编比较陌生,正在尝试理解以下汇编程序转储(这是从常见的“二进制炸弹”练习中获得的,为了更熟悉汇编,我正在尝试该练习)。基本前提是,您必须通过检查程序集和设置断点,找到成功退出程序所需的正确输入,而无需“触发炸弹”(调用explode_bomb 函数)。这是用于教授 GDB 调试和汇编语法的常见练习。

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

我将不胜感激任何帮助/建议!

更新(我不确定这是否正确):

  • 该程序采用 1 个输入参数,存储在 eax 寄存器中。如果不是 1 个参数输入,则爆炸。
  • 然后程序执行 mov 0x1c(%esp),%eax基本上是 eax = [esp + 0x1c] (这不会覆盖程序的输入吗?)
  • 然后程序执行 lea (%eax,%eax,2),%eax基本上是 eax = eax + eax * 2
  • 最后,程序确实cmp $0x52b,%eax比较 eax 中的值注册到 0x52b .

  • 0x08048bd0 <+0>:     sub    $0x2c,%esp
    0x08048bd3 <+3>: movl $0x0,0x1c(%esp)
    0x08048bdb <+11>: lea 0x1c(%esp),%eax
    0x08048bdf <+15>: mov %eax,0x8(%esp)
    0x08048be3 <+19>: movl $0x804a644,0x4(%esp)
    0x08048beb <+27>: mov 0x30(%esp),%eax
    0x08048bef <+31>: mov %eax,(%esp)
    0x08048bf2 <+34>: call 0x8048870 <__isoc99_sscanf@plt>
    0x08048bf7 <+39>: cmp $0x1,%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 $0x52b,%eax
    0x08048c0d <+61>: je 0x8048c14 <phase_1+68>
    0x08048c0f <+63>: call 0x8049363 <explode_bomb>
    0x08048c14 <+68>: add $0x2c,%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 $0x804a644,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"因为之后该值被视为整数。您可以查看地址 0x804a644 的内容与 x/s 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 .

    关于c - 无法理解汇编逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61065039/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com