阅读汇编代码(炸弹实验室第 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...
的循环,因此它永远不会退出。
顺便说一句,这意味着您也不能从 0
、1
或 8
开始。所以让我们尝试 2
: 2 + 16 + 15 + 21 + 11 = 65
然后我们回到 2
这样循环就退出了。是的,这就是我们的解决方案:2 5
.
我必须为炸弹实验室解码这个汇编语言:
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...
的循环,因此它永远不会退出。
顺便说一句,这意味着您也不能从 0
、1
或 8
开始。所以让我们尝试 2
: 2 + 16 + 15 + 21 + 11 = 65
然后我们回到 2
这样循环就退出了。是的,这就是我们的解决方案:2 5
.