CS:APP二进制炸弹phase3

来源:互联网 发布:js对象数组按属性排序 编辑:程序博客网 时间:2024/06/04 19:12

写在前面

到目前为止,已经比较轻松的完成了前两个阶段。本文来试试第三个阶段吧。let's go !!!


分析

还是一样,先找到调用phase_3处的汇编:


继续反汇编函数phase_3如下:


函数phase_3一走来就调用了sscanf函数来读取我们的输入。有了分析phase_2的经验,很容易从寄存器%esi中获得格式化字符串,x/s显示的结果是"%d %d",即从我们的输入中获得两个int型整数。我们不妨将第一个整数命令为num1,第二个为num2。

紧接着判断sscanf的返回值,如果小于等于1,则触发炸弹。否则继续。

cmpl   $0x7,0x8(%rsp),判断num1是否大于7,如果大于,则调整到地址0x0000000000400fad处,触发炸弹。否则继续。

接下来的两条指令是难点,如果搞懂了这两条指令就差不多了。第一条指令,mov    0x8(%rsp),%eax,将num1的值存储寄存器%eax中,第二条指令jmpq  *0x402470(,%rax,8),这条指令什么意思呢? 可能AT&T的汇编指令不太容易看懂,那我们通过set disassembly-flavor intel来查看intel形式的这条指令为jmp    QWORD PTR [rax*8+0x402470],这下就容易多了 -- 取出地址rax*8+0x402470处的值,并调转到这个值指示的内存地址处继续执行。如果读者有一点点的经验,就可以很容易看出此处是switch语句的跳转表,跳转表的首地址为0x402470,我们可以通过x命令看看这个表中都存储了哪些地址。


因为上面判断num1小于8,因此可知跳转表中应该存储有8个地址。x表明以十六进制的形式显示地址,g表示每8个字节的内存,因为这是x64平台,所以地址占8个字节。

仔细观察这些地址,可以发现都是函数phase_3范围内的地址。

当num1等于0时,跳转到0x0000000000400f7c处执行。如果num2不等于0xcf,则触发炸弹。

当num1等于1时,跳转到0x0000000000400fb9处执行。如果num2不等于0x137,则触发炸弹。

当num1等于2时,跳转到0x0000000000400f83处执行。如果num2不等于0x2c3,则触发炸弹。

当num1等于3时,跳转到0x0000000000400f8a处执行。如果num2不等于0x100,则触发炸弹。

当num1等于4时,跳转到0x0000000000400f91处执行。如果num2不等于0x185,则触发炸弹。

当num1等于5时,跳转到0x0000000000400f98处执行。如果num2不等于0xce,则触发炸弹。

当num1等于6时,跳转到0x0000000000400f9f处执行。如果num2不等于0x2aa,则触发炸弹。

当num1邓毅7时,跳转到0x0000000000400fa6处执行。如果num2不等于0x147,则触发炸弹。

因此可以得出这个阶段的答案有8种,任选其一。分别为(0,207)、(1,311)、(2,707)、(3,256)、(4,389)、(5,206)、(6,682)、(7,327)。

C源码应该如下所示:

void phase_3(const char *input){//  0x8(%rsp)  0xc(%rsp)int num1, num2;//     %rdi     %rsi   %rdx   %rcx int result = sscnaf(input, "%d %d", &num1, &num2);if (result <= 1) {explode_bomb();}switch (num1) {case 0:// 0 207if (num2 != 0xcf) {explode_bomb();}break;case 1:// 1 311if (num2 != 0x137) {explode_bomb();}break;case 2:// 2 707if (num2 != 0x2c3) {explode_bomb();}break;case 3:// 3 256if (num2 != 0x100) {explode_bomb();}break;case 4:// 4 389if (num2 != 0x185) {explode_bomb();}break;case 5:// 5 206if (num2 != 0xce) {explode_bomb();}break;case 6:// 6 682if (num2 != 0x2aa) {explode_bomb();}break;case 7:// 7 327if (num2 != 0x147) {explode_bomb();}break;default:explode_bomb();break;}}

总结:

本阶段主要考察switch语句的跳转表,如果能迅速察觉到,没什么难度!继续下一个阶段吧!

原创粉丝点击