时间:2021-07-01 10:21:17 帮助过:49人阅读
CSAPP lab2 哈哈~ 不愧是“美国进口的六级*”!爽歪歪的“升级打怪” 我把实验材料都上传到下面这个link了,0分下载(良心啊~) http://download.csdn.net/detail/u011368821/7892649 再一个实验指导说明供大家下载: http://download.csdn.net/detail/u011
哈哈~ 不愧是“美国进口的六级*”!爽歪歪的“升级打怪”
我把实验材料都上传到下面这个link了,0分下载(良心啊~)
http://download.csdn.net/detail/u011368821/7892649
再一个实验指导说明供大家下载:
http://download.csdn.net/detail/u011368821/7892677
- 0000000000400ef0 <phase_1>:
- 400ef0:
- 48 83 ec 08
- sub $0x8,%rsp
- 400ef4:
- be 18 1b 40 00
- mov $0x401b18,%esi
- 400ef9:
- e8 10 04 00 00
- callq 40130e <strings_not_equal>
- 400efe:
- 85 c0
- test %eax,%eax
- 400f00:
- 74 05
- je 400f07 <phase_1+0x17>
- 400f02:
- e8 dc 07 00 00
- callq 4016e3 <explode_bomb>
- 400f07:
- 48 83 c4 08
- add $0x8,%rsp
- 400f0b:
- c3
- retq </explode_bomb></phase_1+0x17></strings_not_equal></phase_1>
注意到这句指令.
400ef4:be 18 1b 40 00 mov $0x401b18,%esi
ESI/EDI 分别叫做"源/目标索引寄存器"(source/destination
index),因为在很多字符串操作指令中
就是要培养的对寄存器很敏感的能力.上面mov $0x401b18,%esi之后立马callq string_not_equal.这是在bomb爆炸之前.我们看看string_not_equal 里面能找到什么线索
- 000000000040130e <strings_not_equal>:
- 40130e:
- 41 54
- push %r12
- 401310:
- 55
- push %rbp
- 401311:
- 53
- push %rbx
- 401312:
- 48 89 fb
- mov %rdi,%rbx
- 401315:
- 48 89 f5
- mov %rsi,%rbp
- 401318:
- e8 d4 ff ff ff
- callq 4012f1 <string_length>
- 40131d:
- 41 89 c4
- mov %eax,%r12d
- 401320:
- 48 89 ef
- mov %rbp,%rdi
- 401323:
- e8 c9 ff ff ff
- callq 4012f1 <string_length>
- 401328:
- ba 01 00 00 00
- mov $0x1,%edx
- 40132d:
- 41 39 c4
- cmp %eax,%r12d
- 401330:
- 75 3e
- jne 401370 <strings_not_equal+0x62>
- ... ...
- 401369:
- eb 05
- jmp 401370 <strings_not_equal+0x62>
- 40136b:
- ba 01 00 00 00
- mov $0x1,%edx
- 401370:
- 89 d0
- mov %edx,%eax
- 401372:
- 5b
- pop %rbx
- 401373:
- 5d
- pop %rbp
- 401374:
- 41 5c
- pop %r12
- 401376:
- c3
- retq </strings_not_equal+0x62></strings_not_equal+0x62></string_length></string_length></strings_not_equal>
我们可以看到这里有连个string_length. 注意到之前的%rdi 和%rsi 分别被mov到%rbx和%rbp中
%rdi记录的是第一个参数的地址,于是当第一次调用直接第一个参数(指针)指向的字符串,
经过
mov %rsi %rbp
mov %rbp %rdi
这样第二次传入string_length的参数就变成了string_not_equal的第二个参数(指针),
string_length 对这两个不同指针指向的字符串进行计算,返回它们的长度值,如果不一致,返回1,如果一致返回0(关于返回值的情况这里的汇编不足以解释,还要分析所有的string_not_equal反汇编才会知道)
phase_1中
callq 40130e
test %eax,%eax
je 如果上一个test指令的结果是0就跳转,否者不跳转
这里如果返回值是0就跳转到了
add $0x8,%rsp
retq
正确返回弹栈了。
上面唧唧歪歪说了这么一对铺垫就一个目的,推理出
400ef4:be 18 1b 40 00 mov $0x401b18,%esi涉及的这个0x401b18是不寻常的,它指向一个字符串,而我们输入的字符串必须和这个指针指向的字符串完全相同才能不触发bomb否者触发BOMB
那就看看0x401b18这里究竟都藏了什么!
gdb debug去
Science isn't about why, it's about why not?
输入0x401b18 指向的字符串即可过了phase 1 : -)
main函数部分截选
我们可以看到搞定了phase_1这里又要进入pahse_2鸟~
- 400e30:
- e8 bb 00 00 00
- callq 400ef0 <phase_1>
- 400e35:
- e8 f2 09 00 00
- callq 40182c <phase_defused>
- 400e3a:
- bf 08 1a 40 00
- mov $0x401a08,%edi
- 400e3f:
- e8 ac fc ff ff
- callq 400af0 <puts@plt>
- 400e44:
- e8 fe 08 00 00
- callq 401747 <read_line>
- 400e49:
- 48 89 c7
- mov %rax,%rdi
- 400e4c:
- e8 bb 00 00 00
- callq 400f0c <phase_2></phase_2></read_line></puts@plt></phase_defused></phase_1>
mov $0x401a08,%edi
0x401a08这个地址装着是一个普通的提示字符串不必在意(测试过了)
看看pahse_2
- 0000000000400f0c <phase_2>:
- 400f0c:
- 55
- push %rbp
- 400f0d:
- 53
- push %rbx
- 400f0e:
- 48 83 ec 28
- sub $0x28,%rsp
- 400f12:
- 48 89 e6
- mov %rsp,%rsi
- 400f15:
- e8 eb 07 00 00
- callq 401705 <read_six_numbers>
- 400f1a:
- 83 3c 24 01
- cmpl $0x1,(%rsp)
- 400f1e:
- 74 25
- je 400f45 <phase_2+0x39>
- 400f20:
- e8 be 07 00 00
- callq 4016e3 <explode_bomb>
- 400f25:
- eb 1e
- jmp 400f45 <phase_2+0x39>
- 400f27:
- 83 c3 01
- add $0x1,%ebx
- 400f2a:
- 89 d8
- mov %ebx,%eax
- 400f2c:
- 0f af 45 fc
- imul -0x4(%rbp),%eax
- 400f30:
- 39 45 00
- cmp %eax,0x0(%rbp)
- 400f33:
- 74 05
- je 400f3a <phase_2+0x2e>
- 400f35:
- e8 a9 07 00 00
- callq 4016e3 <explode_bomb>
- 400f3a:
- 48 83 c5 04
- add $0x4,%rbp
- 400f3e:
- 83 fb 06
- cmp $0x6,%ebx
- 400f41:
- 75 e4
- jne 400f27 <phase_2+0x1b>
- 400f43:
- eb 0c
- jmp 400f51 <phase_2+0x45>
- 400f45:
- 48 8d 6c 24 04
- lea 0x4(%rsp),%rbp
- 400f4a:
- bb 01 00 00 00
- mov $0x1,%ebx
- 400f4f:
- eb d6
- jmp 400f27 <phase_2+0x1b>
- 400f51:
- 48 83 c4 28
- add $0x28,%rsp
- 400f55:
- 5b
- pop %rbx
- 400f56:
- 5d
- pop %rbp
- 400f57:
- c3
- retq </phase_2+0x1b></phase_2+0x45></phase_2+0x1b></explode_bomb></phase_2+0x2e></phase_2+0x39></explode_bomb></phase_2+0x39></read_six_numbers></phase_2>
核心语句
imul -0x4(%rbp),%eax
cmp %eax,0x0(%rbp) //如果比较结果是0,就跳转,否则BOMB
je 400f3a
callq 4016e3
callq 401705
cmpl $0x1,(%rsp)
je 400f45
callq 4016e3
首先比较第一个输入的数(%rsp)和1是否相等,如果是则跳转到400f45标记的位置,否者callq explode_bomb,爆炸
那么可以确定,第一个输入的数字必须是1,接着我们跳转到 400f45
这里lea把rsp寄存器指向的指针+4,然后赋值给rbp,并把%edx寄存器初始化为1
- 400f45:
- 48 8d 6c 24 04
- lea 0x4(%rsp),%rbp
- 400f4a:
- bb 01 00 00 00
- mov $0x1,%ebx
- 400f4f:
- eb d6
- jmp 400f27 <phase_2+0x1b></phase_2+0x1b>
最后跳转到400f27的位置
此时add 把ebx 增 1,然后赋值给%eax,即数值2.
- 400f27:
- 83 c3 01
- add $0x1,%ebx
- 400f2a:
- 89 d8
- mov %ebx,%eax
- 400f2c:
- 0f af 45 fc
- imul -0x4(%rbp),%eax
- 400f30:
- 39 45 00
- cmp %eax,0x0(%rbp)
- 400f33:
- 74 05
- je 400f3a <phase_2+0x2e>
- 400f35:
- e8 a9 07 00 00
- callq 4016e3 <explode_bomb>
- 400f3a:
- 48 83 c5 04
- add $0x4,%rbp
- 400f3e:
- 83 fb 06
- cmp $0x6,%ebx
- 400f41:
- 75 e4
- jne 400f27 <phase_2+0x1b></phase_2+0x1b></explode_bomb></phase_2+0x2e>
把-0x4(%rbp)即第一个输入的数字,imul 乘以%eax的值,然后赋值给%eax,即 %eax = 1*2
cmp把此时的%eax 和当前输入0x0(%rbp),此时为第二个输入数字,比较。如果相同就跳转到400f3a的位置,否者callq explode_bomb爆炸. 由此我们可以知道,第二个输入的数字必须是2.
如果第二个数字输入的是2,接着add 把%rbp +4, 接着cmp 比较%ebx(此时为2)和0x6比较,不相等就跳转到400f27,
于是我们又回到了400f27的位置,有点汇编经验的人一看就可以发现,这里其实是一个循环. %ebx每次+1, 循环6次。
每次都把%eax和前一个输入数字相乘,赋值给%eax,并和当前数字0x0(%rbp)比较。
- 400f2c:
- 0f af 45 fc
- imul -0x4(%rbp),%eax
- 400f30:
- 39 45 00
- cmp %eax,0x0(%rbp)
这样一步步按照汇编语句构造的循环,执行下去,可以发现要想不bomb,输入应该是
1 2 6 24 120 720
OK~ 搞定,phase_2。
当我们搞定phase_2之后,phase_3来了~
- 400e4c:
- e8 bb 00 00 00
- callq 400f0c <phase_2>
- 400e51:
- e8 d6 09 00 00
- callq 40182c <phase_defused>
- 400e56:
- bf 67 19 40 00
- mov $0x401967,%edi
- 400e5b:
- e8 90 fc ff ff
- callq 400af0 <puts@plt>
- 400e60:
- e8 e2 08 00 00
- callq 401747 <read_line>
- 400e65:
- 48 89 c7
- mov %rax,%rdi
- 400e68:
- e8 eb 00 00 00
- callq 400f58 <phase_3>
- 400e6d:
- e8 ba 09 00 00
- callq 40182c <phase_defused></phase_defused></phase_3></read_line></puts@plt></phase_defused></phase_2>
phase_3:
- 0000000000400f58 <phase_3>:
- 400f58:
- 48 83 ec 18
- sub $0x18,%rsp
- 400f5c:
- 4c 8d 44 24 08
- lea 0x8(%rsp),%r8 //把%rsp指向的地址+0x8 赋值给%rcx ,以下的lea操作同理
- 400f61:
- 48 8d 4c 24 07
- lea 0x7(%rsp),%rcx
- 400f66:
- 48 8d 54 24 0c
- lea 0xc(%rsp),%rdx
- 400f6b:
- be 6e 1b 40 00
- mov $0x401b6e,%esi //把0x401b6赋值给%esi ,注意esi是字符串相关寄存器,我们看看这个地址里面是什么
- 400f70:
- b8 00 00 00 00
- mov $0x0,%eax
- 400f75:
- e8 86 fc ff ff
- callq 400c00 <__isoc99_sscanf@plt>
- 400f7a:
- 83 f8 02
- cmp $0x2,%eax
- 400f7d:
- 7f 05
- jg 400f84 <phase_3+0x2c>
- 400f7f:
- e8 5f 07 00 00
- callq 4016e3 <explode_bomb>
- 400f84:
- 83 7c 24 0c 07
- cmpl $0x7,0xc(%rsp) //比较0xc(%rsp)处的值和7比较,如果大于7,ja跳转,接着bomb,于是我们知道0xc(%rsp)处的值要在(0~7)
- 400f89:
- 0f 87 fc 00 00 00
- ja 40108b <phase_3+0x133>
- 400f8f:
- 8b 44 24 0c
- mov 0xc(%rsp),%eax
- 400f93:
- ff 24 c5 80 1b 40 00
- jmpq *0x401b80(,%rax,8)
- 400f9a:
- b8 6a 00 00 00
- mov $0x6a,%eax //把0x6a赋值给%eax,这里很重要,每一个witch分支的这里都不一样,而且第二个输入参数和这个有关系
- 400f9f:
- 81 7c 24 08 40 02 00
- cmpl $0x240,0x8(%rsp) //把0x8(%rsp)的值和0x240比较,如果不相等,bomb,相等就正常跳转到 401095
- 400fa6:
- 00
- 400fa7:
- 0f 84 e8 00 00 00
- je 401095 <phase_3+0x13d>
- 400fad:
- e8 31 07 00 00
- callq 4016e3 <explode_bomb>
- 400fb2:
- b8 6a 00 00 00
- mov $0x6a,%eax
- 400fb7:
- e9 d9 00 00 00
- jmpq 401095 <phase_3+0x13d>
- 400fbc:
- b8 66 00 00 00
- mov $0x66,%eax
- 400fc1:
- 81 7c 24 08 bc 03 00
- cmpl $0x3bc,0x8(%rsp)
- 400fc8:
- 00
- 400fc9:
- 0f 84 c6 00 00 00
- je 401095 <phase_3+0x13d>
- 400fcf:
- e8 0f 07 00 00
- callq 4016e3 <explode_bomb>
- 400fd4:
- b8 66 00 00 00
- mov $0x66,%eax
- 400fd9:
- e9 b7 00 00 00
- jmpq 401095 <phase_3+0x13d>
- 400fde:
- b8 6a 00 00 00
- mov $0x6a,%eax
- 400fe3:
- 81 7c 24 08 2a 02 00
- cmpl $0x22a,0x8(%rsp)
- 400fea:
- 00
- 400feb:
- 0f 84 a4 00 00 00
- je 401095 <phase_3+0x13d>
- 400ff1:
- e8 ed 06 00 00
- callq 4016e3 <explode_bomb>
- 400ff6:
- b8 6a 00 00 00
- mov $0x6a,%eax
- 400ffb:
- e9 95 00 00 00
- jmpq 401095 <phase_3+0x13d>
- 401000:
- b8 76 00 00 00
- mov $0x76,%eax
- 401005:
- 81 7c 24 08 c9 00 00
- cmpl $0xc9,0x8(%rsp)
- 40100c:
- 00
- 40100d:
- 0f 84 82 00 00 00
- je 401095 <phase_3+0x13d>
- 401013:
- e8 cb 06 00 00
- callq 4016e3 <explode_bomb>
- 401018:
- b8 76 00 00 00
- mov $0x76,%eax
- 40101d:
- eb 76
- jmp 401095 <phase_3+0x13d>
- 40101f:
- b8 62 00 00 00
- mov $0x62,%eax
- 401024:
- 81 7c 24 08 07 01 00
- cmpl $0x107,0x8(%rsp)
- 40102b:
- 00
- 40102c:
- 74 67
- je 401095 <phase_3+0x13d>
- 40102e:
- e8 b0 06 00 00
- callq 4016e3 <explode_bomb>
- 401033:
- b8 62 00 00 00
- mov $0x62,%eax
- 401038:
- eb 5b
- jmp 401095 <phase_3+0x13d>
- 40103a:
- b8 69 00 00 00
- mov $0x69,%eax
- 40103f:
- 81 7c 24 08 3b 03 00
- cmpl $0x33b,0x8(%rsp)
- 401046:
- 00
- 401047:
- 74 4c
- je 401095 <phase_3+0x13d>
- 401049:
- e8 95 06 00 00
- callq 4016e3 <explode_bomb>
- 40104e:
- b8 69 00 00 00
- mov $0x69,%eax
- 401053:
- eb 40
- jmp 401095 <phase_3+0x13d>
- 401055:
- b8 71 00 00 00
- mov $0x71,%eax
- 40105a:
- 81 7c 24 08 c6 00 00
- cmpl $0xc6,0x8(%rsp)
- 401061:
- 00
- 401062:
- 74 31
- je 401095 <phase_3+0x13d>
- 401064:
- e8 7a 06 00 00
- callq 4016e3 <explode_bomb>
- 401069:
- b8 71 00 00 00
- mov $0x71,%eax
- 40106e:
- eb 25
- jmp 401095 <phase_3+0x13d>
- 401070:
- b8 77 00 00 00
- mov $0x77,%eax
- 401075:
- 81 7c 24 08 74 01 00
- cmpl $0x174,0x8(%rsp)
- 40107c:
- 00
- 40107d:
- 74 16
- je 401095 <phase_3+0x13d>
- 40107f:
- e8 5f 06 00 00
- callq 4016e3 <explode_bomb>
- 401084:
- b8 77 00 00 00
- mov $0x77,%eax
- 401089:
- eb 0a
- jmp 401095 <phase_3+0x13d>
- 40108b:
- e8 53 06 00 00
- callq 4016e3 <explode_bomb>
- 401090:
- b8 68 00 00 00
- mov $0x68,%eax
- 401095:
- 3a 44 24 07
- cmp 0x7(%rsp),%al //把0x7(%rsp)和 %al(%eax低字节)比较,相等就跳转,否者,bomb
- 401099:
- 74 05
- je 4010a0 <phase_3+0x148>
- 40109b:
- e8 43 06 00 00
- callq 4016e3 <explode_bomb>
- 4010a0:
- 48 83 c4 18
- add $0x18,%rsp
- 4010a4:
- c3
- retq
- </explode_bomb></phase_3+0x148></explode_bomb></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x133></explode_bomb></phase_3+0x2c></phase_3>
注意到开头这里
mov $0x401b6e,%esi
把0x401b6赋值给%esi ,注意esi是字符串相关寄存器,我们看看这个地址里面是什么
我们发现是一个格式化输入说明字符串
于是我们就知道我们应该输入什么类型的数据了
400f75: callq 400c00 <__isoc99_sscanf@plt>
400f7a: cmp $0x2,%eax
400f7d: jg 400f84
400f7f: callq 4016e3
400f84: cmpl $0x7,0xc(%rsp)
根据前面的格式化字符串我们可以注意到
输入三个数据即正常跳转
这里又有个跳转语句
我们看看 *0x401b80处是什么东东
- 400f93:
- ff 24 c5 80 1b 40 00
- jmpq *0x401b80(,%rax,8)
- 400f9a:
- b8 6a 00 00 00
- mov $0x6a,%eax
是一个数,0x400f9a,这个是指令mov $0x6a,%eax 的代码段标记地址
如果%rax是0,就直接跳转到0x400f9a 否则0x400f9a + %rax * 8
这里是典型的witch 语句的汇编形式...如果不明白就去看CSAPP第三章
上面给出的phase_3汇编部分注释我已经写的很清楚了~
这里可以推知phase_3一开始就保存了0x8(%rsp),0x7(%rsp),0xc(%rsp)三处的值,这三处肯定要被接下来的程序重写利用.
- 400f5c:
- 4c 8d 44 24 08
- lea 0x8(%rsp),%r8 //把%rsp指向的地址+0x8 赋值给%rcx ,以下的lea操作同理
- 400f61:
- 48 8d 4c 24 07
- lea 0x7(%rsp),%rcx
- 400f66:
- 48 8d 54 24 0c
- lea 0xc(%rsp),%rdx
而分析偏移量0x8 0x7 0xc,以及格式化字符串参数入栈顺序可知,0xc(%rsp)储存第一个参数,0x7(%rsp)储存第二个参数,0x8(%rsp)储存第三个参数.
提示: printf("%d %d",a,b); 参数是b先入栈,然后是a
综合以上分析,输入
0 j 576
即可过关
这里我偷一下懒第一个选择了0
实际上第一个数据可以是0~7内的任意数字,这也会导致跳转至不同的分支,而影响第二个第三个参数的输入情况。
以0 作为第一个输入参数的例子,
- 400f9a:
- b8 6a 00 00 00
- mov $0x6a,%eax
以上两个指令将被执行,我们可以知道0x7(%rsp)第二个输入的参数应当为0x6a对应的ascii码字符,于是这里应当输入 j
- 401095:
- 3a 44 24 07
- cmp 0x7(%rsp),%al
第三个参数的确定是在
于是第三个参数必须为0x240,否则bomb,这里是%d的读入,于是转化为相应的十进制数为576.
- 400f9f:
- 81 7c 24 08 40 02 00
- cmpl $0x240,0x8(%rsp) //把0x8(%rsp)的值和0x240比较,如果不相等,bomb,相等就正常跳转到 401095
- 400fa6:
- 00
- 400fa7:
- 0f 84 e8 00 00 00
- je 401095 <phase_3+0x13d></phase_3+0x13d>
OK, Phase_3 搞定 halfway there!
注意到phase_4会调用到func4
- 00000000004010a5 <func4>:
- 4010a5:
- 53
- push %rbx
- 4010a6:
- 89 fb
- mov %edi,%ebx
- 4010a8:
- b8 01 00 00 00
- mov $0x1,%eax
- 4010ad:
- 83 ff 01
- cmp $0x1,%edi
- 4010b0:
- 7e 0b
- jle 4010bd <func4+0x18>
- 4010b2:
- 8d 7f ff
- lea -0x1(%rdi),%edi
- 4010b5:
- e8 eb ff ff ff
- callq 4010a5 <func4>
- 4010ba:
- 0f af c3
- imul %ebx,%eax
- 4010bd:
- 5b
- pop %rbx
- 4010be:
- c3
- retq
- 00000000004010bf <phase_4>:
- 4010bf:
- 48 83 ec 18
- sub $0x18,%rsp
- 4010c3:
- 48 8d 54 24 0c
- lea 0xc(%rsp),%rdx
- 4010c8:
- be 74 1b 40 00
- mov $0x401b74,%esi
- 4010cd:
- b8 00 00 00 00
- mov $0x0,%eax
- 4010d2:
- e8 29 fb ff ff
- callq 400c00 <__isoc99_sscanf@plt>
- 4010d7:
- 83 f8 01
- cmp $0x1,%eax
- 4010da:
- 75 07
- jne 4010e3 <phase_4+0x24>
- 4010dc:
- 83 7c 24 0c 00
- cmpl $0x0,0xc(%rsp)
- 4010e1:
- 7f 05
- jg 4010e8 <phase_4+0x29>
- 4010e3:
- e8 fb 05 00 00
- callq 4016e3 <explode_bomb>
- 4010e8:
- 8b 7c 24 0c
- mov 0xc(%rsp),%edi
- 4010ec:
- e8 b4 ff ff ff
- callq 4010a5 <func4>
- 4010f1:
- 3d 00 5f 37 00
- cmp $0x375f00,%eax
- 4010f6:
- 74 05
- je 4010fd <phase_4+0x3e>
- 4010f8:
- e8 e6 05 00 00
- callq 4016e3 <explode_bomb>
- 4010fd:
- 48 83 c4 18
- add $0x18,%rsp
- 401101:
- c3
- retq </explode_bomb></phase_4+0x3e></func4></explode_bomb></phase_4+0x29></phase_4+0x24></phase_4></func4></func4+0x18></func4>
主题就是phase_4要求根据格式化字符串“%d”输入一个数字,这个数字传入func做递归乘法,相当于传入参数的阶乘.
最后
返回值和0x375f00比较,如果不相等就bomb,于是我们必须找到阶乘等于0x375f00的数字.
- 4010f1:
- 3d 00 5f 37 00
- cmp $0x375f00,%eax
的方法嘛.写个阶乘的C 函数去测试,什么输入参数的阶乘是0x375f00
- #include <stdio.h>
- int main()
- {
- int ans = 1;
- int tmp = 1;
- for(tmp = 1;ans != 0x375f00;tmp++)
- {
- ans *= tmp;
- }
- printf("%d \n",tmp-1);
- return 0;
- }</stdio.h>
- 0000000000401102 <phase_5>:
- 401102:
- 53
- push %rbx
- 401103:
- 48 89 fb
- mov %rdi,%rbx
- 401106:
- e8 e6 01 00 00
- callq 4012f1 <string_length>
- 40110b:
- 83 f8 06
- cmp $0x6,%eax //输入字符串的长度必须是6,否则bomb
- 40110e:
- 74 05
- je 401115 <phase_5+0x13>
- 401110:
- e8 ce 05 00 00
- callq 4016e3 <explode_bomb>
- 401115:
- b8 00 00 00 00
- mov $0x0,%eax // 把%eax %edx 寄存器赋值为0
- 40111a:
- ba 00 00 00 00
- mov $0x0,%edx
- 40111f:
- 0f b6 0c 03
- movzbl (%rbx,%rax,1),%ecx //%rbx + %rax*1 赋值给%ecx
- 401123:
- 83 e1 0f
- and $0xf,%ecx //取%ecx低4位赋值给%ecx
- 401126:
- 03 14 8d c0 1b 40 00
- add 0x401bc0(,%rcx,4),%edx
- 40112d:
- 48 83 c0 01
- add $0x1,%rax
- 401131:
- 48 83 f8 06
- cmp $0x6,%rax
- 401135:
- 75 e8
- jne 40111f <phase_5+0x1d>
- 401137:
- 83 fa 3e
- cmp $0x3e,%edx
- 40113a:
- 74 05
- je 401141 <phase_5+0x3f>
- 40113c:
- e8 a2 05 00 00
- callq 4016e3 <explode_bomb>
- 401141:
- 5b
- pop %rbx
- 401142:
- c3
- retq </explode_bomb></phase_5+0x3f></phase_5+0x1d></explode_bomb></phase_5+0x13></string_length></phase_5>
值得注意的是
这里又有个很特殊的地址0x401bc0
- 401126:
- 03 14 8d c0 1b 40 00
- add 0x401bc0(,%rcx,4),%edx
我尝试打印这里的数据,怀疑这里很可能是个数组
对于phase_5,概括性的说,就是输入6个ascii字符,然后这6个字符的低4位对应这个数组的index,然后对应数字累加要等于0x3e,即62
这里我的想法是62 = 2+2+10+16+16+16
对应的偏移量是001555
我们查看ascii码表可以发现,恰巧数字字符00155符合要求,于是输入00155
最后一关了!
- 0000000000401143 <fun6>:
- 401143:
- 48 89 f8
- mov %rdi,%rax
- 401146:
- 4c 8b 47 08
- mov 0x8(%rdi),%r8
- 40114a:
- 48 c7 47 08 00 00 00
- movq $0x0,0x8(%rdi)
- 401151:
- 00
- 401152:
- 4d 85 c0
- test %r8,%r8
- 401155:
- 75 48
- jne 40119f <fun6+0x5c>
- 401157:
- f3 c3
- repz retq
- 401159:
- 48 89 d1
- mov %rdx,%rcx
- 40115c:
- 48 8b 51 08
- mov 0x8(%rcx),%rdx
- 401160:
- 48 85 d2
- test %rdx,%rdx
- 401163:
- 74 09
- je 40116e <fun6+0x2b>
- 401165:
- 39 32
- cmp %esi,(%rdx)
- 401167:
- 7f f0
- jg 401159 <fun6+0x16>
- 401169:
- 48 89 d6
- mov %rdx,%rsi
- 40116c:
- eb 03
- jmp 401171 <fun6+0x2e>
- 40116e:
- 48 89 d6
- mov %rdx,%rsi
- 401171:
- 48 39 ce
- cmp %rcx,%rsi
- 401174:
- 74 06
- je 40117c <fun6+0x39>
- 401176:
- 4c 89 41 08
- mov %r8,0x8(%rcx)
- 40117a:
- eb 13
- jmp 40118f <fun6+0x4c>
- 40117c:
- 4c 89 c0
- mov %r8,%rax
- 40117f:
- eb 0e
- jmp 40118f <fun6+0x4c>
- 401181:
- 48 89 c2
- mov %rax,%rdx
- 401184:
- 4c 89 c0
- mov %r8,%rax
- 401187:
- eb 06
- jmp 40118f <fun6+0x4c>
- 401189:
- 48 89 c2
- mov %rax,%rdx
- 40118c:
- 4c 89 c0
- mov %r8,%rax
- 40118f:
- 49 8b 48 08
- mov 0x8(%r8),%rcx
- 401193:
- 49 89 50 08
- mov %rdx,0x8(%r8)
- 401197:
- 48 85 c9
- test %rcx,%rcx
- 40119a:
- 74 14
- je 4011b0 <fun6+0x6d>
- 40119c:
- 49 89 c8
- mov %rcx,%r8
- 40119f:
- 48 85 c0
- test %rax,%rax
- 4011a2:
- 74 dd
- je 401181 <fun6+0x3e>
- 4011a4:
- 41 8b 30
- mov (%r8),%esi
- 4011a7:
- 39 30
- cmp %esi,(%rax)
- 4011a9:
- 7e de
- jle 401189 <fun6+0x46>
- 4011ab:
- 48 89 c1
- mov %rax,%rcx
- 4011ae:
- eb ac
- jmp 40115c <fun6+0x19>
- 4011b0:
- f3 c3
- repz retq
- 00000000004011b2 <phase_6>:
- 4011b2:
- 48 83 ec 08
- sub $0x8,%rsp
- 4011b6:
- ba 0a 00 00 00
- mov $0xa,%edx
- 4011bb:
- be 00 00 00 00
- mov $0x0,%esi
- 4011c0:
- e8 1b fa ff ff
- callq 400be0 <strtol@plt>
- 4011c5:
- 89 05 55 21 20 00
- mov %eax,0x202155(%rip) # 603320 <node0>
- 4011cb:
- bf 20 33 60 00
- mov $0x603320,%edi
- 4011d0:
- e8 6e ff ff ff
- callq 401143 <fun6>
- 4011d5:
- 48 8b 40 08
- mov 0x8(%rax),%rax
- 4011d9:
- 8b 0d 41 21 20 00
- mov 0x202141(%rip),%ecx # 603320 <node0>
- 4011df:
- 39 08
- cmp %ecx,(%rax)
- 4011e1:
- 74 05
- je 4011e8 <phase_6+0x36>
- 4011e3:
- e8 fb 04 00 00
- callq 4016e3 <explode_bomb>
- 4011e8:
- 48 83 c4 08
- add $0x8,%rsp
- 4011ec:
- c3
- retq
- </explode_bomb></phase_6+0x36></node0></fun6></node0></strtol@plt></phase_6></fun6+0x19></fun6+0x46></fun6+0x3e></fun6+0x6d></fun6+0x4c></fun6+0x4c></fun6+0x4c></fun6+0x39></fun6+0x2e></fun6+0x16></fun6+0x2b></fun6+0x5c></fun6>
这步不要陷入到func6了,逐步的去gdb stepi nexti 调试就是了. 具体的调试方法不讲了
值得一提的就是这里
这里0x202155(%rip) 0x202141(%rip)都是指向同一个地址,这个地址储存着输入数据
- 4011c5:
- 89 05 55 21 20 00
- mov %eax,0x202155(%rip) # 603320 <node0>
- 4011d9:
- 8b 0d 41 21 20 00
- mov 0x202141(%rip),%ecx # 603320 <node0></node0></node0>
最后这里比较的时候,直接gdb查看%rax指向的地址存的什么东东,
- cmp %ecx,(%rax)
打印出来
826!于是我们就应该输入826
其实应该还有个彩蛋——secrete phase
我目前~没心思看了,过两天继续更新
*****************************************************************************************************************************
参考资料——向所有前辈致敬, sharing,step together! open source!
逆向工程——二进制*(CSAPP Project)
http://www.cnblogs.com/remlostime/archive/2011/05/21/2052708.html
http://blog.csdn.net/u013648407/article/details/24845129
CSAPP:二进制*实验 lycos的六度空间
http://blog.csdn.net/caoxu1987728/article/details/6056947
最后感谢
呵呵,国内的某些大学学着点别人的风度.
***************************************************************************************************************************