我正在研究二元炸弹项目。我正在研究这段代码,我正在尝试理解汇编代码的一部分。所以我很容易通过phase1,而对于第2阶段,我需要输入4个字符。
例如:phase-2: x y z d
在下面的示例中,我使用输入: a b c d 作为我的四个字符
当我在gdp中运行它并检查汇编代码时,我得到以下内容:
Dump of assembler code for function phase2:
0x080487d6 <+0>: push %ebp
0x080487d7 <+1>: mov %esp,%ebp
0x080487d9 <+3>: sub $0xc,%esp
=> 0x080487dc <+6>: mov 0x8(%ebp),%ecx
0x080487df <+9>: mov 0xc(%ebp),%edx
0x080487e2 <+12>: mov 0x10(%ebp),%eax
0x080487e5 <+15>: mov %cl,-0x4(%ebp)
0x080487e8 <+18>: mov %dl,-0x8(%ebp)
0x080487eb <+21>: mov %al,-0xc(%ebp)
0x080487ee <+24>: cmpb $0x77,-0x4(%ebp)
0x080487f2 <+28>: jne 0x8048807 <phase2+49>
0x080487f4 <+30>: cmpb $0x62,-0x8(%ebp)
0x080487f8 <+34>: jne 0x8048807 <phase2+49>
0x080487fa <+36>: cmpb $0x79,-0xc(%ebp)
0x080487fe <+40>: jne 0x8048807 <phase2+49>
0x08048800 <+42>: mov $0x1,%eax
0x08048805 <+47>: jmp 0x804880c <phase2+54>
0x08048807 <+49>: mov $0x0,%eax
0x0804880c <+54>: leave
0x0804880d <+55>: ret
End of assembler dump.
我真正理解的是
0x080487ee <+24>: cmpb $0x77,-0x4(%ebp)
这里发生了什么?我认为它将值$ 0x77与ebp中的值进行比较。那有意义吗?我怎么知道ebp中存储了什么?
我运行代码直到上面一行,ebp和我得到以下内容:
ebp 0xbffff6e8 0xbffff6e8
总而言之,我想知道比较行的确在做什么,这样我才能更好地理解代码。如何在不进入离开状态的情况下找出ebp中的值。
答案 0 :(得分:1)
%ebp
通常用作堆栈帧指针 - -0x4
是与%ebp
中存储的地址的偏移量 - 以及下面的值(负偏移量)%ebp
通常是局部变量(如果从C代码编译),上面的值(正偏移)通常是函数参数。此代码似乎是通过编译C代码生成的代码,%ebp
用法是典型的。 -0x4(%ebp)
将引用函数的第一个局部变量。似乎早先已经使用mov %cl,-0x4(%ebp)
设置了一些语句。这提出了%cl
值中的值来自哪里的问题,如果我们追溯到后面,我们可以看到mov 0x8(%ebp),%cx
设置为%cl
。请注意,cmpb
指令具有b
前缀,这意味着它是字节比较。 (与16位或32位比较相反。)这与仅使用%cl
设置的值的观察相匹配,这也是一个8位值。
所有这些都告诉我们,您要问的行是与十六进制值0x77进行8位比较。如果你看一个ASCII表,你可以看到0x77是小写&#39; w&#39;。如果字节不等于该值,则下一条指令跳转。这使我得出结论,我们正在检查传递给函数的第一个参数,看它是否是一个&#39; w&#39;字符。
答案 1 :(得分:0)
据我所知,这种炸弹通常是给学生的。我觉得你缺少应该学习的基本知识。你应该重温你所拥有的任何课程资料。
无论如何,一些快速提示:
x(%ebp)
是间接寻址,它访问地址x+%ebp
+1
%ebp
,saved ebp
,return address
,arg1
,arg2
arg3
行之后堆叠内容
+6
将8(%ebp)
(这是第一个参数)加载到%ecx
。+15
然后将其低8位保存到-4(%ebp)
的本地变量中。+24
然后将此值与0x77
进行比较。请注意,您声称需要4个号码。虽然在调用者中可能是这样,但phase2
只使用3个参数。