CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 4
来源:互联网 发布:阿里云搭建http代理 编辑:程序博客网 时间:2024/05/02 04:26
先看看phase_4做了什么:
000000000040100c <phase_4>: 40100c: 48 83 ec 18 sub $0x18,%rsp 401010: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx 401015: 48 8d 54 24 08 lea 0x8(%rsp),%rdx 40101a: be cf 25 40 00 mov $0x4025cf,%esi 40101f: b8 00 00 00 00 mov $0x0,%eax 401024: e8 c7 fb ff ff callq 400bf0 <__isoc99_sscanf@plt> 401029: 83 f8 02 cmp $0x2,%eax 40102c: 75 07 jne 401035 <phase_4+0x29> 40102e: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp) 401033: 76 05 jbe 40103a <phase_4+0x2e> # 0<=num1<=14 401035: e8 00 04 00 00 callq 40143a <explode_bomb> 40103a: ba 0e 00 00 00 mov $0xe,%edx 40103f: be 00 00 00 00 mov $0x0,%esi 401044: 8b 7c 24 08 mov 0x8(%rsp),%edi 401048: e8 81 ff ff ff callq 400fce <func4> 40104d: 85 c0 test %eax,%eax 40104f: 75 07 jne 401058 <phase_4+0x4c> # %rax must be 0 401051: 83 7c 24 0c 00 cmpl $0x0,0xc(%rsp) # the second num must be 0 401056: 74 05 je 40105d <phase_4+0x51> 401058: e8 dd 03 00 00 callq 40143a <explode_bomb> 40105d: 48 83 c4 18 add $0x18,%rsp 401061: c3 retq同样将rcx和rdx这两个参数设置好后调用sscanf扫入两个整型数(通过查看0x4025cf也可以验证这一点),并且从401029可以看出必为2个,否则触雷
第一个数字存在rsp+8的位置上,在401033可以看出,jbe将其作为无符号数比较,满足条件才能跳过炸弹,这使得第一个数不能小于0,也不能大于14
其后edx被设为14,esi为0,edi为我们输入的第一个数,然后调用func4:
0000000000400fce <func4>: 400fce:48 83 ec 08 sub $0x8,%rsp 400fd2:89 d0 mov %edx,%eax 400fd4:29 f0 sub %esi,%eax 400fd6:89 c1 mov %eax,%ecx 400fd8:c1 e9 1f shr $0x1f,%ecx 400fdb:01 c8 add %ecx,%eax 400fdd:d1 f8 sar %eax 400fdf:8d 0c 30 lea (%rax,%rsi,1),%ecx 400fe2:39 f9 cmp %edi,%ecx 400fe4:7e 0c jle 400ff2 <func4+0x24> 400fe6:8d 51 ff lea -0x1(%rcx),%edx 400fe9:e8 e0 ff ff ff callq 400fce <func4> 400fee:01 c0 add %eax,%eax 400ff0:eb 15 jmp 401007 <func4+0x39> 400ff2:b8 00 00 00 00 mov $0x0,%eax 400ff7:39 f9 cmp %edi,%ecx 400ff9:7d 0c jge 401007 <func4+0x39> 400ffb:8d 71 01 lea 0x1(%rcx),%esi 400ffe:e8 cb ff ff ff callq 400fce <func4> 401003:8d 44 00 01 lea 0x1(%rax,%rax,1),%eax 401007:48 83 c4 08 add $0x8,%rsp 40100b:c3 retq这个函数做的事情,从400fd2到400fdf是将edx赋值给eax,eax减去esi,然后将eax赋值给ecx,ecx逻辑右移31位(也就是说,它在eax小于0时变为1,否则为0)
接着将eax加上ecx,然后eax除以2,将eax+esi的值赋给ecx
关键的地方400fe2,将此时的ecx与我们输入的第一个数(存在edi那里)作比较,不妨先假设我们输入的数较小会发生什么:
400fe4的jump不会被采用,下一步时将ecx-1赋值给edx后,再调用func4
总结一下,进行到这一步时,rax、rdx和rcx这三个变量,在phase_4中分别为0 14 rsp+12 已经分别变成了7 6 7
也就是,如果要让ecx比第一个数大,我们的数要小于7才行
那接下来会发生什么?调用func4,同样的套路,rax rdx rcx会变成3 2 3
如果我们输入的数比3还要小,又调用func4: rax rdx rcx就成了1 0 1
如果我们输入的数干脆是0:rax rdx rcx成了0 -1 0
这样肯定可以满足ecx<=edi,看看接下来又发生什么
jbe满足,跳到400ff2,eax被赋值为0,
关键又来了,400ff7处比较ecx和edi:
如果ecx大于等于edi(假设我们输入的数是0,显然这时ecx也是0能满足),直接跳到401007结束了,这时eax是0
回到之前存有另外几个func4的栈,类似逐一跳出,400fee处eax乘以2不改变它是0
回到phase_4的40104d,类似我们在phase_1中看到的,需要ZF为0才能避免满足jne的条件触雷,也就是说eax必须为0,这个条件满足
其后401051可见,第二个数必须为0,否则会在401058无法跳过触雷
这样我们就确定了一个解:0 0
如果我们仔细看400fe2和400ff7两处cmp命令及紧跟的jle和jge,不难发现如果edi和ecx两个参数相等,就能直接跳过两次结束func4了,并且400ff2处eax也被赋予了0
可以看出,每次递归调用func4后如果经过处理的ecx能与我们输入的第一个数相等,就能返回正确结果
这样另外几个正确解就是:
1 0
3 0
7 0
有没有其他的解呢?如果我们输入的第一个数大于7,在[8,14]上,那么代入计算可知,ecx会不断变大。
eax edx ecx esi的变化规律是(以输入14为例)(每次在第一个cmp后跳到400ff2前)
7 14 7 8
3 14 11 12
1 14 13 14
0 14 14(这时第二个cmp后jge也满足,故将eax乘以2加1跳出)
但不管在哪一组参数时跳出,在401003处eax都要被赋予2*eax+1的值,这决定了eax最后都不会等于0。
如果第一个数在[0,7]上而有别于之前的正确解呢? 根据之前总结过的,我们知道func4会递归调用到某一层使得ecx小于第一个数,然后满足了第一个jle的条件使得跳到400ff2,进入第二个cmp,这回到了我们上面讲过的类似情况,同样的,由于一定会在第二个cmp后调用过func4后,将eax乘以2加上1,
因此eax不可能返回为0,因此回到第一层func4,400fee处将eax乘以2,eax也不可能为0
所以正确的结果只有:
0 0
1 0
3 0
7 0
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 4
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 1
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 2
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 3
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 6
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 5
- CSAPP3e - x86-64 assembly code analysis - Attack Lab: Level I
- CSAPP3e - x86-64 assembly code analysis - Attack Lab: Level II
- CSAPP: Bomb Lab(4)
- Bomb lab
- CSAPP3e - integer and floating point - Data Lab
- CMU bomb lab
- CSAPP: bomb lab
- ICS bomb lab总结
- CSAPP Bomb Lab
- x86 assembly
- lab code
- CSAPP: Bomb Lab(1)
- 二分思路总结
- Spring学习(十三)Spring Bean 的命名方式介绍
- 内省(Introspector)操作JavaBean的属性
- 内省—beanutils工具包 操作javabean属性
- epub是什么文件?epub文件怎么打开?
- CSAPP3e - x86-64 assembly code analysis - Bomb Lab: phase 4
- Jackson入门教程
- 给定一个未排序的整数数组,找到其中位数。 中位数是排序后数组的中间值,
- C语言学习篇-9指针运算、指针与数组
- C语言到c++的第一步 注释转换
- POJ 2688 Cleaning Robot
- java socket实现文件的上传和下载试例
- 两款JSON类库Jackson与JSON-lib的性能对比
- 工厂模式