计算机系统基础的实验课,引用了国外的实验,非常好
文章目录
一、实验目的:
逆向工程拆除“二进制炸弹”程序
增强对程序机器级表示、汇编语言、调试器和逆向工程等 理解。
一个“Binary Bombs”(二进制炸弹,简称炸弹)是一个 Linux可执行C程序,包含phase1~phase6共6个阶段。
炸弹运行各阶段要求输入一个字符串,若输入符合程序预 期,该阶段炸弹被“拆除”,否则“爆炸”。
你需要拆除尽可能多的炸弹
二、实验要求
拆弹装备:
熟练使用gdb调试器和objdump;
单步跟踪调试每一阶段的机器代码;
理解汇编语言代码的行为或作用;
“推断”拆除炸弹所需的目标字符串。
在各阶段的开始代码前和引爆炸弹函数前设置断点,便于调试。
每个炸弹阶段考察机器级语言程序不同方面,难度递增
阶段1:字符串比较
阶段2:循环
阶段3:条件/分支:含switch语句
阶段4:递归调用和栈
阶段5:指针
阶段6:链表/指针/结构
隐藏阶段,第4阶段之后附加特定字符串后出现
三、实验内容(所修改函数代码,功能以及重要代码的解释):
1.phase_1
8048b30: 55 push %ebp
8048b31: 89 e5 mov %esp,%ebp
8048b33: 83 ec 10 sub $0x10,%esp
8048b36: 68 44 a0 04 08 push $0x804a044
8048b3b: ff 75 08 pushl 0x8(%ebp)
8048b3e: e8 9a 04 00 00 call 8048fdd <strings_not_equal>
8048b43: 83 c4 10 add $0x10,%esp
8048b46: 85 c0 test %eax,%eax
8048b48: 74 05 je 8048b4f <phase_1+0x1f>
8048b4a: e8 91 05 00 00 call 80490e0 <explode_bomb>
8048b4f: c9 leave
8048b50: c3 ret
观察汇编代码,第6行,可知输入为一个字符串,4 5行压入参数时有两个参数,用gdb参看0x804a044中的内容
可知,call的函数判断我们输入的参数与该字符串是否相等,返回值会存入eax中 ,test指令与,若两字符串相等,返回0,跳过炸弹
第一题答案为“Border relations with Canada have never been better.”
2.phase_2
8048b51: 55 push %ebp
8048b52: 89 e5 mov %esp,%ebp
8048b54: 53 push %ebx
8048b55: 83 ec 2c sub $0x2c,%esp//下移11个字节
8048b58: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048b5e: 89 45 f4 mov %eax,-0xc(%ebp)
8048b61: 31 c0 xor %eax,%eax
8048b63: 8d 45 dc lea -0x24(%ebp),%eax
8048b66: 50 push %eax
8048b67: ff 75 08 pushl 0x8(%ebp)
8048b6a: e8 99 05 00 00 call 8049108 <read_six_numbers>//读入6个输入
8048b6f: 83 c4 10 add $0x10,%esp//栈顶指针下移
8048b72: 83 7d dc 00 cmpl $0x0,-0x24(%ebp)//将-0x24(%ebx)的内容与0比较(将第一个输入与0比较)
8048b76: 79 05 jns 8048b7d <phase_2+0x2c>//若数据比0大,跳转
8048b78: e8 63 05 00 00 call 80490e0 <explode_bomb>
8048b7d: bb 01 00 00 00 mov $0x1,%ebx //令ebx存1
8048b82: 89 d8 mov %ebx,%eax //eax存ebx的内容(存i)
8048b84: 03 44 9d d8 add -0x28(%ebp,%ebx,4),%eax //eax存自己加上ebp移位11个字节后的内容(i+第i-1个输入)
8048b88: 39 44 9d dc cmp %eax,-0x24(%ebp,%ebx,4) //比较此时eax结果与ebp移位10个字节后的内容(第i个输入与i+i-1输入相等)
8048b8c: 74 05 je 8048b93 <phase_2+0x42> //若eax与比较数相等则跳转
8048b8e: e8 4d 05 00 00 call 80490e0 <explode_bomb>
8048b93: 83 c3 01 add $0x1,%ebx //令ebx内容+1
8048b96: 83 fb 06 cmp $0x6,%ebx //比较6与1
8048b99: 75 e7 jne 8048b82 <phase_2+0x31> //不相等跳转循环,循环 6次后ebx与6相等
8048b9b: 8b 45 f4 mov -0xc(%ebp),%eax
8048b9e: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048ba5: 74 05 je 8048bac <phase_2+0x5b>
8048ba7: e8 e4 fb ff ff call 8048790 <__stack_chk_fail@plt>
8048bac: 8b 5d fc mov -0x4(%ebp),%ebx
8048baf: c9 leave
8048bb0: c3 ret
由11行分析知6个输入数字,根据17和24行可判断是一个6次的循环,可知如果要安全通过这6次循环,需要在第19行时满足某个条件,根据上下文分析,条件为第i个数与第i-1个数与i相加进行比较,则我们需要输入的6个数满足这样一个数学公式 a i = a i − 1 + i a_i=a_{i-1}+i ai=ai−1+i
又根据第13行确定第一个输入为0 则可退出我们的输入为 0 1 3 6 10 15
3.phase_3
8048bb1: 55 push %ebp
8048bb2: 89 e5 mov %esp,%ebp //使ebp指向新的栈底
8048bb4: 83 ec 18 sub $0x18,%esp //分配栈空间,6个字节
8048bb7: 65 a1 14 00 00 00 mov %gs:0x14,%eax//赋值eax
8048bbd: 89 45 f4 mov %eax,-0xc(%ebp)//令第3个字节赋值
8048bc0: 31 c0 xor %eax,%eax
8048bc2: 8d 45 f0 lea -0x10(%ebp),%eax
8048bc5: 50 push %eax
8048bc6: 8d 45 ec lea -0x14(%ebp),%eax
8048bc9: 50 push %eax
8048bca: 68 2f a2 04 08 push