phase_6:链表/指针/结构
先贴代码,这一关代码又臭又长。
000016e6 <phase_6>:
16e6: 55 push %ebp
16e7: 89 e5 mov %esp,%ebp
16e9: 57 push %edi
16ea: 56 push %esi
16eb: 53 push %ebx
16ec: 83 ec 54 sub $0x54,%esp
16ef: e8 1c fb ff ff call 1210 <__x86.get_pc_thunk.bx>
16f4: 81 c3 0c 39 00 00 add $0x390c,%ebx
16fa: 8d 45 d0 lea -0x30(%ebp),%eax
16fd: 50 push %eax
16fe: ff 75 08 pushl 0x8(%ebp)
1701: e8 bb 04 00 00 call 1bc1 <read_six_numbers>
1706: 8d 45 d4 lea -0x2c(%ebp),%eax
1709: 89 45 ac mov %eax,-0x54(%ebp)
170c: 83 c4 10 add $0x10,%esp
170f: c7 45 b0 00 00 00 00 movl $0x0,-0x50(%ebp)
1716: 8d 45 e8 lea -0x18(%ebp),%eax
1719: 89 45 b4 mov %eax,-0x4c(%ebp)
171c: eb 21 jmp 173f <phase_6+0x59>
171e: e8 4c 04 00 00 call 1b6f <explode_bomb>
1723: eb 2d jmp 1752 <phase_6+0x6c>
1725: 83 c6 04 add $0x4,%esi
1728: 39 75 b4 cmp %esi,-0x4c(%ebp)
172b: 74 0e je 173b <phase_6+0x55>
172d: 8b 06 mov (%esi),%eax
172f: 39 47 fc cmp %eax,-0x4(%edi)
1732: 75 f1 jne 1725 <phase_6+0x3f>
1734: e8 36 04 00 00 call 1b6f <explode_bomb>
1739: eb ea jmp 1725 <phase_6+0x3f>
173b: 83 45 ac 04 addl $0x4,-0x54(%ebp) #猜测我们输入的数在这里存放
173f: 8b 45 ac mov -0x54(%ebp),%eax
1742: 89 c7 mov %eax,%edi
1744: 8b 40 fc mov -0x4(%eax),%eax
1747: 89 45 a8 mov %eax,-0x58(%ebp)
174a: 83 e8 01 sub $0x1,%eax
174d: 83 f8 05 cmp $0x5,%eax
1750: 77 cc ja 171e <phase_6+0x38>
1752: 83 45 b0 01 addl $0x1,-0x50(%ebp)
1756: 8b 45 b0 mov -0x50(%ebp),%eax
1759: 83 f8 05 cmp $0x5,%eax
175c: 7f 05 jg 1763 <phase_6+0x7d>
175e: 8b 75 ac mov -0x54(%ebp),%esi
1761: eb ca jmp 172d <phase_6+0x47>
1763: be 00 00 00 00 mov $0x0,%esi
1768: 89 f7 mov %esi,%edi
176a: 8b 4c b5 d0 mov -0x30(%ebp,%esi,4),%ecx
176e: b8 01 00 00 00 mov $0x1,%eax
1773: 8d 93 78 05 00 00 lea 0x578(%ebx),%edx #猜测这里面是链表的表头
1779: 83 f9 01 cmp $0x1,%ecx
177c: 7e 0a jle 1788 <phase_6+0xa2>
177e: 8b 52 08 mov 0x8(%edx),%edx
1781: 83 c0 01 add $0x1,%eax
1784: 39 c8 cmp %ecx,%eax
1786: 75 f6 jne 177e <phase_6+0x98>
1788: 89 54 bd b8 mov %edx,-0x48(%ebp,%edi,4)
178c: 83 c6 01 add $0x1,%esi
178f: 83 fe 06 cmp $0x6,%esi
1792: 75 d4 jne 1768 <phase_6+0x82>
1794: 8b 75 b8 mov -0x48(%ebp),%esi
1797: 8b 45 bc mov -0x44(%ebp),%eax
179a: 89 46 08 mov %eax,0x8(%esi)
179d: 8b 55 c0 mov -0x40(%ebp),%edx
17a0: 89 50 08 mov %edx,0x8(%eax)
17a3: 8b 45 c4 mov -0x3c(%ebp),%eax
17a6: 89 42 08 mov %eax,0x8(%edx)
17a9: 8b 55 c8 mov -0x38(%ebp),%edx
17ac: 89 50 08 mov %edx,0x8(%eax)
17af: 8b 45 cc mov -0x34(%ebp),%eax
17b2: 89 42 08 mov %eax,0x8(%edx)
17b5: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax)
17bc: bf 05 00 00 00 mov $0x5,%edi
17c1: eb 08 jmp 17cb <phase_6+0xe5>
17c3: 8b 76 08 mov 0x8(%esi),%esi
17c6: 83 ef 01 sub $0x1,%edi
17c9: 74 10 je 17db <phase_6+0xf5>
17cb: 8b 46 08 mov 0x8(%esi),%eax
17ce: 8b 00 mov (%eax),%eax
17d0: 39 06 cmp %eax,(%esi)
17d2: 7d ef jge 17c3 <phase_6+0xdd>
17d4: e8 96 03 00 00 call 1b6f <explode_bomb>
17d9: eb e8 jmp 17c3 <phase_6+0xdd>
17db: 8d 65 f4 lea -0xc(%ebp),%esp
17de: 5b pop %ebx
17df: 5e pop %esi
17e0: 5f pop %edi
17e1: 5d pop %ebp
17e2: c3 ret
通关操作如下
下面这段代码说明要输入六个数。我们先输入1 2 3 4 5 6
试试。
1701: e8 bb 04 00 00 call 1bc1 <read_six_numbers>
逐步调试程序,发现一处循环:
1768: 89 f7 mov %esi,%edi
176a: 8b 4c b5 d0 mov -0x30(%ebp,%esi,4),%ecx
176e: b8 01 00 00 00 mov $0x1,%eax
1773: 8d 93 78 05 00 00 lea 0x578(%ebx),%edx
1779: 83 f9 01 cmp $0x1,%ecx
177c: 7e 0a jle 1788 <phase_6+0xa2>
177e: 8b 52 08 mov 0x8(%edx),%edx
1781: 83 c0 01 add $0x1,%eax
1784: 39 c8 cmp %ecx,%eax
1786: 75 f6 jne 177e <phase_6+0x98>
1788: 89 54 bd b8 mov %edx,-0x48(%ebp,%edi,4) #对输入的内容进行改变
178c: 83 c6 01 add $0x1,%esi
178f: 83 fe 06 cmp $0x6,%esi
1792: 75 d4 jne 1768 <phase_6+0x82>
对可能是链表所在处进行调试,0x80005000即ebx内存放的地址。
可以看到,只有5个节点,害得我好找一番,少的那个还是头指针。
可以看到,node6和其它几个节点离得还挺远的。
这是我输入的6个数在循环前的状态,0xbfffef28是ebp中存放的地址。
这是循环后的状态:
可以推测地址与输入内容的对应关系:
265 : 6
36d : 1
34c : 5
27a : 4
1ef : 2
29c : 3
根据地址排序,36d(1)>34c(5)>29c(3)>27a(4)>265(6)>1ef(2),猜测输入的顺序应该是1 5 3 4 6 2
。
验证猜测,很幸运,猜对了,通关!