CSAPP lab2 二进制拆弹 binary bombs phase_3
给出对应于7个阶段的7篇博客
phase_1 https://www.cnblogs.com/wkfvawl/p/10632044.html
phase_2 https://www.cnblogs.com/wkfvawl/p/10636214.html
phase_3 https://www.cnblogs.com/wkfvawl/p/10651205.html
phase_4 https://www.cnblogs.com/wkfvawl/p/10672680.html
phase_5 https://www.cnblogs.com/wkfvawl/p/10703941.html
phase_6 https://www.cnblogs.com/wkfvawl/p/10742405.html
secret_phase https://www.cnblogs.com/wkfvawl/p/10745307.html
phase_3
phase_3要求输入包含1个小于10的整数,一个整数的字符串。phase_2函数从中读取这些信息,并判断其正确性,如果不正确,则炸弹爆炸。
phase_3主要考察学生对C语言条件/分支的机器级表示的掌握程度。
观察框架源文件bomb.c:
从上可以看出:
1、首先调用了read_line()函数,用于输入炸弹秘钥,输入放置在char* input中。
2、调用phase_3函数,输入参数即为input,可以初步判断,phase_3函数将输入的input字符串作为参数。
因此下一步的主要任务是从asm.txt中查找在哪个地方调用了readline函数以及phase_3函数。
1.1 寻找并分析调用phase_3函数的代码
打开asm.txt,寻找phase_3函数。
和phase_1类似分析:
1、当前栈的位置存放的是read_line函数读入的一串输入;
2、phase_3的函数入口地址为0x8048c72。
此时的函数栈为:
1.2 phase_3函数分析
寻找8048c72,或者继续寻找phase_3,可以寻找到phase_3函数,如下图所示:
1、第421~431行:初始化函数栈帧,同时为调用sscanf准备参数。之后,函数栈帧如下所示:
1)esp + 4的地方,存放的是0x804a689,其对应的字符串为“%d%d”(其分析过程参见phase_2,不再赘述);
2)esp + 8的地方实际的内容是esp + 0x18(是esp + 0x18地址的内容的地址),esp + c内容是esp + 0x1c。
3)参考phase读取6个整数的分析,可以认为前面几个参数都是为调用sscanf准备参数:sscanf(input, "%d %d", &d1, &d2),其中&d1对应18(%esp),&c对应1c(%esp)。
4)因此,可以看出18(%esp)、1c(%esp)分别对应于d1、d2。也即sscanf最终读取的数据分别放置于栈帧中的这两个个地方,在后面的代码分析中,均以d1以及d2来代替这三个地址的内容。
2、第431-433行:判断sscanf返回结果是否大于1,如果不是,则explode_bomb。如果大于,则认为输入正确,跳转到<phase_3 + 0x31>(8048ca3)-->第434行。
3、第434行(phase_3 + 0x39)及435行:d1与7相比较,大于则跳转到<phase_3 + 0x9e>(8048d10)(引爆炸弹),也即d1应该小于等于7。、
4、第436-437行:将d1送给eax,跳转到0x804a450 + d1 * 4的内容所指示的地址。使用objdump --start-address=0x804a450 -s bomb查看0x804a450的内容,如下图所示:
显然,后面连续的8个32位的数值分别指向的地址是08048cbc、08048cb5、08048cc8、08048cd4、08048ce0、08048cec、08048cf8、08048d04(注意:IA32为小端表示低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。),分别对应于d1为0~7。显然这一块应该是一个swich-case的机器级表示。(参见袁春风老师《选择及循环语句的机器级表示》)
这里以d1等于3为例,d2初值赋为0,然后-18c,之后不断跳转+18c,-18c,+18c,-18c,最终结果是-18c,也就是-396
第446行初始d2赋值为0。
第447行进行-18c。
第478行执行跳转到地址8048ce5,即第450行的位置。
第450行执行+18c。
第451行执行跳转到地址8048cf1,即第453行的位置。
第453行执行-18c
第454行执行跳转到地址8048cfd,即第456行的位置。
第456行执行+18c
第457行执行跳转到地址8048d09,即第459行的位置。
第459行执行-18c
第460行执行跳转到地址8048d1a,即第463行的位置。
第463行先确定d1不大于5,之后第465行比较判断此时的d2,此时d2为-18c,即-396