Tan's Blog.

Challenge:Phase6

字数统计: 1k阅读时长: 5 min
2019/04/20 Share

Phase 6

解题思路

1
2
3
4
5
6
7
8
8048db4:	56                   	push   %esi
8048db5: 53 push %ebx
8048db6: 83 ec 44 sub $0x44,%esp
8048db9: 8d 44 24 10 lea 0x10(%esp),%eax
8048dbd: 89 44 24 04 mov %eax,0x4(%esp)
8048dc1: 8b 44 24 50 mov 0x50(%esp),%eax
8048dc5: 89 04 24 mov %eax,(%esp)
8048dc8: e8 4f 03 00 00 call 804911c <read_six_numbers>

前面部分和之前几题都一样,初始化栈操作。到8048dc8处,调用了<read_six_numbers>函数,推断此题需要输入六个数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
8048dcd:	be 00 00 00 00       	mov    $0x0,%esi
8048dd2: 8b 44 b4 10 mov 0x10(%esp,%esi,4),%eax
8048dd6: 83 e8 01 sub $0x1,%eax
8048dd9: 83 f8 05 cmp $0x5,%eax
8048ddc: 76 05 jbe 8048de3 <phase_6+0x2f>
8048dde: e8 12 03 00 00 call 80490f5 <explode_bomb>
8048de3: 83 c6 01 add $0x1,%esi
8048de6: 83 fe 06 cmp $0x6,%esi
8048de9: 75 07 jne 8048df2 <phase_6+0x3e>
8048deb: bb 00 00 00 00 mov $0x0,%ebx
8048df0: eb 38 jmp 8048e2a <phase_6+0x76>
8048df2: 89 f3 mov %esi,%ebx
8048df4: 8b 44 9c 10 mov 0x10(%esp,%ebx,4),%eax
8048df8: 39 44 b4 0c cmp %eax,0xc(%esp,%esi,4)
8048dfc: 75 05 jne 8048e03 <phase_6+0x4f>
8048dfe: e8 f2 02 00 00 call 80490f5 <explode_bomb>
8048e03: 83 c3 01 add $0x1,%ebx
8048e06: 83 fb 05 cmp $0x5,%ebx
8048e09: 7e e9 jle 8048df4 <phase_6+0x40>
8048e0b: eb c5 jmp 8048dd2 <phase_6+0x1e>

对%esi赋值0,分析完后面可以看出%esi是一个计数器,接下来进入一个循环,从8048dd2到8048e0b的内容是第一个循环,目的是循环读取输入的数字,要求小于等于6,并且任意两个数字不相同。第一个循环结束后从8048df0跳入8048e2a,将计数器清零。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
8048e0d:	8b 52 08             	mov    0x8(%edx),%edx
8048e10: 83 c0 01 add $0x1,%eax
8048e13: 39 c8 cmp %ecx,%eax
8048e15: 75 f6 jne 8048e0d <phase_6+0x59>
8048e17: eb 05 jmp 8048e1e <phase_6+0x6a>
8048e19: ba 3c c1 04 08 mov $0x804c13c,%edx
8048e1e: 89 54 b4 28 mov %edx,0x28(%esp,%esi,4)
8048e22: 83 c3 01 add $0x1,%ebx
8048e25: 83 fb 06 cmp $0x6,%ebx
8048e28: 74 17 je 8048e41 <phase_6+0x8d>
8048e2a: 89 de mov %ebx,%esi
8048e2c: 8b 4c 9c 10 mov 0x10(%esp,%ebx,4),%ecx
8048e30: 83 f9 01 cmp $0x1,%ecx
8048e33: 7e e4 jle 8048e19 <phase_6+0x65>
8048e35: b8 01 00 00 00 mov $0x1,%eax
8048e3a: ba 3c c1 04 08 mov $0x804c13c,%edx
8048e3f: eb cc jmp 8048e0d <phase_6+0x59>

在8048e2c处令%ecx=10+%esp+%ebx*4,判断%ecx≦1,不管成不成立,我发现都进行了一个取地址操作,%edx=$0x804c13c,%edx获取完地址值后,继续分析,发现第二个循环目的是将%edx+8位置的值放入esp中,如此循环6次。那就查看一下0x804c13c的内容,再查看0x804c13c+8的值。发现一个是16进制数,一个是另一个地址。顺着给出的另一个地址再次进行查看,+8查看······手动输入,最后一个位置给出0x0,说明结束了。






如此一番查看得到一个线性表,结构是(0xd5,1)->(0x6c,2)->(0x10c,3)->(0x392,4)->(0xf4,5)->(0x307,6)
后面跟着的数字是节点名称。

1
2
3
4
5
6
7
8
9
10
11
12
8048e41:	8b 5c 24 28          	mov    0x28(%esp),%ebx
8048e45: 8d 44 24 2c lea 0x2c(%esp),%eax
8048e49: 8d 74 24 40 lea 0x40(%esp),%esi
8048e4d: 89 d9 mov %ebx,%ecx
8048e4f: 8b 10 mov (%eax),%edx
8048e51: 89 51 08 mov %edx,0x8(%ecx)
8048e54: 83 c0 04 add $0x4,%eax
8048e57: 39 f0 cmp %esi,%eax
8048e59: 74 04 je 8048e5f <phase_6+0xab>
8048e5b: 89 d1 mov %edx,%ecx
8048e5d: eb f0 jmp 8048e4f <phase_6+0x9b>
8048e5f: c7 42 08 00 00 00 00 movl $0x0,0x8(%edx)

这段代码刚好验证之前的推测,取值放值。

1
2
3
4
5
6
7
8
9
8048e66:	be 05 00 00 00       	mov    $0x5,%esi
8048e6b: 8b 43 08 mov 0x8(%ebx),%eax
8048e6e: 8b 00 mov (%eax),%eax
8048e70: 39 03 cmp %eax,(%ebx)
8048e72: 7e 05 jle 8048e79 <phase_6+0xc5>
8048e74: e8 7c 02 00 00 call 80490f5 <explode_bomb>
8048e79: 8b 5b 08 mov 0x8(%ebx),%ebx
8048e7c: 83 ee 01 sub $0x1,%esi
8048e7f: 75 ea jne 8048e6b <phase_6+0xb7>

这段循环就是将结构体数据域的值按从小到大顺序排列,那我们的输入就应该是排列顺序的节点名称值顺序,进行输入得到

总结

今天用到的汇编指令在之前的几题中都出现过,没有新的内容。虽然没有新的,但这些指令加在一块看起来十分复杂,代码量巨大,逐行分析费了不少时间。在此题中学习了有关线性表的知识,学习到线性表在汇编语言中的表示形式。

CATALOG
  1. 1. Phase 6
    1. 1.1. 解题思路
    2. 1.2. 总结