CSAPP: Bomb Lab(1)
来源:互联网 发布:混沌战域仙魂进阶数据 编辑:程序博客网 时间:2024/05/21 10:25
实验需要掌握的相关工具
一.gdb(调试工具)
主要作用在于设置断点调试程序。
详细见gdb教程
二. objdump(反编译工具)
主要是两个命令:
- objdump -d ./bomb>assemble.txt
反汇编bomb程序,并且输出到assemble.txt。该命令将整个程序反汇编(与gdb中disassemble可以协助使用) - objdump -t ./bomb
输出符号表
三. strings
打印程序中出现的所有的字符串
实验过程
实验准备
实验虚拟机为:ubuntu 14.4 64位
运用objdump将程序反汇编到assemble.txt文件中
main函数的有用的主要反汇编代码如下
0000000000400da0 <main>: 400da0: 53 push %rbx ....... 400e32: e8 67 06 00 00 callq 40149e <read_line> 400e37: 48 89 c7 mov %rax,%rdi 400e3a: e8 a1 00 00 00 callq 400ee0 <phase_1> 400e3f: e8 80 07 00 00 callq 4015c4 <phase_defused> 400e44: bf a8 23 40 00 mov $0x4023a8,%edi 400e49: e8 c2 fc ff ff callq 400b10 <puts@plt> 400e4e: e8 4b 06 00 00 callq 40149e <read_line> 400e53: 48 89 c7 mov %rax,%rdi 400e56: e8 a1 00 00 00 callq 400efc <phase_2> 400e5b: e8 64 07 00 00 callq 4015c4 <phase_defused> 400e60: bf ed 22 40 00 mov $0x4022ed,%edi 400e65: e8 a6 fc ff ff callq 400b10 <puts@plt> 400e6a: e8 2f 06 00 00 callq 40149e <read_line> 400e6f: 48 89 c7 mov %rax,%rdi 400e72: e8 cc 00 00 00 callq 400f43 <phase_3> 400e77: e8 48 07 00 00 callq 4015c4 <phase_defused> 400e7c: bf 0b 23 40 00 mov $0x40230b,%edi 400e81: e8 8a fc ff ff callq 400b10 <puts@plt> 400e86: e8 13 06 00 00 callq 40149e <read_line> 400e8b: 48 89 c7 mov %rax,%rdi 400e8e: e8 79 01 00 00 callq 40100c <phase_4> 400e93: e8 2c 07 00 00 callq 4015c4 <phase_defused> 400e98: bf d8 23 40 00 mov $0x4023d8,%edi 400e9d: e8 6e fc ff ff callq 400b10 <puts@plt> 400ea2: e8 f7 05 00 00 callq 40149e <read_line> 400ea7: 48 89 c7 mov %rax,%rdi 400eaa: e8 b3 01 00 00 callq 401062 <phase_5> 400eaf: e8 10 07 00 00 callq 4015c4 <phase_defused> 400eb4: bf 1a 23 40 00 mov $0x40231a,%edi 400eb9: e8 52 fc ff ff callq 400b10 <puts@plt> 400ebe: e8 db 05 00 00 callq 40149e <read_line> 400ec3: 48 89 c7 mov %rax,%rdi 400ec6: e8 29 02 00 00 callq 4010f4 <phase_6> 400ecb: e8 f4 06 00 00 callq 4015c4 <phase_defused> 400ed0: b8 00 00 00 00 mov $0x0,%eax
Bomb 1
用于验证输入的phase_1()函数反汇编代码如下:
(gdb) disassemble phase_1 //反编译phase_1函数Dump of assembler code for function phase_1: 0x0000000000400ee0 <+0>: sub $0x8,%rsp 0x0000000000400ee4 <+4>: mov $0x402400,%esi 0x0000000000400ee9 <+9>: callq 0x401338 <strings_not_equal> 0x0000000000400eee <+14>: test %eax,%eax 0x0000000000400ef0 <+16>: je 0x400ef7 <phase_1+23> 0x0000000000400ef2 <+18>: callq 0x40143a <explode_bomb> 0x0000000000400ef7 <+23>: add $0x8,%rsp 0x0000000000400efb <+27>: retq End of assembler dump.
其中我们可以看到mov $0x402400,%esi
,将内存地址指向的内容作为strings_not_equal()
的第二参数,而在main()的400e37行
已经将input变量地址放入rdi中作为第一个参数(相关代码段见下面代码段)。根据strings_not_equal()
函数名可以得到该函数是比较两个参数所指向的内容是否相等。故我们在gdb中运用print方法获取
(gdb) break phase_1 //为函数phase_1设置断点,当进入phase_1时暂停 (gdb) si//单步调试,且函数则进入函数内部 .........//多次单步调试 (gdb) si 0x0000000000400ee9 in phase_1 () (gdb) info register //程序运行到400ee9之前的程序寄存器内容列表 rax 0x603780 6305664 rbx 0x0 0 rcx 0x3 3 rdx 0x1 1 rsi 0x402400 4203520 //参数2 rdi 0x603780 6305664 //参数1 rbp 0x0 0x0 rsp 0x7fffffffdd20 0x7fffffffdd20 r8 0x7ffff7ff6004 140737354096644 r9 0x0 0 r10 0x7fffffffdab0 140737488345776 r11 0x7ffff7a45110 140737348129040 r12 0x400c90 4197520 r13 0x7fffffffde10 140737488346640 r14 0x0 0 r15 0x0 0 rip 0x400ee9 0x400ee9 <phase_1+9> eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) p/s (char*)0x402400 //根据分析打印内存地址内容,获取以下字符串 $1 = 0x402400 "Border relations with Canada have never been better."
根据得到的字符串测试bomb确实为正确的结果,解除bomb 1。
Bomb 2
(gdb) disassemble phase_2 Dump of assembler code for function phase_2: 0x0000000000400efc <+0>: push %rbp 0x0000000000400efd <+1>: push %rbx 0x0000000000400efe <+2>: sub $0x28,%rsp 0x0000000000400f02 <+6>: mov %rsp,%rsi 0x0000000000400f05 <+9>: callq 0x40145c <read_six_numbers> //读入,并且判断是否读入6个数字 0x0000000000400f0a <+14>: cmpl $0x1,(%rsp) //判断第一个数字是否为1 0x0000000000400f0e <+18>: je 0x400f30 <phase_2+52> //相等则进入循环判断 0x0000000000400f10 <+20>: callq 0x40143a <explode_bomb>//第一个不是1,则爆炸 0x0000000000400f15 <+25>: jmp 0x400f30 <phase_2+52> 0x0000000000400f17 <+27>: mov -0x4(%rbx),%eax 0x0000000000400f1a <+30>: add %eax,%eax 0x0000000000400f1c <+32>: cmp %eax,(%rbx) //后一个元素是不是前一个的两倍,因为第一个是1,所以得到后面的元素一定是2、4、8、16、32 0x0000000000400f1e <+34>: je 0x400f25 <phase_2+41> 0x0000000000400f20 <+36>: callq 0x40143a <explode_bomb> //不是两倍则炸弹爆炸 0x0000000000400f25 <+41>: add $0x4,%rbx 0x0000000000400f29 <+45>: cmp %rbp,%rbx 0x0000000000400f2c <+48>: jne 0x400f17 <phase_2+27> 0x0000000000400f2e <+50>: jmp 0x400f3c <phase_2+64> 0x0000000000400f30 <+52>: lea 0x4(%rsp),%rbx 0x0000000000400f35 <+57>: lea 0x18(%rsp),%rbp 0x0000000000400f3a <+62>: jmp 0x400f17 <phase_2+27> 0x0000000000400f3c <+64>: add $0x28,%rsp 0x0000000000400f40 <+68>: pop %rbx 0x0000000000400f41 <+69>: pop %rbp 0x0000000000400f42 <+70>: retq End of assembler dump.
根据callq 0x40145c <read_six_numbers>
上下文可以得到这个字符串是由6个数字组成,并且在该函数中有函数的401480: mov $0x4025c3,%esi
行代码中可以读取输入的内存地址中存储的字符串格式为“%d %d %d %d %d %d”。紧接着对于phase_2函数的汇编代码进行阅读分析,先关重要代码注释见上面代码段,可以推测得到第一个数字一定为1,并且后面的数字是第一个数字的两倍。综上所述可以得到拆除该炸弹的字符串为“1 2 4 8 16 32”
根据验证,确认为正确答案
1 0
- CSAPP: Bomb Lab(1)
- CSAPP: Bomb Lab(2)
- CSAPP: Bomb Lab(3)
- CSAPP: Bomb Lab(4)
- CSAPP: bomb lab
- CSAPP Bomb Lab
- CSAPP实验2:Bomb Lab
- csapp bomb lab:csapp lab2 炸弹实验
- <csapp> bomb lab (《深入理解计算机系统》lab2)
- CSAPP lab binary bomb 二进制炸弹
- CSAPP课程实验 bomb实验 拆炸弹实验(1)
- Bomb lab
- CSAPP LAB---Proxy lab
- csapp lab2 bomb
- CSAPP: buffer lab
- CSAPP: shell lab
- CSAPP: malloc lab
- CSAPP LAB---MALLOC实验
- 检测点12.1
- LayoutInflater.from(this) 这个this是什么,加载完后的View 就是谁的。
- 自定义tableview cell
- 细说#Pragma Pack(n)与内存对齐
- setsockopt()函数使用详解
- CSAPP: Bomb Lab(1)
- 欢迎使用CSDN-markdown编辑器
- tomcat下jndi的三种配置方式
- Java 继承Thread类和实现Runnable接口的区别
- 基于STM32的简单数字示波器
- 十分钟理解 Java 中的动态代理
- Excel -- 自动填充
- 前端学习_Series2_01.JavaScript_03
- Java通过WebSocket WebRTC实现视频通话实例