阅读汇编代码(炸弹实验室第 5 阶段帮助)

Reading Assembly Code (Bomb lab phase 5 help)

我必须为炸弹实验室解码这个汇编语言:

Dump of assembler code for function phase_5:
0x08048e79 <+0>:    push   %ebx
0x08048e7a <+1>:    sub    [=10=]x28,%esp
0x08048e7d <+4>:    lea    0x1c(%esp),%eax
0x08048e81 <+8>:    mov    %eax,0xc(%esp)
0x08048e85 <+12>:   lea    0x18(%esp),%eax
0x08048e89 <+16>:   mov    %eax,0x8(%esp)
0x08048e8d <+20>:   movl   [=10=]x804a9de,0x4(%esp)
0x08048e95 <+28>:   mov    0x30(%esp),%eax
0x08048e99 <+32>:   mov    %eax,(%esp)
0x08048e9c <+35>:   call   0x8048940 <__isoc99_sscanf@plt>
0x08048ea1 <+40>:   cmp    [=10=]x1,%eax
0x08048ea4 <+43>:   jg     0x8048eab <phase_5+50>
0x08048ea6 <+45>:   call   0x804961b <explode_bomb>
0x08048eab <+50>:   mov    0x18(%esp),%eax
0x08048eaf <+54>:   mov    %eax,%edx
0x08048eb1 <+56>:   and    [=10=]xf,%edx
0x08048eb4 <+59>:   cmp    %edx,%eax
0x08048eb6 <+61>:   je     0x8048ebd <phase_5+68>
0x08048eb8 <+63>:   call   0x804961b <explode_bomb>
0x08048ebd <+68>:   mov    0x18(%esp),%ebx
0x08048ec1 <+72>:   mov    %ebx,%eax
0x08048ec3 <+74>:   mov    [=10=]x0,%ecx
0x08048ec8 <+79>:   mov    [=10=]x0,%edx
0x08048ecd <+84>:   add    [=10=]x1,%edx
0x08048ed0 <+87>:   add    %eax,%ecx
0x08048ed2 <+89>:   mov    0x804a700(,%eax,4),%eax
0x08048ed9 <+96>:   cmp    %eax,%ebx
0x08048edb <+98>:   jne    0x8048ecd <phase_5+84>
0x08048edd <+100>:  cmp    0x1c(%esp),%edx
0x08048ee1 <+104>:  jne    0x8048ee8 <phase_5+111>
0x08048ee3 <+106>:  cmp    [=10=]x41,%ecx
0x08048ee6 <+109>:  je     0x8048eed <phase_5+116>
0x08048ee8 <+111>:  call   0x804961b <explode_bomb>
0x08048eed <+116>:  add    [=10=]x28,%esp
0x08048ef0 <+119>:  pop    %ebx
0x08048ef1 <+120>:  ret

我知道直到 +68,它基本上检查我输入的字符串中是否至少有 2 个整数。

退出循环后,edx 必须为 4(+100 时我看到 0x1c(%esp) = 4)并且 ecx 必须为 65(+106 时为 0x41)。有人可以帮我弄清楚发生了什么以及我需要输入什么吗?

***编辑 4/18(数组内容): 它在 %eax = 24 之后变为 0,所以我想我已经结束了。从 eax = 5 开始并遍历 7 次到 eax = 11 时,%ecx 将 = 65 但是当我输入“5 7”时它不起作用:(

%eax=0: 0x00000014 
1:  0x00000008
2:  0x00000010
3:  0x00000018
4:  0x00000005
5:  0x0000000a
6:  0x0000000e
7:  0x0000000d
8:  0x00000000
9:  0x00000004
10: 0x00000016
11: 0x00000002
12: 0x00000013
13: 0x00000017
14: 0x00000012
15: 0x00000015
16: 0x0000000f
17: 0x0000000c
18: 0x00000006
19: 0x00000011
20: 0x00000001
21: 0x0000000b
22: 0x00000009
23: 0x00000003
24: 0x00000007
25: 0x00000000
26: 0x00000000
27: 0x00000000
28: 0x00000000
29: 0x00000000...

首先,您显然在 0x18(%esp)0x1c(%esp) 处有两个输入整数。因此,只有当您输入 4 作为第二个数字时,您的 "edx must be 4" 声明才有效。一般来说,检查是 edx 必须等于第二个数字。

该代码在地址 0x804a700 处有一个链表,从第一个输入数字给出的索引开始遍历该链表。如果找到第一个输入给出的值,则循环退出。 edx 用于跟踪迭代次数,这就是应该与第二个数字匹配的内容。

ecx用于跟踪搜索过程中遇到的所有值的总和,最后应该是0x41

因此,您需要确定链表的哪一部分给出 0x41 作为总和,并输入其起点和长度作为两个输入。


记住退出条件是找到第一个数字。从 5 开始将进入 0->20->1->8->0... 的循环,因此它永远不会退出。 顺便说一句,这意味着您也不能从 018 开始。所以让我们尝试 2: 2 + 16 + 15 + 21 + 11 = 65 然后我们回到 2 这样循环就退出了。是的,这就是我们的解决方案:2 5.