CSAPP: Bomb Lab(3)
2016-06-18 23:53
841 查看
Bomb 5
0000000000401062 <phase_5>: 401062: 53 push %rbx 401063: 48 83 ec 20 sub $0x20,%rsp 401067: 48 89 fb mov %rdi,%rbx //将输入的字符串放在rbx中 40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 401073: 48 89 44 24 18 mov %rax,0x18(%rsp) 401078: 31 c0 xor %eax,%eax 40107a: e8 9c 02 00 00 callq 40131b <string_length> 40107f: 83 f8 06 cmp $0x6,%eax //string lengh must 6 401082: 74 4e je 4010d2 <phase_5+0x70> 401084: e8 b1 03 00 00 callq 40143a <explode_bomb>
根据
40107a,40107f处代码可以得到,输入的字符串的长度为6。
根据下面代码中
<strings_not_equal>函数,可以知道我们最后经过处理,字符串需要与
内存$0x40245e处的字符串比较是否相等,运用
p/s (char*)$0x40245e,获得该比较字符串为flyers。
401089: eb 47 jmp 4010d2 <phase_5+0x70> 40108b: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx //将输入字符串的第一个字符给ecx 40108f: 88 0c 24 mov %cl,(%rsp) 401092: 48 8b 14 24 mov (%rsp),%rdx 401096: 83 e2 0f and $0xf,%edx //取字符的最低4位到edx,大小从0~15 401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx //根据rdx中的数字,从0x4024b0(%rdx)中取字符 //maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you? 4010a0: 88 54 04 10 mov %dl,0x10(%rsp,%rax,1) //存储取出的字符 4010a4: 48 83 c0 01 add $0x1,%rax //处理次数+1 4010a8: 48 83 f8 06 cmp $0x6,%rax //判断处理次数是否到6次 4010ac: 75 dd jne 40108b <phase_5+0x29> 4010ae: c6 44 24 16 00 movb $0x0,0x16(%rsp) //为新创建的字符串添加结尾符“/0” 4010b3: be 5e 24 40 00 mov $0x40245e,%esi // flyers 4010b8: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi //比较新创建的字符串与flyers是否相等 4010bd: e8 76 02 00 00 callq 401338 <strings_not_equal> 4010c2: 85 c0 test %eax,%eax 4010c4: 74 13 je 4010d9 <phase_5+0x77> 4010c6: e8 6f 03 00 00 callq 40143a <explode_bomb> 4010cb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4010d0: eb 07 jmp 4010d9 <phase_5+0x77> 4010d2: b8 00 00 00 00 mov $0x0,%eax 4010d7: eb b2 jmp 40108b <phase_5+0x29> ...... 其他结束代码
然后在分析以上代码。可以看出大致是一个while循环,
while(处理次数< 6)。根据上面代码块的注释,我们可以理解这个函数主要功能是根据我们输入的6位字符串,以这字符串的每个字符的后4位(0000 ~ 1111,0 ~ 15 ) 为索引,从内存
0x4024b0(%rdx)中取出新的字符组成新6位字符串。然后比较新创建的字符串与
flyers是否相等。
内存$0x4024b0处的字符串数组获取命令行如下:
(gdb) p/s (char*)0x4024b0 $5 = 0x4024b0 <array> "maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?"
根据这个字符串,可以得到f(9),l(15),y(14),e(5),r(6),s(7)
所以只要我们输入的字符串的字符ASCII的第二位(16进制)符合这个要求就可以了。
其中一个答案为:
ionefg(0x49,0x4f,0x4E,0x45,0x46,0x47)
Bomb 6
对phase_6()函数反汇编。下面是代码的开头,可以通过注释得到,我们输入的6位数字,且都小于64010f4: 41 56 push %r14 4010f6: 41 55 push %r13 4010f8: 41 54 push %r12 4010fa: 55 push %rbp 4010fb: 53 push %rbx //被调用者负责寄存器 4010fc: 48 83 ec 50 sub $0x50,%rsp 401100: 49 89 e5 mov %rsp,%r13 401103: 48 89 e6 mov %rsp,%rsi 401106: e8 51 03 00 00 callq 40145c <read_six_numbers> //==>读入6个数字 40110b: 49 89 e6 mov %rsp,%r14 =====init 40110e: 41 bc 00 00 00 00 mov $0x0,%r12d 401114: 4c 89 ed mov %r13,%rbp 401117: 41 8b 45 00 mov 0x0(%r13),%eax 40111b: 83 e8 01 sub $0x1,%eax 40111e: 83 f8 05 cmp $0x5,%eax //==>所有数字小于6 401121: 76 05 jbe 401128 <phase_6+0x34> 401123: e8 12 03 00 00 callq 40143a <explode_bomb>
接下去的代码是一个while循环,r12d和ebx是一个循环计数器。该循环用于判断这6个数是否存在等于0的。可以推测得到每个数字都不为0.
401128: 41 83 c4 01 add $0x1,%r12d //r12d计数 40112c: 41 83 fc 06 cmp $0x6,%r12d //计数小于6 401130: 74 21 je 401153 <phase_6+0x5f> 401132: 44 89 e3 mov %r12d,%ebx 401135: 48 63 c3 movslq %ebx,%rax 401138: 8b 04 84 mov (%rsp,%rax,4),%eax 40113b: 39 45 00 cmp %eax,0x0(%rbp) //==>判断每个数字都不等于 0 40113e: 75 05 jne 401145 <phase_6+0x51> 401140: e8 f5 02 00 00 callq 40143a <explode_bomb> 401145: 83 c3 01 add $0x1,%ebx 401148: 83 fb 05 cmp $0x5,%ebx 40114b: 7e e8 jle 401135 <phase_6+0x41>
接下去的代码是用来对输入的数字进行修改,input[i] = 7 - input[i]。
401153: 48 8d 74 24 18 lea 0x18(%rsp),%rsi 401158: 4c 89 f0 mov %r14,%rax 40115b: b9 07 00 00 00 mov $0x7,%ecx 401160: 89 ca mov %ecx,%edx 401162: 2b 10 sub (%rax),%edx 401164: 89 10 mov %edx,(%rax) //input[i] = 7 - input[i] 401166: 48 83 c0 04 add $0x4,%rax //下一个元素,相当于i++ 40116a: 48 39 f0 cmp %rsi,%rax //是否越界 40116d: 75 f1 jne 401160 <phase_6+0x6c>
下面的代码是讲
内存$6032d0位置处的内容,按照我们输入的数字的标号在指定位置排序(如5 4 3,则
内存$6032d0第5个元素处的元素排在第1个,第4个排在第2个,第3个排在第3个)。
40116f: be 00 00 00 00 mov $0x0,%esi 401174: eb 21 jmp 401197 <phase_6+0xa3> 401176: 48 8b 52 08 mov 0x8(%rdx),%rdx //到40117f 。为了找到第ecx个node 40117a: 83 c0 01 add $0x1,%eax 40117d: 39 c8 cmp %ecx,%eax 40117f: 75 f5 jne 401176 <phase_6+0x82> 401181: eb 05 jmp 401188 <phase_6+0x94> 401183: ba d0 32 60 00 mov $0x6032d0,%edx 401188: 48 89 54 74 20 mov %rdx,0x20(%rsp,%rsi,2) //将相应Node放入指定位置 40118d: 48 83 c6 04 add $0x4,%rsi //input数组下一个元素 401191: 48 83 fe 18 cmp $0x18,%rsi //检查是否越界(input数组) 401195: 74 14 je 4011ab <phase_6+0xb7> 401197: 8b 0c 34 mov (%rsp,%rsi,1),%ecx //a[rsi/4] 40119a: 83 f9 01 cmp $0x1,%ecx //if a[i]<= 1 40119d: 7e e4 jle 401183 <phase_6+0x8f> 40119f: b8 01 00 00 00 mov $0x1,%eax 4011a4: ba d0 32 60 00 mov $0x6032d0,%edx 4011a9: eb cb jmp 401176 <phase_6+0x82>
对于$0x6032d0处的内容,我们要仔细看一下。运用
x *0x6032d0,可以看到显示是一个node。
通过不断的查看可以看到该node的内容如下图:
下面代码段用来将node之间建立链表连接指针
4011ab: 48 8b 5c 24 20 mov 0x20(%rsp),%rbx 4011b0: 48 8d 44 24 28 lea 0x28(%rsp),%rax 4011b5: 48 8d 74 24 50 lea 0x50(%rsp),%rsi 4011ba: 48 89 d9 mov %rbx,%rcx 4011bd: 48 8b 10 mov (%rax),%rdx 4011c0: 48 89 51 08 mov %rdx,0x8(%rcx) //将下一个NOde的地址赋值给前一个 4011c4: 48 83 c0 08 add $0x8,%rax 4011c8: 48 39 f0 cmp %rsi,%rax 4011cb: 74 05 je 4011d2 <phase_6+0xde> 4011cd: 48 89 d1 mov %rdx,%rcx 4011d0: eb eb jmp 4011bd <phase_6+0xc9> 4011d2: 48 c7 42 08 00 00 00 movq $0x0,0x8(%rdx) //最后的指针值为NULL
下面代码用来判断该链表是否递增,如果递减,则不爆,否则爆炸。
4011da: bd 05 00 00 00 mov $0x5,%ebp //计步 4011df: 48 8b 43 08 mov 0x8(%rbx),%rax 4011e3: 8b 00 mov (%rax),%eax 4011e5: 39 03 cmp %eax,(%rbx) //前一项是否大于后一项 4011e7: 7d 05 jge 4011ee <phase_6+0xfa> 4011e9: e8 4c 02 00 00 callq 40143a <explode_bomb> 4011ee: 48 8b 5b 08 mov 0x8(%rbx),%rbx 4011f2: 83 ed 01 sub $0x1,%ebp 4011f5: 75 e8 jne 4011df <phase_6+0xeb>
所以根据上面所有的分析得到,我们输入的数字串,是为链表排序的,输入的编号数字的位置,决定了相应编号节点的位置。
所以我们输入的应该使得链表递减的顺序。
根据之前查看的链表内容
$61 = {332, 1, 6304480, 0, 168, 2, 6304496, 0, 924, 3, 6304512, 0,
691, 4, 6304528, 0, 477, 5, 6304544, 0, 443, 6, 0, 0}
应该是924>692>477>443>332>168 ==>3 4 5 6 1 2
由因为之前知道input[i] = 7-input[i];
所以最初输入应该为 4 3 2 1 6 5
经过验证为正确答案。
相关文章推荐
- Android 之dragger使用
- Android 之dragger使用
- Android 之dragger使用
- Android 开源框架ImageLoader完全解析(一)--- 基本介绍及使用
- github项目解析(五)-->android日志框架
- android app启动慢分析
- 初探Swift 3.0的重大变化
- Android设置全屏
- Android Studio解决unspecified on project app resolves to an APK archive which is not supported
- 致Android-那些年,我们一起踩过的坑
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
- android studio界面简单介绍
- Unity项目架构设计
- Android:代码的规范
- iOS EXC_BAD_ACCESS 的处理方法
- Android Icon数字角标(BadgeNumber)的实现方式
- 探索view的触发事件
- ios学习路线—iOS高级(NSThread)