计算机系统基础实验_bomb
bomb实验实验需用到的linux指令:汇编中需注意的小知识:phase_1phase_2phase_3phase_4phase_5phase_6实验需用到的linux指令:ls:查看该目录下包含的文件tar vxf***.tar:解压缩objdump-d***>a.txt :将***文件反汇编成a.txt汇编中需注意的小知识:%表示取寄存器的值( )表示以该寄存器值为地址对应的内存值即()
实验需用到的linux指令:
ls:查看该目录下包含的文件
tar vxf ***.tar: 解压缩
objdump -d *** > a.txt :将***文件反汇编成a.txt
输入 gdb bomb 命令进入调试
b:设置断点
r:开始运行
ni:单步执行命令
q 命令退出 gdb 模式
汇编中需注意的小知识:
%表示取寄存器的值
()表示内存
move和lea对()有不同的处理
move:对()解引用,以寄存器的值作为地址得到该地址对应的内存单元
lea对()不解引用
如:
lea eax,[ebx+8]就是将ebx+8这个值直接赋给eax,
不是把ebx+8处的内存地址里的数据赋给eax。
而mov指令则恰恰相反,
mov eax,[ebx+8]则是把内存地址为ebx+8处的数据赋给eax。
phase_1
源代码
00001499 <phase_1>:
1499: 55 push %ebp
149a: 89 e5 mov %esp,%ebp
149c: 53 push %ebx
149d: 83 ec 0c sub $0xc,%esp
14a0: e8 6b fd ff ff call 1210 <__x86.get_pc_thunk.bx>
14a5: 81 c3 5b 3b 00 00 add $0x3b5b,%ebx
14ab: 8d 83 44 e1 ff ff lea -0x1ebc(%ebx),%eax 将包含字符串的地址送给eax
14b1: 50 push %eax
14b2: ff 75 08 pushl 0x8(%ebp)
14b5: e8 db 04 00 00 call 1995 <strings_not_equal>
14ba: 83 c4 10 add $0x10,%esp
14bd: 85 c0 test %eax,%eax
14bf: 75 05 jne 14c6 <phase_1+0x2d>
14c1: 8b 5d fc mov -0x4(%ebp),%ebx
14c4: c9 leave
14c5: c3 ret
14c6: e8 01 06 00 00 call 1acc <explode_bomb>
14cb: eb f4 jmp 14c1 <phase_1+0x28>
答案藏在eax寄存器中,用gdb中的 i r 指令查看寄存器eax中保存的地址,再使用x/s显示该地址内存中保存的字符串
答案为:Houses will begat jobs, jobs will begat houses.
注:
x/[number][format]
d:整数integer
s:字符串string
c:字符char
u:无符号整数 unsigned integer
o:八进制格式显示变量
x:十六进制格式
f: 浮点数格式float
phase_2
源代码:
000014cd <phase_2>:
14cd: 55 push %ebp
14ce: 89 e5 mov %esp,%ebp
14d0: 57 push %edi
14d1: 56 push %esi
14d2: 53 push %ebx
14d3: 83 ec 34 sub $0x34,%esp
14d6: e8 35 fd ff ff call 1210 <__x86.get_pc_thunk.bx> (esp)->ebx
14db: 81 c3 25 3b 00 00 add $0x3b25,%ebx
14e1: 8d 45 d0 lea -0x30(%ebp),%eax
14e4: 50 push %eax
14e5: ff 75 08 pushl 0x8(%ebp)
14e8: e8 17 06 00 00 call 1b04 <read_six_numbers> 输入6个数
14ed: 83 c4 10 add $0x10,%esp esp上移
14f0: 83 7d d0 01 cmpl $0x1,-0x30(%ebp) 该处的值必须为1
14f4: 75 08 jne 14fe <phase_2+0x31> 不相等则push ebp
14f6: 8d 75 d0 lea -0x30(%ebp),%esi 虽然有()但传递的是ebp自身的值
14f9: 8d 7d e4 lea -0x1c(%ebp),%edi
14fc: eb 13 jmp 1511 <phase_2+0x44> esi指向的内存内容给eax
14fe: e8 c9 05 00 00 call 1acc <explode_bomb> push ebp
1503: eb f1 jmp 14f6 <phase_2+0x29> (ebp-30)->esi
1505: e8 c2 05 00 00 call 1acc <explode_bomb>
150a: 83 c6 04 add $0x4,%esi esi上移1
150d: 39 fe cmp %edi,%esi
150f: 74 0b je 151c <phase_2+0x4f> 如果edi和esi相等则(ebp-12)->esp
1511: 8b 06 mov (%esi),%eax
1513: 01 c0 add %eax,%eax
1515: 39 46 04 cmp %eax,0x4(%esi)
1518: 74 f0 je 150a <phase_2+0x3d>
151a: eb e9 jmp 1505 <phase_2+0x38>
151c: 8d 65 f4 lea -0xc(%ebp),%esp
151f: 5b pop %ebx
1520: 5e pop %esi
1521: 5f pop %edi
1522: 5d pop %ebp
1523: c3 ret
要求输入6个数,第一个数要求必须为1,后面的数分别为前面一个数的2倍。
答案为:1 2 4 8 16 32
phase_3
源代码:
00001524 <phase_3>:
1524: 55 push %ebp
1525: 89 e5 mov %esp,%ebp
1527: 53 push %ebx
1528: 83 ec 14 sub $0x14,%esp
152b: e8 e0 fc ff ff call 1210 <__x86.get_pc_thunk.bx> esp->ebx
1530: 81 c3 d0 3a 00 00 add $0x3ad0,%ebx
1536: 8d 45 f0 lea -0x10(%ebp),%eax
1539: 50 push %eax
153a: 8d 45 f4 lea -0xc(%ebp),%eax
153d: 50 push %eax
153e: 8d 83 0f e3 ff ff lea -0x1cf1(%ebx),%eax
1544: 50 push %eax
1545: ff 75 08 pushl 0x8(%ebp)
1548: e8 d3 fb ff ff call 1120 <__isoc99_sscanf@plt> 读入函数 将输入的参数按照指定格式读到相应的地址
154d: 83 c4 10 add $0x10,%esp
1550: 83 f8 01 cmp $0x1,%eax
1553: 7e 14 jle 1569 <phase_3+0x45> eax<=1则爆炸
1555: 83 7d f4 07 cmpl $0x7,-0xc(%ebp)
1559: 77 4e ja 15a9 <.L17+0x7> ebp-12>7则爆炸
155b: 8b 45 f4 mov -0xc(%ebp),%eax ebp-12->eax
155e: 89 da mov %ebx,%edx
1560: 03 94 83 a0 e1 ff ff add -0x1e60(%ebx,%eax,4),%edx ni edx: 0x80005460
1567: ff e2 jmp *%edx edx储存的地址:157f
1569: e8 5e 05 00 00 call 1acc <explode_bomb>
156e: eb e5 jmp 1555 <phase_3+0x31>
00001570 <.L24>:
1570: b8 d3 02 00 00 mov $0x2d3,%eax
1575: 39 45 f0 cmp %eax,-0x10(%ebp)
1578: 75 42 jne 15bc <.L27+0x7> 不相等则爆炸
157a: 8b 5d fc mov -0x4(%ebp),%ebx
157d: c9 leave
157e: c3 ret
0000157f <.L23>:
157f: b8 68 02 00 00 mov $0x268,%eax
1584: eb ef jmp 1575 <.L24+0x5>
00001586 <.L22>:
1586: b8 59 02 00 00 mov $0x259,%eax
158b: eb e8 jmp 1575 <.L24+0x5>
0000158d <.L21>:
158d: b8 95 00 00 00 mov $0x95,%eax
1592: eb e1 jmp 1575 <.L24+0x5>
00001594 <.L20>:
1594: b8 31 02 00 00 mov $0x231,%eax
1599: eb da jmp 1575 <.L24+0x5>
0000159b <.L19>:
159b: b8 00 02 00 00 mov $0x200,%eax
15a0: eb d3 jmp 1575 <.L24+0x5>
000015a2 <.L17>:
15a2: b8 10 01 00 00 mov $0x110,%eax
15a7: eb cc jmp 1575 <.L24+0x5>
15a9: e8 1e 05 00 00 call 1acc <explode_bomb>
15ae: b8 00 00 00 00 mov $0x0,%eax
15b3: eb c0 jmp 1575 <.L24+0x5>
000015b5 <.L27>:
15b5: b8 ff 00 00 00 mov $0xff,%eax
15ba: eb b9 jmp 1575 <.L24+0x5>
15bc: e8 0b 05 00 00 call 1acc <explode_bomb>
15c1: eb b7 jmp 157a <.L24+0xa>
观察phase_3的函数结构得,该函数包含switch语句
.Lx的一般含义为第x个label
由函数的爆炸条件得eax中储存了第一个参数a,且参数的范围为:2<=a<=7,第二个参数的大小可以根据跳转函数得到
我们可以先输入第一个参数2和任意指定的第二个参数b。
之后使用ni指令一步一步运行到1567地址,再查看寄存器edx中储存的地址值为157f,该地址便为switch跳转地址。
查看跳转执行函数,由 mov $0x268,%eax 得到第二个参数的真实值。(函数将其返回值储存在eax中)
答案:2 616
phase_4
源代码:
0000161e <phase_4>:
161e: 55 push %ebp
161f: 89 e5 mov %esp,%ebp
1621: 53 push %ebx
1622: 83 ec 14 sub $0x14,%esp
1625: e8 e6 fb ff ff call 1210 <__x86.get_pc_thunk.bx> esp->ebx
162a: 81 c3 d6 39 00 00 add $0x39d6,%ebx
1630: 8d 45 f0 lea -0x10(%ebp),%eax
1633: 50 push %eax
1634: 8d 45 f4 lea -0xc(%ebp),%eax
1637: 50 push %eax
1638: 8d 83 0f e3 ff ff lea -0x1cf1(%ebx),%eax
163e: 50 push %eax
163f: ff 75 08 pushl 0x8(%ebp)
1642: e8 d9 fa ff ff call 1120 <__isoc99_sscanf@plt> 输入函数,返回参数个数
1647: 83 c4 10 add $0x10,%esp
164a: 83 f8 02 cmp $0x2,%eax
164d: 75 06 jne 1655 <phase_4+0x37> 不相等则爆炸,所以eax(参数个数)值为2
164f: 83 7d f4 0e cmpl $0xe,-0xc(%ebp)
1653: 76 05 jbe 165a <phase_4+0x3c> 要求ebp-12<=14
1655: e8 72 04 00 00 call 1acc <explode_bomb>
165a: 83 ec 04 sub $0x4,%esp
165d: 6a 0e push $0xe
165f: 6a 00 push $0x0
1661: ff 75 f4 pushl -0xc(%ebp)
1664: e8 5a ff ff ff call 15c3 <func4> 递归函数
1669: 83 c4 10 add $0x10,%esp
166c: 0b 45 f0 or -0x10(%ebp),%eax 要求ebp-16等于eax=0
166f: 74 05 je 1676 <phase_4+0x58>
1671: e8 56 04 00 00 call 1acc <explode_bomb>
1676: 8b 5d fc mov -0x4(%ebp),%ebx
1679: c9 leave
167a: c3 ret
phase_4递归调用了fun4函数
源代码:
000015c3 <func4>:
15c3: 55 push %ebp
15c4: 89 e5 mov %esp,%ebp
15c6: 56 push %esi
15c7: 53 push %ebx
15c8: 8b 4d 08 mov 0x8(%ebp),%ecx 参数a:x
15cb: 8b 45 0c mov 0xc(%ebp),%eax 参数b:0
15ce: 8b 5d 10 mov 0x10(%ebp),%ebx 参数c:14
15d1: 89 de mov %ebx,%esi
15d3: 29 c6 sub %eax,%esi esi:c与b的差值14
15d5: 89 f2 mov %esi,%edx
15d7: c1 ea 1f shr $0x1f,%edx 右移31位即edx清零
15da: 01 f2 add %esi,%edx edx赋值差值14
15dc: d1 fa sar %edx 右移1位即除以2 edx=7
15de: 01 c2 add %eax,%edx edx=7
15e0: 39 ca cmp %ecx,%edx
15e2: 7f 0e jg 15f2 <func4+0x2f>
15e4: b8 00 00 00 00 mov $0x0,%eax
15e9: 7c 1c jl 1607 <func4+0x44>
15eb: 8d 65 f8 lea -0x8(%ebp),%esp
15ee: 5b pop %ebx
15ef: 5e pop %esi
15f0: 5d pop %ebp
15f1: c3 ret
15f2: 83 ec 04 sub $0x4,%esp
15f5: 83 ea 01 sub $0x1,%edx
15f8: 52 push %edx
15f9: 50 push %eax
15fa: 51 push %ecx
15fb: e8 c3 ff ff ff call 15c3 <func4>
1600: 83 c4 10 add $0x10,%esp
1603: 01 c0 add %eax,%eax
1605: eb e4 jmp 15eb <func4+0x28>
1607: 83 ec 04 sub $0x4,%esp
160a: 53 push %ebx
160b: 83 c2 01 add $0x1,%edx
160e: 52 push %edx
160f: 51 push %ecx
1610: e8 ae ff ff ff call 15c3 <func4>
1615: 83 c4 10 add $0x10,%esp
1618: 8d 44 00 01 lea 0x1(%eax,%eax,1),%eax
161c: eb cd jmp 15eb <func4+0x28>
fun4函数的ret条件是最终edx的值为7,故一开始我们便可以将第一个参数的值设置为7,递归函数便只执行一遍,第二个参数要求必须为0.
答案:7 0
phase_5
源代码:
0000167b <phase_5>:
167b: 55 push %ebp
167c: 89 e5 mov %esp,%ebp
167e: 56 push %esi
167f: 53 push %ebx ebx为调用者寄存器
1680: 83 ec 10 sub $0x10,%esp
1683: e8 88 fb ff ff call 1210 <__x86.get_pc_thunk.bx> mov(%esp),%ebx
1688: 81 c3 78 39 00 00 add $0x3978,%ebx
168e: 8d 45 f0 lea -0x10(%ebp),%eax ebp-16参数2
1691: 50 push %eax
1692: 8d 45 f4 lea -0xc(%ebp),%eax ebp-12参数1
1695: 50 push %eax
1696: 8d 83 0f e3 ff ff lea -0x1cf1(%ebx),%eax
169c: 50 push %eax
169d: ff 75 08 pushl 0x8(%ebp)
16a0: e8 7b fa ff ff call 1120 <__isoc99_sscanf@plt>
16a5: 83 c4 10 add $0x10,%esp
16a8: 83 f8 01 cmp $0x1,%eax 要求eax>1 参数个数大于1
16ab: 7e 48 jle 16f5 <phase_5+0x7a>
16ad: 8b 45 f4 mov -0xc(%ebp),%eax 参数1给eax
16b0: 83 e0 0f and $0xf,%eax 参数1高四位清0
16b3: 89 45 f4 mov %eax,-0xc(%ebp) 刷新参数1的值
16b6: 83 f8 0f cmp $0xf,%eax
16b9: 74 2e je 16e9 <phase_5+0x6e> 参数1不能大于等于15
16bb: b9 00 00 00 00 mov $0x0,%ecx ecx=0
16c0: ba 00 00 00 00 mov $0x0,%edx edx=0
16c5: 8d b3 c0 e1 ff ff lea -0x1e40(%ebx),%esi ebx:80005000,esi:0x800031c0
循环
16cb: 83 c2 01 add $0x1,%edx edx=1 记录循环次数
16ce: 8b 04 86 mov (%esi,%eax,4),%eax 从数组中读数,每次跳四个字节
16d1: 01 c1 add %eax,%ecx ecx为数组中的值的累加
16d3: 83 f8 0f cmp $0xf,%eax
16d6: 75 f3 jne 16cb <phase_5+0x50> 要求eax的值为15
16d8: c7 45 f4 0f 00 00 00 movl $0xf,-0xc(%ebp) 参数1为15
16df: 83 fa 0f cmp $0xf,%edx
16e2: 75 05 jne 16e9 <phase_5+0x6e> 要求循环15次
16e4: 39 4d f0 cmp %ecx,-0x10(%ebp) 要求参数2等于ecx
16e7: 74 05 je 16ee <phase_5+0x73>
16e9: e8 de 03 00 00 call 1acc <explode_bomb>
16ee: 8d 65 f8 lea -0x8(%ebp),%esp
16f1: 5b pop %ebx
16f2: 5e pop %esi
16f3: 5d pop %ebp
16f4: c3 ret
16f5: e8 d2 03 00 00 call 1acc <explode_bomb>
16fa: eb b1 jmp 16ad <phase_5+0x32>
该函数是有关一个数组的计算,首先要找到储存该数组的地址
为了在给函数设置断点并分布执行时不会因为参数的输入而导致bomb爆炸,故根据函数对参数的范围要求可先输入两个参数a,b。
分布执行到16c5查看寄存器中的值,esi中便是数组的首地址
函数的功能为:前一个加数为数组中的值,后一个加数为:以前一个加数的值作为索引得到的数组中的值。不断求和,直到遇到数组中值为15。
答案:5 115
phase_6
源代码:
000016fc <phase_6>:
16fc: 55 push %ebp
16fd: 89 e5 mov %esp,%ebp
16ff: 57 push %edi
1700: 56 push %esi
1701: 53 push %ebx
1702: 83 ec 54 sub $0x54,%esp
1705: e8 06 fb ff ff call 1210 <__x86.get_pc_thunk.bx> mov(%esp),%ebx
170a: 81 c3 f6 38 00 00 add $0x38f6,%ebx
1710: 8d 45 d0 lea -0x30(%ebp),%eax
1713: 50 push %eax
1714: ff 75 08 pushl 0x8(%ebp)
1717: e8 e8 03 00 00 call 1b04 <read_six_numbers> 读6个数
171c: 8d 45 d4 lea -0x2c(%ebp),%eax
171f: 89 45 ac mov %eax,-0x54(%ebp)
1722: 83 c4 10 add $0x10,%esp
1725: c7 45 b0 00 00 00 00 movl $0x0,-0x50(%ebp)
172c: 8d 45 e8 lea -0x18(%ebp),%eax
172f: 89 45 b4 mov %eax,-0x4c(%ebp)
1732: eb 21 jmp 1755 <phase_6+0x59>
1734: e8 93 03 00 00 call 1acc <explode_bomb>
1739: eb 2d jmp 1768 <phase_6+0x6c>
173b: e8 8c 03 00 00 call 1acc <explode_bomb>
1740: 83 c6 04 add $0x4,%esi
1743: 39 75 b4 cmp %esi,-0x4c(%ebp) 要求其相等
1746: 74 09 je 1751 <phase_6+0x55>
1748: 8b 06 mov (%esi),%eax
174a: 39 47 fc cmp %eax,-0x4(%edi)
174d: 75 f1 jne 1740 <phase_6+0x44>
174f: eb ea jmp 173b <phase_6+0x3f>
1751: 83 45 ac 04 addl $0x4,-0x54(%ebp)
1755: 8b 45 ac mov -0x54(%ebp),%eax
1758: 89 c7 mov %eax,%edi
175a: 8b 40 fc mov -0x4(%eax),%eax
175d: 89 45 a8 mov %eax,-0x58(%ebp)
1760: 83 e8 01 sub $0x1,%eax
1763: 83 f8 05 cmp $0x5,%eax
1766: 77 cc ja 1734 <phase_6+0x38> 要求eax<=5
1768: 83 45 b0 01 addl $0x1,-0x50(%ebp)
176c: 8b 45 b0 mov -0x50(%ebp),%eax
176f: 83 f8 05 cmp $0x5,%eax
1772: 7f 05 jg 1779 <phase_6+0x7d> 循环验证,要求出入的数据有6个
1774: 8b 75 ac mov -0x54(%ebp),%esi
1777: eb cf jmp 1748 <phase_6+0x4c>
按输入序列进行排序
1779: 8d 45 d0 lea -0x30(%ebp),%eax
177c: 8d 75 e8 lea -0x18(%ebp),%esi
177f: b9 07 00 00 00 mov $0x7,%ecx
1784: 89 ca mov %ecx,%edx
1786: 2b 10 sub (%eax),%edx
1788: 89 10 mov %edx,(%eax)
178a: 83 c0 04 add $0x4,%eax
178d: 39 c6 cmp %eax,%esi
178f: 75 f3 jne 1784 <phase_6+0x88>
1791: be 00 00 00 00 mov $0x0,%esi
1796: 89 f7 mov %esi,%edi
1798: 8b 4c b5 d0 mov -0x30(%ebp,%esi,4),%ecx
179c: b8 01 00 00 00 mov $0x1,%eax
17a1: 8d 93 4c 01 00 00 lea 0x14c(%ebx),%edx
17a7: 83 f9 01 cmp $0x1,%ecx
17aa: 7e 0a jle 17b6 <phase_6+0xba> 0x80005158
查找节点 0x8000514c
17ac: 8b 52 08 mov 0x8(%edx),%edx 将链表对应的值传递
17af: 83 c0 01 add $0x1,%eax
17b2: 39 c8 cmp %ecx,%eax
17b4: 75 f6 jne 17ac <phase_6+0xb0>
17b6: 89 54 bd b8 mov %edx,-0x48(%ebp,%edi,4)
17ba: 83 c6 01 add $0x1,%esi
17bd: 83 fe 06 cmp $0x6,%esi
17c0: 75 d4 jne 1796 <phase_6+0x9a>
按降序重建链表
17c2: 8b 75 b8 mov -0x48(%ebp),%esi 输入的第一个数
17c5: 8b 45 bc mov -0x44(%ebp),%eax
17c8: 89 46 08 mov %eax,0x8(%esi)
17cb: 8b 55 c0 mov -0x40(%ebp),%edx
17ce: 89 50 08 mov %edx,0x8(%eax)
17d1: 8b 45 c4 mov -0x3c(%ebp),%eax
17d4: 89 42 08 mov %eax,0x8(%edx)
17d7: 8b 55 c8 mov -0x38(%ebp),%edx
17da: 89 50 08 mov %edx,0x8(%eax)
17dd: 8b 45 cc mov -0x34(%ebp),%eax
17e0: 89 42 08 mov %eax,0x8(%edx)
17e3: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax)
判断是否为降序排列
17ea: bf 05 00 00 00 mov $0x5,%edi
17ef: eb 08 jmp 17f9 <phase_6+0xfd>
17f1: 8b 76 08 mov 0x8(%esi),%esi 前一个链表的数
17f4: 83 ef 01 sub $0x1,%edi
17f7: 74 10 je 1809 <phase_6+0x10d>
17f9: 8b 46 08 mov 0x8(%esi),%eax 后一个链表的数
17fc: 8b 00 mov (%eax),%eax
17fe: 39 06 cmp %eax,(%esi) 如果第一个数大于等于第二个数就继续
1800: 7d ef jge 17f1 <phase_6+0xf5>
1802: e8 c5 02 00 00 call 1acc <explode_bomb>
1807: eb e8 jmp 17f1 <phase_6+0xf5>
1809: 8d 65 f4 lea -0xc(%ebp),%esp
180c: 5b pop %ebx
180d: 5e pop %esi
180e: 5f pop %edi
180f: 5d pop %ebp
1810: c3 ret
对列表进行降序排列
查看edx中的值,保存的即为列表的地址
根据节点从大到小排序为3 5 6 2 1 4
再用7减去对应的值得到答案
答案:4 2 1 5 6 3
将所有答案写到ans.txt文件中进行编译
更多推荐
所有评论(0)