难以理解汇编逻辑

mlz7

我对汇编语言比较陌生,正在尝试了解以下汇编程序转储(这是我为了使大家对汇编更加熟悉而尝试的“二进制炸弹”练习)。基本前提是您必须通过检查程序集和设置断点来找到成功退出程序所需的正确输入,而无需“触发炸弹”(调用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,%eaxeax寄存器中的值与进行比较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调用约定在堆栈上传递参数(有关更多信息,请参见此Wiki页面)。

您的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"因为此后该值被视为整数。您可以检查地址处的内容0x804a644x/s 0x804a644以确切了解格式字符串是什么(并了解正在读取的变量的类型)。

之后,这两个指令:

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

从堆栈中获取扫描值到中eax,然后乘以3lea最后得到eax = eax*2 + eax)。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章