计算机系统原理的实验,参考了我的前舍友和不知道哪位同学的博客,不过写得也太简略了并且还有一些错误,更像是单纯的记录,对手头没代码的人大概没啥意义吧。所以就把我自己做时的带注释的代码贴住来吧,也不过是记录罢了。
两位同学的博客:
MIPS - 反汇编 - 拆炸弹 - bomb(如你所见直接把标题抄过来了)
bomb二进制炸弹拆除实验(MIPS)
如果有同校学弟做实验时看到这篇博客,还是希望可以先尽量尝试独立完成,实在没办法时再来参考。如有错误,欢迎指正。

前导知识

gdb操作请看:GDB汇编调试指令合集
MIPS相关知识请看:MIPS指令集及汇编完全解析

开拆前…

本实验含有六个炸弹(和一个隐藏炸弹 ),在运行程序开头,需要输入ID(学号),在之后的拆弹过程中会使用到。每个炸弹都需要输入一行数据,包括数字或字符串。需避开一个个引爆点来通关。
阅读反汇编代码时,最好能够前后联系,理解数行/一部分代码的功能。要逐渐熟练掌握MIPS指令集操作和寄存器含义,了解数据存储的位置和方式。
有???标记的是我暂时抱有疑惑的地方,可以忽视。
本文还未完成,随缘更新。

phase_1

第一个炸弹,主要是熟悉用。炸弹会调用函数strings_not_equal来比较输入字符串与存储的字符串是否相等,不需要理解该子函数的实现,只需要明白该函数的功能即可。读寄存器$a1中保存的字符串,为“Let’s begin now!”,即为我们要输入的内容。

00400900 <main>:...400ba4: 8fdc0010  lw  gp,16(s8)400ba8: 0c1007fb  jal 401fec <read_line> //读取输入400bac: 00000000  nop400bb0: 8fdc0010  lw  gp,16(s8)400bb4: afc20020  sw  v0,32(s8) //将读得的数据存入栈400bb8: 8fc40020  lw  a0,32(s8) //并放入$a0中供函数phase_1使用400bbc: 0c10035b  jal 400d6c <phase_1>...00400d6c <phase_1>:400d6c: 27bdffe0    addiu   sp,sp,-32 //为当前函数开辟栈空间400d70:   afbf001c    sw  ra,28(sp)400d74:    afbe0018    sw  s8,24(sp)400d78:    03a0f021    move    s8,sp400d7c:    afc40020    sw  a0,32(s8) //将$a0的内容存入栈400d80:   8fc40020    lw  a0,32(s8)400d84:    3c020040    lui v0,0x40400d88:  2445276c    addiu   a1,v0,10092 //加载参数到$a1400d8c:   0c10073e    jal 401cf8 <strings_not_equal> //比较字符串$a0和$a1,不相等则$v0 = 1,否则$v0 = 1400d90:    00000000    nop400d94:  10400003    beqz    v0,400da4 <phase_1+0x38> //若$v0 == 0则跳至0x00400da4处400d98:  00000000    nop400d9c:  0c10087c    jal 4021f0 <explode_bomb> //否则若$v0 == 0则爆炸400da0:   00000000    nop400da4:  03c0e821    move    sp,s8400da8:    8fbf001c    lw  ra,28(sp)400dac:    8fbe0018    lw  s8,24(sp)400db0:    27bd0020    addiu   sp,sp,32400db4: 03e00008    jr  ra400db8:   00000000    nop

phase_2

该炸弹要求我们输入六个数字(看函数名称识功能,第1个数必须为1),之后进入循环中一个个对这些数字进行处理,将第i个数分别与学号倒数i位相乘结果与第i+1个数比较判断是否相等,意味着我们输入的六个数就是对ID后五位累乘的序列。为什么知道是ID后五位?读寄存器得到的。ID不够五位?那就相当于定义了一个变量却没有赋值,一样能解决这个炸弹。这个炸弹不理解代码强行在0x400e80处读$a0的值并反复尝试令其与$v0相等也能解决,当然不推荐就是了。

00400dbc <phase_2>:400dbc: 27bdffc0    addiu   sp,sp,-64400dc0:    afbf003c    sw  ra,60(sp)400dc4:    afbe0038    sw  s8,56(sp)400dc8:    03a0f021    move    s8,sp400dcc:    3c1c0042    lui gp,0x42400dd0:  279cb190    addiu   gp,gp,-20080400dd4: afbc0010    sw  gp,16(sp)400dd8:    afc40040    sw  a0,64(s8)400ddc:    27c2001c    addiu   v0,s8,28400de0: 8fc40040    lw  a0,64(s8)400de4:    00402821    move    a1,v0400de8:    0c1006ea    jal 401ba8 <read_six_numbers> //读入6个数字400dec: 00000000    nop400df0:  8fdc0010    lw  gp,16(s8)400df4:    8fc3001c    lw  v1,28(s8) //m[$s8+28]存有读入的第一个数,将其存入$v1400df8:   24020001    li  v0,1400dfc: 10620004    beq v1,v0,400e10 <phase_2+0x54> //判定$v1是否为1,不是则引爆400e00:  00000000    nop400e04:  0c10087c    jal 4021f0 <explode_bomb>400e08:  00000000    nop400e0c:  8fdc0010    lw  gp,16(s8)400e10:    24020001    li  v0,1 //设定循环单次表达式$v0 = 1(i = 1)400e14: afc20018    sw  v0,24(s8) //将$v0(i)存入栈400e18:   10000023    b   400ea8 <phase_2+0xec> //循环开始,跳至条件表达式400e1c:   00000000    nop400e20:  8fc20018    lw  v0,24(s8) //将之前存在栈中的变量i取出400e24:    00000000    nop400e28:  2442ffff    addiu   v0,v0,-1 //$v0自减400e2c: 00021080    sll v0,v0,0x2 //$v0 = $v0 * 4(拓到1 int长度)400e30:  27c30018    addiu   v1,s8,24 //第i个数的存放位置为m[$s8 + 24 + i * 4](一个int型变量占4个字节)400e34:  00621021    addu    v0,v1,v0400e38: 8c440004    lw  a0,4(v0) //将第i个数的值存入$a0(所以前面自减有意义吗)400e3c:  2403000c    li  v1,12400e40:    8fc20018    lw  v0,24(s8) //将之前存在栈中的变量i取出400e44:    00000000    nop400e48:  00621023    subu    v0,v1,v0 //$v0 = $v1(12) - $v0(i)400e4c:   8f83806c    lw  v1,-32660(gp) //读得输入的学号400e50:  00021080    sll v0,v0,0x2 //$v0 = $v0 * 4(拓到1 int长度)400e54:  00621021    addu    v0,v1,v0 //$v0 = $v1 + $v0400e58: 8c420000    lw  v0,0(v0) //将学号的倒数i位读入$v0中400e5c:    00000000    nop400e60:  00820018    mult    a0,v0 //$a0与$v0相乘400e64:    00002012    mflo    a0 //将结果存入$a0400e68:    8fc20018    lw  v0,24(s8) //将之前存在栈中的变量i取出400e6c:    00000000    nop400e70:  00021080    sll v0,v0,0x2 //$v0 = $v0 * 4(拓到1 int长度)400e74:  27c30018    addiu   v1,s8,24 //第i个数得存放位置为m[$s8 + 24 + i * 4](一个int型变量占4个字节)400e78:  00621021    addu    v0,v1,v0 //得到第i个数的位置400e7c: 8c420004    lw  v0,4(v0) //将第i + 1个数的值存入$v0400e80: 00000000    nop400e84:  10820004    beq a0,v0,400e98 <phase_2+0xdc> //比较$a0(第i个数与学号的倒数i位相乘的结果)与$v0(第i + 1个数),若不相等则引爆400e88:    00000000    nop400e8c:  0c10087c    jal 4021f0 <explode_bomb>400e90:  00000000    nop400e94:  8fdc0010    lw  gp,16(s8) //末尾循环体400e98:    8fc20018    lw  v0,24(s8)400e9c:    00000000    nop400ea0:  24420001    addiu   v0,v0,1 //i自加400ea4:    afc20018    sw  v0,24(s8) //将i存入栈中400ea8:   8fc20018    lw  v0,24(s8)400eac:    00000000    nop400eb0:  28420006    slti    v0,v0,6 //判断循环是否结束,相当于i != 6(i < 6)400eb4:   1440ffda    bnez    v0,400e20 <phase_2+0x64>400eb8:  00000000    nop400ebc:  03c0e821    move    sp,s8400ec0:    8fbf003c    lw  ra,60(sp)400ec4:    8fbe0038    lw  s8,56(sp)400ec8:    27bd0040    addiu   sp,sp,64400ecc: 03e00008    jr  ra400ed0:   00000000    nop

phase_3

考察分支结构(switch…case…结构)。要求输入格式为"%d %c %d"(看调用数据时的指令得到的,word/byte的区别),第一个数就是switch语句中的变量,跳至不同的case语句(0到7共八个,超出直接引爆)。除case 3外,其他数均是要求一个数与输入的第三个数相乘的结果为指定的立即数,而case 3要求相乘结果为0。读寄存器可知该数为输入ID的最后一位。另外在每个case结构的开头都将一个字符存入栈中,在switch…case…结束后与我们输入的字符比较,令两个字符相等即可。

00400ed4 <phase_3>:400ed4: 27bdffc8    addiu   sp,sp,-56400ed8:    afbf0034    sw  ra,52(sp)400edc:    afbe0030    sw  s8,48(sp)400ee0:    03a0f021    move    s8,sp400ee4:    3c1c0042    lui gp,0x42400ee8:  279cb190    addiu   gp,gp,-20080400eec: afbc0018    sw  gp,24(sp)400ef0:    afc40038    sw  a0,56(s8)400ef4:    8fc40038    lw  a0,56(s8)400ef8:    3c020040    lui v0,0x40400efc:  24452780    addiu   a1,v0,10112400f00:  27c3002c    addiu   v1,s8,44400f04: 27c20028    addiu   v0,s8,40400f08: 27c60024    addiu   a2,s8,36400f0c: afa60010    sw  a2,16(sp)400f10:    00603021    move    a2,v1400f14:    00403821    move    a3,v0400f18:    8f828084    lw  v0,-32636(gp)400f1c:    00000000    nop400f20:  0040c821    move    t9,v0400f24:    0320f809    jalr    t9400f28:   00000000    nop400f2c:  8fdc0018    lw  gp,24(s8)400f30:    28420003    slti    v0,v0,3 //判定输入的数据个数是否为3400f34:  10400004    beqz    v0,400f48 <phase_3+0x74>400f38:  00000000    nop400f3c:  0c10087c    jal 4021f0 <explode_bomb>400f40:  00000000    nop400f44:  8fdc0018    lw  gp,24(s8)400f48:    8fc2002c    lw  v0,44(s8) //读入输入的第一个数至$v0400f4c:    00000000    nop400f50:  2c430008    sltiu   v1,v0,8 //判断$v0是否小于8,是则继续,否则引爆400f54:   1060008e    beqz    v1,401190 <phase_3+0x2bc>400f58: 00000000    nop400f5c:  00021880    sll v1,v0,0x2 //$v1 = $v0 * 4,拓至1 int型变量长度400f60:   3c020040    lui v0,0x40400f64:  2442278c    addiu   v0,v0,10124400f68:  00621021    addu    v0,v1,v0400f6c: 8c420000    lw  v0,0(v0) //$v0对应case语句的地址,用x $v0查看400f70:    00000000    nop400f74:  00400008    jr  v0 //switch语句,跳至相应的case语句400f78: 00000000    nop //case 0:400f7c:    24020071    li  v0,113 //q的ASCII码400f80:    a3c20020    sb  v0,32(s8) //存入1byte的数据400f84:   8f82806c    lw  v0,-32660(gp)400f88:    00000000    nop400f8c:  8c43002c    lw  v1,44(v0) //读入学号的最后一位400f90:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数400f94:  00000000    nop400f98:  00620018    mult    v1,v0400f9c:    00001812    mflo    v1 //$v1 = $v1 * $v0400fa0:    24020309    li  v0,777 //判断是否为777(=3*=7*111),是则break,否则引爆400fa4:    10620081    beq v1,v0,4011ac <phase_3+0x2d8>400fa8:  00000000    nop400fac:  0c10087c    jal 4021f0 <explode_bomb>400fb0:  00000000    nop400fb4:  8fdc0018    lw  gp,24(s8)400fb8:    1000008f    b   4011f8 <phase_3+0x324>400fbc:    00000000    nop //case 1:400fc0:    24020062    li  v0,98 //b的ASCII码400fc4: a3c20020    sb  v0,32(s8) //存入1byte的数据400fc8:   8f82806c    lw  v0,-32660(gp)400fcc:    00000000    nop400fd0:  8c43002c    lw  v1,44(v0) //读入学号的最后一位400fd4:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数400fd8:  00000000    nop400fdc:  00620018    mult    v1,v0400fe0:    00001812    mflo    v1 //$v1 = $v1 * $v0400fe4:    240200d6    li  v0,214 //判断是否为214(=2*107),是则break,否则引爆400fe8:    10620073    beq v1,v0,4011b8 <phase_3+0x2e4>400fec:  00000000    nop400ff0:  0c10087c    jal 4021f0 <explode_bomb>400ff4:  00000000    nop400ff8:  8fdc0018    lw  gp,24(s8)400ffc:    1000007e    b   4011f8 <phase_3+0x324>401000:    00000000    nop //case 2:401004:    24020062    li  v0,98 //b的ASCII码401008: a3c20020    sb  v0,32(s8) //存入1byte的数据40100c:   8f82806c    lw  v0,-32660(gp)401010:    00000000    nop401014:  8c43002c    lw  v1,44(v0) //读入学号的最后一位401018:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数40101c:  00000000    nop401020:  00620018    mult    v1,v0401024:    00001812    mflo    v1 //$v1 = $v1 * $v0401028:    240202f3    li  v0,755 //判断是否为755(=5*151),是则break,否则引爆40102c:    10620065    beq v1,v0,4011c4 <phase_3+0x2f0>401030:  00000000    nop401034:  0c10087c    jal 4021f0 <explode_bomb>401038:  00000000    nop40103c:  8fdc0018    lw  gp,24(s8)401040:    1000006d    b   4011f8 <phase_3+0x324>401044:    00000000    nop //case 3:401048:    2402006b    li  v0,107 //k的ASCII码40104c:    a3c20020    sb  v0,32(s8) //存入1byte的数据401050:   8f82806c    lw  v0,-32660(gp)401054:    00000000    nop401058:  8c43002c    lw  v1,44(v0) //读入学号的最后一位40105c:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数401060:  00000000    nop401064:  00620018    mult    v1,v0401068:    00001012    mflo    v0 //$v0 = $v1 * $v040106c:    10400058    beqz    v0,4011d0 <phase_3+0x2fc> //判断$v0是否等于0,是则break,否则引爆401070: 00000000    nop401074:  0c10087c    jal 4021f0 <explode_bomb>401078:  00000000    nop40107c:  8fdc0018    lw  gp,24(s8)401080:    1000005d    b   4011f8 <phase_3+0x324>401084:    00000000    nop //case 4:401088:    2402006f    li  v0,111 //o的ASCII码40108c:    a3c20020    sb  v0,32(s8) //存入1byte的数据401090:   8f82806c    lw  v0,-32660(gp)401094:    00000000    nop401098:  8c43002c    lw  v1,44(v0) //读入学号的最后一位40109c:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数4010a0:  00000000    nop4010a4:  00620018    mult    v1,v04010a8:    00001812    mflo    v1 //$v1 = $v1 * $v04010ac:    240200e4    li  v0,228 //判断是否为228(=2*114=4*57),是则break,否则引爆 ???4010b0:  1062004a    beq v1,v0,4011dc <phase_3+0x308>4010b4:  00000000    nop4010b8:  0c10087c    jal 4021f0 <explode_bomb>4010bc:  00000000    nop4010c0:  8fdc0018    lw  gp,24(s8)4010c4:    1000004c    b   4011f8 <phase_3+0x324>4010c8:    00000000    nop //case 5:4010cc:    24020074    li  v0,116 //t的ASCII码4010d0:    a3c20020    sb  v0,32(s8) //存入1byte的数据4010d4:   8f82806c    lw  v0,-32660(gp)4010d8:    00000000    nop4010dc:  8c43002c    lw  v1,44(v0) //读入学号的最后一位4010e0:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数4010e4:  00000000    nop4010e8:  00620018    mult    v1,v04010ec:    00001812    mflo    v1 //$v1 = $v1 * $v04010f0:    24020201    li  v0,513 //判断是否为513(=3*171=9*57),是则break,否则引爆4010f4:  1062003c    beq v1,v0,4011e8 <phase_3+0x314>4010f8:  00000000    nop4010fc:  0c10087c    jal 4021f0 <explode_bomb>401100:  00000000    nop401104:  8fdc0018    lw  gp,24(s8)401108:    1000003b    b   4011f8 <phase_3+0x324>40110c:    00000000    nop //case 6:401110:    24020076    li  v0,118 //v的ASCII码401114:    a3c20020    sb  v0,32(s8) //存入1byte的数据401118:   8f82806c    lw  v0,-32660(gp)40111c:    00000000    nop401120:  8c43002c    lw  v1,44(v0) //读入学号的最后一位401124:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数401128:  00000000    nop40112c:  00620018    mult    v1,v0401130:    00001812    mflo    v1 //$v1 = $v1 * $v0401134:    2402030c    li  v0,780 //判断是否为780(=2*390=3*260=4*195=5*156=6*130),是则break,否则引爆401138:    10620004    beq v1,v0,40114c <phase_3+0x278>40113c:  00000000    nop401140:  0c10087c    jal 4021f0 <explode_bomb>401144:  00000000    nop //case 7:401148:    8fdc0018    lw  gp,24(s8) ???40114c:    24020062    li  v0,98 //b的ASCII码401150: a3c20020    sb  v0,32(s8) //存入1byte的数据401154:   8f82806c    lw  v0,-32660(gp)401158:    00000000    nop40115c:  8c43002c    lw  v1,44(v0) //读入学号的最后一位401160:    8fc20024    lw  v0,36(s8) //读入输入数据的第三个数401164:  00000000    nop401168:  00620018    mult    v1,v040116c:    00001812    mflo    v1 //$v1 = $v1 * $v0401170:    24020338    li  v0,824 //判断是否为824(=2*412=4*206),是则break,否则引爆401174: 1062001f    beq v1,v0,4011f4 <phase_3+0x320>401178:  00000000    nop40117c:  0c10087c    jal 4021f0 <explode_bomb>401180:  00000000    nop401184:  8fdc0018    lw  gp,24(s8)401188:    1000001b    b   4011f8 <phase_3+0x324>40118c:    00000000    nop401190:  24020078    li  v0,120401194:   a3c20020    sb  v0,32(s8)401198:    0c10087c    jal 4021f0 <explode_bomb>40119c:  00000000    nop4011a0:  8fdc0018    lw  gp,24(s8)4011a4:    10000014    b   4011f8 <phase_3+0x324>4011a8:    00000000    nop4011ac:  00000000    nop4011b0:  10000011    b   4011f8 <phase_3+0x324>4011b4:    00000000    nop4011b8:  00000000    nop4011bc:  1000000e    b   4011f8 <phase_3+0x324>4011c0:    00000000    nop4011c4:  00000000    nop4011c8:  1000000b    b   4011f8 <phase_3+0x324>4011cc:    00000000    nop4011d0:  00000000    nop4011d4:  10000008    b   4011f8 <phase_3+0x324>4011d8:    00000000    nop4011dc:  00000000    nop4011e0:  10000005    b   4011f8 <phase_3+0x324>4011e4:    00000000    nop4011e8:  00000000    nop4011ec:  10000002    b   4011f8 <phase_3+0x324>4011f0:    00000000    nop4011f4:  00000000    nop4011f8:  83c20028    lb  v0,40(s8) //输入的第二个字符数据4011fc:   83c30020    lb  v1,32(s8) //将case语句中存的字符取出401200:   00000000    nop401204:  10620004    beq v1,v0,401218 <phase_3+0x344> //比较,不相等则引爆401208:   00000000    nop40120c:  0c10087c    jal 4021f0 <explode_bomb>401210:  00000000    nop401214:  8fdc0018    lw  gp,24(s8)401218:    03c0e821    move    sp,s840121c:    8fbf0034    lw  ra,52(sp)401220:    8fbe0030    lw  s8,48(sp)401224:    27bd0038    addiu   sp,sp,56401228: 03e00008    jr  ra40122c:   00000000    nop

phase_4

该炸弹使用了if…else…语句和递归结构,学号最后一位的奇偶分别进入判断fun4(x)是否与8和13相等,很容易联想到斐波那契数列。而调用的fun4也是计算f(x)=f(x-1)+f(x-2),正是斐波那契数列的递归解法。那么输入的数字x就是函数fun4的参数。注意fun4定义f(0)=f(1)=1,与通常的斐波那契数列不同,所以答案为5或6。

00401230 <func4>:401230: 27bdffd8  addiu sp,sp,-40401234: afbf0024  sw  ra,36(sp)401238: afbe0020  sw  s8,32(sp)40123c: afb0001c  sw  s0,28(sp)401240: 03a0f021  move  s8,sp401244: afc40028  sw  a0,40(s8)401248: 8fc20028  lw  v0,40(s8)40124c: 00000000  nop401250: 28420002  slti  v0,v0,2 //判断$v0是否小于2,是则$v0 = 1401254: 14400011  bnez  v0,40129c <func4+0x6c> //$v0 != 0则return 1401258: 00000000  nop40125c: 8fc20028  lw  v0,40(s8)401260: 00000000  nop401264: 2442ffff  addiu v0,v0,-1401268: 00402021  move  a0,v040126c: 0c10048c  jal 401230 <func4> //递归引用自身f(x - 1)401270: 00000000  nop401274: 00408021  move  s0,v0 //将f(x - 1)的结果存入$s0401278: 8fc20028  lw  v0,40(s8)40127c: 00000000  nop401280: 2442fffe  addiu v0,v0,-2401284: 00402021  move  a0,v0401288: 0c10048c  jal 401230 <func4> //递归引用自身f(x - 2)40128c: 00000000  nop401290: 02021021  addu  v0,s0,v0 //$v0 = f(x - 1) + f(x - 2),返回$v0401294: 10000002  b 4012a0 <func4+0x70>401298: 00000000  nop40129c: 24020001  li  v0,1 //return 14012a0: 03c0e821  move  sp,s84012a4: 8fbf0024  lw  ra,36(sp)4012a8: 8fbe0020  lw  s8,32(sp)4012ac: 8fb0001c  lw  s0,28(sp)4012b0: 27bd0028  addiu sp,sp,404012b4: 03e00008  jr  ra4012b8: 00000000  nop004012bc <phase_4>:4012bc:  27bdffd8    addiu   sp,sp,-404012c0:    afbf0024    sw  ra,36(sp)4012c4:    afbe0020    sw  s8,32(sp)4012c8:    03a0f021    move    s8,sp4012cc:    3c1c0042    lui gp,0x424012d0:  279cb190    addiu   gp,gp,-200804012d4: afbc0010    sw  gp,16(sp)4012d8:    afc40028    sw  a0,40(s8)4012dc:    8fc30028    lw  v1,40(s8)4012e0:    3c020040    lui v0,0x404012e4:  244227ac    addiu   v0,v0,101564012e8:  00602021    move    a0,v14012ec:    00402821    move    a1,v04012f0:    27c20018    addiu   v0,s8,244012f4: 00403021    move    a2,v04012f8:    8f828084    lw  v0,-32636(gp)4012fc:    00000000    nop401300:  0040c821    move    t9,v0401304:    0320f809    jalr    t9401308:   00000000    nop40130c:  8fdc0010    lw  gp,16(s8)401310:    00401821    move    v1,v0401314:    24020001    li  v0,1401318: 14620005    bne v1,v0,401330 <phase_4+0x74> //$v0 != 1则引爆40131c:    00000000    nop401320:  8fc20018    lw  v0,24(s8)401324:    00000000    nop401328:  1c400005    bgtz    v0,401340 <phase_4+0x84>40132c:  00000000    nop401330:  0c10087c    jal 4021f0 <explode_bomb>401334:  00000000    nop401338:  8fdc0010    lw  gp,16(s8)40133c:    00000000    nop401340:  8f82806c    lw  v0,-32660(gp)401344:    00000000    nop401348:  8c42002c    lw  v0,44(v0) //令$v0等于学号的最后一位40134c:    00000000    nop401350:  30420001    andi    v0,v0,0x1 //判定奇偶401354: 304200ff    andi    v0,v0,0xff401358:   10400010    beqz    v0,40139c <phase_4+0xe0> //if...else...结构,奇数(1)继续,偶数(0)跳转40135c:   00000000    nop401360:  8fc20018    lw  v0,24(s8) //令$v0等于输入的第一个数401364:    00000000    nop401368:  00402021    move    a0,v0 //传入参数40136c: 0c10048c    jal 401230 <func4> //计算f(x)401370:    00000000    nop401374:  8fdc0010    lw  gp,16(s8)401378:    00401821    move    v1,v040137c:    24020008    li  v0,8401380: 10620013    beq v1,v0,4013d0 <phase_4+0x114> //f(x) = $v1 != 8则引爆,则x = 5401384:    00000000    nop401388:  0c10087c    jal 4021f0 <explode_bomb>40138c:  00000000    nop401390:  8fdc0010    lw  gp,16(s8)401394:    1000000e    b   4013d0 <phase_4+0x114>401398:    00000000    nop40139c:  8fc20018    lw  v0,24(s8)4013a0:    00000000    nop4013a4:  00402021    move    a0,v0 //传入参数4013a8: 0c10048c    jal 401230 <func4> //计算f(x)4013ac:    00000000    nop4013b0:  8fdc0010    lw  gp,16(s8)4013b4:    00401821    move    v1,v04013b8:    2402000d    li  v0,134013bc:    10620004    beq v1,v0,4013d0 <phase_4+0x114> //f(x) = $v1 != 13则引爆,则x = 64013c0:   00000000    nop4013c4:  0c10087c    jal 4021f0 <explode_bomb>4013c8:  00000000    nop4013cc:  8fdc0010    lw  gp,16(s8)4013d0:    03c0e821    move    sp,s84013d4:    8fbf0024    lw  ra,36(sp)4013d8:    8fbe0020    lw  s8,32(sp)4013dc:    27bd0028    addiu   sp,sp,404013e0: 03e00008    jr  ra4013e4:   00000000    nop

phase_5

输入字符串,要求其长度为6。进入循环中对每个字符进行处理,获取其二进制数的后四位(即ASCII码的b3b2b1b0),一一对应程序存储的长度为16的字符串S=“isrveawhobpnutfg”,即S[b3b2b1b0],炸弹要求这个映射获得的字符串为"giants",那么输入的字符串就可以是opekma,应当也可以是其他可以映射的字符串(大概没有限制?上机验证一下就知道了)

004013e8 <phase_5>:4013e8: 27bdffb8    addiu   sp,sp,-724013ec:    afbf0044    sw  ra,68(sp)4013f0:    afbe0040    sw  s8,64(sp)4013f4:    03a0f021    move    s8,sp4013f8:    afc40048    sw  a0,72(s8) //$a0为输入的字符串,将其存入栈中4013fc: 8fc40048    lw  a0,72(s8)401400:    0c10071e    jal 401c78 <string_length>401404: 00000000    nop401408:  00401821    move    v1,v040140c:    24020006    li  v0,6401410: 10620003    beq v1,v0,401420 <phase_5+0x38> //输入字符串长度$v1 != 6则引爆401414: 00000000    nop401418:  0c10087c    jal 4021f0 <explode_bomb>40141c:  00000000    nop401420:  afc00018    sw  zero,24(s8) //i = 0401424: 10000020    b   4014a8 <phase_5+0xc0>401428: 00000000    nop40142c:  8fc20018    lw  v0,24(s8) //读得i401430:  8fc30018    lw  v1,24(s8) //读得i401434:  8fc40048    lw  a0,72(s8) //从栈中取出输入的字符串(从0开始编号)401438:    00000000    nop40143c:  00831821    addu    v1,a0,v1401440: 80630000    lb  v1,0(v1) //读取输入字符串的第i个字符401444: 00000000    nop401448:  306300ff    andi    v1,v1,0xff40144c:   3063000f    andi    v1,v1,0xf //取字符转化为二进制数(1byte=8bit)的后四位401450:    00021080    sll v0,v0,0x2 //将i拓至1 int型变量长度401454:   27c40018    addiu   a0,s8,24 //读得i的地址401458:    00821021    addu    v0,a0,v040145c: ac43000c    sw  v1,12(v0) //将字符后四位存入m[$s8 + 36 + i * 4]401460:    8fc40018    lw  a0,24(s8) //读得i401464:  8fc20018    lw  v0,24(s8) //读得i401468:  00000000    nop40146c:  00021080    sll v0,v0,0x2 //将i拓至1 int型变量长度401470:   27c30018    addiu   v1,s8,24 //读得i的地址401474:    00621021    addu    v0,v1,v0401478: 8c43000c    lw  v1,12(v0) //读得字符后四位,存入$v1中40147c:    3c020041    lui v0,0x41401480:  244230ec    addiu   v0,v0,12524 //获取存储的字符串S(从0开始编号)的位置 $v0 = isrveawhobpnutfg401484:    00621021    addu    v0,v1,v0 //得到第$v1个字符的内存地址401488:    80430000    lb  v1,0(v0) //得到第$v1(输入字符串的第i个字符的后四位,即ASCII码的b3b2b1b0)个字符40148c:  27c20018    addiu   v0,s8,24401490: 00441021    addu    v0,v0,a0401494: a0430004    sb  v1,4(v0) //将获得的字符存入m[$s8 + 28 + i]401498: 8fc20018    lw  v0,24(s8) //读得i40149c:  00000000    nop4014a0:  24420001    addiu   v0,v0,1 //i++4014a4:  afc20018    sw  v0,24(s8)4014a8:    8fc20018    lw  v0,24(s8)4014ac:    00000000    nop4014b0:  28420006    slti    v0,v0,6 //$v0 = ($v0 < 6 ? 1 : 0),为1再循环一次,即i < 64014b4:    1440ffdd    bnez    v0,40142c <phase_5+0x44>4014b8:  00000000    nop4014bc:  a3c00022    sb  zero,34(s8) //将字符串尾设为'\0'4014c0:  27c2001c    addiu   v0,s8,284014c4: 00402021    move    a0,v0 //从内存中获取依靠映射从存储的字符串S中得到的字符串4014c8:    3c020040    lui v0,0x404014cc:  244527b0    addiu   a1,v0,10160 //从内存中获取用来比较的字符串4014d0: 0c10073e    jal 401cf8 <strings_not_equal> //比较$a0,$a14014d4: 00000000    nop4014d8:  10400003    beqz    v0,4014e8 <phase_5+0x100>4014dc: 00000000    nop4014e0:  0c10087c    jal 4021f0 <explode_bomb>4014e4:  00000000    nop4014e8:  03c0e821    move    sp,s84014ec:    8fbf0044    lw  ra,68(sp)4014f0:    8fbe0040    lw  s8,64(sp)4014f4:    27bd0048    addiu   sp,sp,724014f8: 03e00008    jr  ra4014fc:   00000000    nop

phase_6

b* 0x4016e0
r
//node[] = {0fd, 2d5, 12d, 3e5, 0d4, 1b0}
x $v1 //node[i]
c
x $v1
c
x $v1
c
x $v1
c
x $v1
c
x $v1
c00401500 <phase_6>:401500:   27bdffa0    addiu   sp,sp,-96401504:    afbf005c    sw  ra,92(sp)401508:    afbe0058    sw  s8,88(sp)40150c:    03a0f021    move    s8,sp401510:    3c1c0042    lui gp,0x42401514:  279cb190    addiu   gp,gp,-20080401518: afbc0010    sw  gp,16(sp)40151c:    afc40060    sw  a0,96(s8)401520:    3c020041    lui v0,0x41401524:  24423130    addiu   v0,v0,12592401528:  afc20020    sw  v0,32(s8)40152c:    27c20024    addiu   v0,s8,36401530: 8fc40060    lw  a0,96(s8)401534:    00402821    move    a1,v0401538:    0c1006ea    jal 401ba8 <read_six_numbers> # 输入六个数字40153c: 00000000    nop  # 第一层循环的初始条件设定401540:  8fdc0010    lw  gp,16(s8)401544:    afc0001c    sw  zero,28(s8) # i = 0401548: 1000003c    b   40163c <phase_6+0x13c> # 跳至0x40163c处条件判断处40154c: 00000000    nop # 第一层循环中间循环体开始401550:   8fc2001c    lw  v0,28(s8) # 获取i401554:  00000000    nop401558:  00021080    sll v0,v0,0x2 #拓至1int长度40155c:  27c30018    addiu   v1,s8,24401560: 00621021    addu    v0,v1,v0401564: 8c42000c    lw  v0,12(v0) # 得到输入的第i个数401568:    00000000    nop40156c:  28420007    slti    v0,v0,7 # 判断第i个数是否小于7401570:    1040000a    beqz    v0,40159c <phase_6+0x9c> # 否则引爆401574:   00000000    nop401578:  8fc2001c    lw  v0,28(s8)40157c:    00000000    nop401580:  00021080    sll v0,v0,0x2401584:    27c30018    addiu   v1,s8,24401588: 00621021    addu    v0,v1,v040158c: 8c42000c    lw  v0,12(v0)401590:    00000000    nop401594:  1c400004    bgtz    v0,4015a8 <phase_6+0xa8> # 判断第i个数是否大于0,否则引爆401598:    00000000    nop40159c:  0c10087c    jal 4021f0 <explode_bomb>4015a0:  00000000    nop4015a4:  8fdc0010    lw  gp,16(s8)4015a8:    8fc2001c    lw  v0,28(s8)4015ac:    00000000    nop # 第二层循环的初始条件设定4015b0:   24420001    addiu   v0,v0,1 # j  = i + 14015b4:   afc20018    sw  v0,24(s8) # 将j存至m[$s8 + 24]处4015b8:    10000017    b   401618 <phase_6+0x118> # 跳至0x401618条件判断处4015bc:  00000000    nop # 第二层循环中间循环体开始4015c0:   8fc2001c    lw  v0,28(s8) # 获取i4015c4:  00000000    nop4015c8:  00021080    sll v0,v0,0x24015cc:    27c30018    addiu   v1,s8,244015d0: 00621021    addu    v0,v1,v04015d4: 8c43000c    lw  v1,12(v0) # 获取第i个数4015d8:   8fc20018    lw  v0,24(s8) # 获取j4015dc:  00000000    nop4015e0:  00021080    sll v0,v0,0x24015e4:    27c40018    addiu   a0,s8,244015e8: 00821021    addu    v0,a0,v04015ec: 8c42000c    lw  v0,12(v0) # 获取第j个数4015f0:   00000000    nop4015f4:  14620004    bne v1,v0,401608 <phase_6+0x108> #判断第i个数和第j个数是否不相等,否则爆炸4015f8:    00000000    nop4015fc:  0c10087c    jal 4021f0 <explode_bomb>401600:  00000000    nop401604:  8fdc0010    lw  gp,16(s8)401608:    8fc20018    lw  v0,24(s8)40160c:    00000000    nop # 第二层循环末尾循环体401610: 24420001    addiu   v0,v0,1 # j++401614:  afc20018    sw  v0,24(s8)401618:    8fc20018    lw  v0,24(s8) # 第二层循环条件判断处40161c:   00000000    nop401620:  28420006    slti    v0,v0,6 # 当j < 6时,继续循环401624: 1440ffe6    bnez    v0,4015c0 <phase_6+0xc0>401628:  00000000    nop40162c:  8fc2001c    lw  v0,28(s8) # 获取i401630:  00000000    nop # 第一层循环末尾循环体401634: 24420001    addiu   v0,v0,1 # i++401638:  afc2001c    sw  v0,28(s8)40163c:    8fc2001c    lw  v0,28(s8) # 第一层循环条件判断处401640:   00000000    nop401644:  28420006    slti    v0,v0,6 # 当i < 6 时,继续循环401648:    1440ffc1    bnez    v0,401550 <phase_6+0x50>40164c:  00000000    nop # 第一层循环的初始条件 401650:    afc0001c    sw  zero,28(s8) # i = 0401654: 10000028    b   4016f8 <phase_6+0x1f8> # 跳至条件判断处401658:  00000000    nop # 第二层循环的初始条件40165c: 3c020041    lui v0,0x41401660:  24423130    addiu   v0,v0,12592 # 令$v0等于&firstnode = 0x413130401664:   afc20020    sw  v0,32(s8) # m[$s8 + 32] = &firstnode401668:   24020001    li  v0,1 # j = 140166c:    afc20018    sw  v0,24(s8)401670:    1000000a    b   40169c <phase_6+0x19c> # 跳至条件判断处401674:  00000000    nop401678:  8fc20020    lw  v0,32(s8) # 取得&node40167c:  00000000    nop401680:  8c420008    lw  v0,8(v0) #  $v0 = m[$v0 + 8]401684:   00000000    nop401688:  afc20020    sw  v0,32(s8) # node = node->next40168c:    8fc20018    lw  v0,24(s8) # 取得j401690:  00000000    nop401694:  24420001    addiu   v0,v0,1 # j++401698:  afc20018    sw  v0,24(s8)40169c:    8fc2001c    lw  v0,28(s8) # 取得i4016a0:  00000000    nop4016a4:  00021080    sll v0,v0,0x24016a8:    27c30018    addiu   v1,s8,244016ac: 00621021    addu    v0,v1,v04016b0: 8c43000c    lw  v1,12(v0) # 取得输入的第i个数4016b4:    8fc20018    lw  v0,24(s8)4016b8:    00000000    nop4016bc:  0043102a    slt v0,v0,v1 # 判断j是否小于输入的第i个数,是则循环继续4016c0:  1440ffed    bnez    v0,401678 <phase_6+0x178>4016c4: 00000000    nop4016c8:  8fc2001c    lw  v0,28(s8) # 取得i4016cc:  00000000    nop4016d0:  00021080    sll v0,v0,0x24016d4:    27c30018    addiu   v1,s8,244016d8: 00621021    addu    v0,v1,v04016dc: 8fc30020    lw  v1,32(s8) # 将node = [链表的第j/【输入的第i个数】个取出4016e0: 00000000    nop4016e4:  ac430024    sw  v1,36(v0) # 存入数组res的res[i]中4016e8:  8fc2001c    lw  v0,28(s8)4016ec:    00000000    nop4016f0:  24420001    addiu   v0,v0,14016f4:  afc2001c    sw  v0,28(s8)4016f8:    8fc2001c    lw  v0,28(s8) # 条件判断处4016fc:    00000000    nop401700:  28420006    slti    v0,v0,6 # i < 6 则循环继续401704: 1440ffd5    bnez    v0,40165c <phase_6+0x15c>401708: 00000000    nop40170c:  8fc2003c    lw  v0,60(s8)401710:    00000000    nop401714:  afc20020    sw  v0,32(s8) # node = firstnode ???401718:    24020001    li  v0,140171c: afc2001c    sw  v0,28(s8) # i = 1401720:   10000016    b   40177c <phase_6+0x27c>401724:    00000000    nop # 循环开始401728:   8fc2001c    lw  v0,28(s8) # 取得i40172c:  00000000    nop401730:  00021080    sll v0,v0,0x2401734:    27c30018    addiu   v1,s8,24401738: 00621021    addu    v0,v1,v040173c: 8c430024    lw  v1,36(v0) # 取得res[i]401740: 8fc20020    lw  v0,32(s8) # 取得node401744:   00000000    nop401748:  ac430008    sw  v1,8(v0) # node->next = res[i]40174c:   8fc2001c    lw  v0,28(s8) # 取得i401750:  00000000    nop401754:  00021080    sll v0,v0,0x2401758:    27c30018    addiu   v1,s8,2440175c: 00621021    addu    v0,v1,v0401760: 8c420024    lw  v0,36(v0) # 取得res[i]401764: 00000000    nop401768:  afc20020    sw  v0,32(s8) # node = res[i]40176c:   8fc2001c    lw  v0,28(s8) # 末尾循环体起始,取得i401770:   00000000    nop401774:  24420001    addiu   v0,v0,1 # i++401778:  afc2001c    sw  v0,28(s8) # 存入内存中40177c:    8fc2001c    lw  v0,28(s8) # 条件判断起始401780:   00000000    nop401784:  28420006    slti    v0,v0,6 # 判断i < 6,是则循环继续401788:   1440ffe7    bnez    v0,401728 <phase_6+0x228>40178c: 00000000    nop401790:  8fc20020    lw  v0,32(s8)401794:    00000000    nop401798:  ac400008    sw  zero,8(v0) # node->next = null40179c:   8fc2003c    lw  v0,60(s8)4017a0:    00000000    nop4017a4:  afc20020    sw  v0,32(s8) # node = firstnode4017a8:    afc0001c    sw  zero,28(s8) # i = 04017ac: 10000032    b   401878 <phase_6+0x378>4017b0:    00000000    nop4017b4:  8f82806c    lw  v0,-32660(gp)4017b8:    00000000    nop4017bc:  8c42002c    lw  v0,44(v0)4017c0:    00000000    nop4017c4:  30420001    andi    v0,v0,0x14017c8:    304200ff    andi    v0,v0,0xff4017cc:   10400012    beqz    v0,401818 <phase_6+0x318> # if...else语句,判断奇偶4017d0:   00000000    nop4017d4:  8fc20020    lw  v0,32(s8)4017d8:    00000000    nop4017dc:  8c430000    lw  v1,0(v0)4017e0: 8fc20020    lw  v0,32(s8)4017e4:    00000000    nop4017e8:  8c420008    lw  v0,8(v0)4017ec: 00000000    nop4017f0:  8c420000    lw  v0,0(v0)4017f4: 00000000    nop4017f8:  0062102a    slt v0,v1,v0 # 比较重排后链表前后两个数的大小,升序则爆炸4017fc:  10400015    beqz    v0,401854 <phase_6+0x354>401800: 00000000    nop401804:  0c10087c    jal 4021f0 <explode_bomb>401808:  00000000    nop40180c:  8fdc0010    lw  gp,16(s8)401810:    10000010    b   401854 <phase_6+0x354>401814:    00000000    nop401818:  8fc20020    lw  v0,32(s8)40181c:    00000000    nop401820:  8c430000    lw  v1,0(v0)401824: 8fc20020    lw  v0,32(s8)401828:    00000000    nop40182c:  8c420008    lw  v0,8(v0)401830: 00000000    nop401834:  8c420000    lw  v0,0(v0)401838: 00000000    nop40183c:  0043102a    slt v0,v0,v1 # 比较重排后链表前后两个数的大小,降序则爆炸401840:  10400004    beqz    v0,401854 <phase_6+0x354>401844: 00000000    nop401848:  0c10087c    jal 4021f0 <explode_bomb>40184c:  00000000    nop401850:  8fdc0010    lw  gp,16(s8)401854:    8fc20020    lw  v0,32(s8)401858:    00000000    nop40185c:  8c420008    lw  v0,8(v0)401860: 00000000    nop401864:  afc20020    sw  v0,32(s8)401868:    8fc2001c    lw  v0,28(s8)40186c:    00000000    nop401870:  24420001    addiu   v0,v0,1 # i++401874:  afc2001c    sw  v0,28(s8)401878:    8fc2001c    lw  v0,28(s8)40187c:    00000000    nop401880:  28420005    slti    v0,v0,5 # i < 5401884:   1440ffcb    bnez    v0,4017b4 <phase_6+0x2b4>401888: 00000000    nop40188c:  03c0e821    move    sp,s8401890:    8fbf005c    lw  ra,92(sp)401894:    8fbe0058    lw  s8,88(sp)401898:    27bd0060    addiu   sp,sp,9640189c: 03e00008    jr  ra4018a0:   00000000    nop

phase_secret

在炸弹四输入5 austinpowers即可进入隐藏炸弹。这个炸弹就是一个普通的二叉搜索树,输入数值x,执行find(x),返回得到根节点到值为x的节点的路径。炸弹要求返回值为7=111B,即根节点的右儿子节点的右儿子节点的右儿子节点,该节点值为1001。因此输入1001即可。

00402264 <phase_defused>:402264:   27bdff88    addiu   sp,sp,-120402268:   afbf0074    sw  ra,116(sp)40226c:   afbe0070    sw  s8,112(sp)402270:   03a0f021    move    s8,sp402274:    3c1c0042    lui gp,0x42402278:  279cb190    addiu   gp,gp,-2008040227c: afbc0010    sw  gp,16(sp)402280:    3c020041    lui v0,0x41402284:  8c433240    lw  v1,12864(v0)402288: 24020006    li  v0,640228c: 14620039    bne v1,v0,402374 <phase_defused+0x110>402290:    00000000    nop402294:  8f828058    lw  v0,-32680(gp)402298:    00000000    nop40229c:  244400f0    addiu   a0,v0,2404022a0:    3c020040    lui v0,0x404022a4:  244328a8    addiu   v1,v0,10408 # "%d %s" !!!4022a8:  27c20068    addiu   v0,s8,1044022ac:    00602821    move    a1,v14022b0:    00403021    move    a2,v04022b4:    27c20018    addiu   v0,s8,244022b8: 00403821    move    a3,v04022bc:    8f828084    lw  v0,-32636(gp)4022c0:    00000000    nop4022c4:  0040c821    move    t9,v04022c8:    0320f809    jalr    t9 # 调用库中函数sscanf !!!4022cc:    00000000    nop4022d0:  8fdc0010    lw  gp,16(s8)4022d4:    00401821    move    v1,v04022d8:    24020002    li  v0,2 # 判断sscanf读得的有效数据个数是否为24022dc: 1462001d    bne v1,v0,402354 <phase_defused+0xf0>4022e0: 00000000    nop4022e4:  27c20018    addiu   v0,s8,244022e8: 00402021    move    a0,v0 # $a0中存储着输入的字符4022ec: 3c020040    lui v0,0x404022f0:  244528b0    addiu   a1,v0,10416 # $a1中存储着"austinpowers"4022f4:    0c10073e    jal 401cf8 <strings_not_equal> # 判断是否相等4022f8:    00000000    nop4022fc:  8fdc0010    lw  gp,16(s8)402300:    14400014    bnez    v0,402354 <phase_defused+0xf0>402304:    00000000    nop402308:  3c020040    lui v0,0x4040230c:  244428c0    addiu   a0,v0,10432402310:  8f828038    lw  v0,-32712(gp)402314:    00000000    nop402318:  0040c821    move    t9,v040231c:    0320f809    jalr    t9402320:   00000000    nop402324:  8fdc0010    lw  gp,16(s8)402328:    3c020040    lui v0,0x4040232c:  244428e8    addiu   a0,v0,10472402330:  8f828038    lw  v0,-32712(gp)402334:    00000000    nop402338:  0040c821    move    t9,v040233c:    0320f809    jalr    t9402340:   00000000    nop402344:  8fdc0010    lw  gp,16(s8)402348:    0c100664    jal 401990 <secret_phase> # 跳转至secret_phase40234c:    00000000    nop402350:  8fdc0010    lw  gp,16(s8)402354:    3c020040    lui v0,0x40402358:  24442920    addiu   a0,v0,1052840235c:  8f828038    lw  v0,-32712(gp)402360:    00000000    nop402364:  0040c821    move    t9,v0402368:    0320f809    jalr    t940236c:   00000000    nop402370:  8fdc0010    lw  gp,16(s8)402374:    03c0e821    move    sp,s8402378:    8fbf0074    lw  ra,116(sp)40237c:   8fbe0070    lw  s8,112(sp)402380:   27bd0078    addiu   sp,sp,120402384:    03e00008    jr  ra402388:   00000000    nop40238c:  00000000    nop004018a4 <fun7>:4018a4: 27bdffe0  addiu sp,sp,-324018a8: afbf001c  sw  ra,28(sp)4018ac: afbe0018  sw  s8,24(sp)4018b0: 03a0f021  move  s8,sp4018b4: afc40020  sw  a0,32(s8)4018b8: afc50024  sw  a1,36(s8)4018bc: 8fc20020  lw  v0,32(s8)4018c0: 00000000  nop4018c4: 14400004  bnez  v0,4018d8 <fun7+0x34> # $v0($a0)不为0则继续,为0则函数结束4018c8: 00000000  nop4018cc: 2402ffff  li  v0,-1 # 设返回值为-1,即没有找到该值4018d0: 10000029  b 401978 <fun7+0xd4>4018d4: 00000000  nop4018d8: 8fc20020  lw  v0,32(s8) # 取出$a0中的值4018dc: 00000000  nop4018e0: 8c430000  lw  v1,0(v0) # $v1 = m[$a0]4018e4: 8fc20024  lw  v0,36(s8) # $v0 = $a14018e8: 00000000  nop4018ec: 0043102a  slt v0,v0,v1 # $v0 >= $v1时函数跳转4018f0: 1040000c  beqz  v0,401924 <fun7+0x80>4018f4: 00000000  nop4018f8: 8fc20020  lw  v0,32(s8)4018fc: 00000000  nop401900: 8c420004  lw  v0,4(v0) # 令fun7第一个参数为节点的左儿子的地址401904: 00000000  nop401908: 00402021  move  a0,v040190c: 8fc50024  lw  a1,36(s8) #第二个参数不变401910: 0c100629  jal 4018a4 <fun7>401914: 00000000  nop401918: 00021040  sll v0,v0,0x1 # $v0左移一位40191c: 10000016  b 401978 <fun7+0xd4>401920: 00000000  nop401924: 8fc20020  lw  v0,32(s8)401928: 00000000  nop40192c: 8c430000  lw  v1,0(v0)401930: 8fc20024  lw  v0,36(s8)401934: 00000000  nop401938: 0062102a  slt v0,v1,v0 # $v1 >= $v0时函数跳转,即$v0 == $v1时找到节点,函数返回040193c: 1040000d  beqz  v0,401974 <fun7+0xd0>401940: 00000000  nop401944: 8fc20020  lw  v0,32(s8)401948: 00000000  nop40194c: 8c420008  lw  v0,8(v0) # 令fun7第一个参数为节点的右儿子的地址401950: 00000000  nop401954: 00402021  move  a0,v0401958: 8fc50024  lw  a1,36(s8) # 第二个参数不变40195c: 0c100629  jal 4018a4 <fun7>401960: 00000000  nop401964: 00021040  sll v0,v0,0x1 # $v0左移一位401968: 24420001  addiu v0,v0,1 # $v0末位补140196c: 10000002  b 401978 <fun7+0xd4>401970: 00000000  nop401974: 00001021  move  v0,zero401978: 03c0e821  move  sp,s840197c: 8fbf001c  lw  ra,28(sp)401980: 8fbe0018  lw  s8,24(sp)401984: 27bd0020  addiu sp,sp,32401988: 03e00008  jr  ra40198c: 00000000  nop00401990 <secret_phase>:401990:   27bdffd8    addiu   sp,sp,-40401994:    afbf0024    sw  ra,36(sp)401998:    afbe0020    sw  s8,32(sp)40199c:    03a0f021    move    s8,sp4019a0:    3c1c0042    lui gp,0x424019a4:  279cb190    addiu   gp,gp,-200804019a8: afbc0010    sw  gp,16(sp)4019ac:    0c1007fb    jal 401fec <read_line> # 输入4019b0:    00000000    nop4019b4:  8fdc0010    lw  gp,16(s8)4019b8:    afc2001c    sw  v0,28(s8)4019bc:    8fc2001c    lw  v0,28(s8)4019c0:    00000000    nop4019c4:  00402021    move    a0,v04019c8:    00002821    move    a1,zero4019cc:  2406000a    li  a2,104019d0:    8f828070    lw  v0,-32656(gp)4019d4:    00000000    nop4019d8:  0040c821    move    t9,v04019dc:    0320f809    jalr    t94019e0:   00000000    nop4019e4:  8fdc0010    lw  gp,16(s8)4019e8:    afc20018    sw  v0,24(s8)4019ec:    8fc20018    lw  v0,24(s8)4019f0:    00000000    nop4019f4:  2442ffff    addiu   v0,v0,-1 # $v0--4019f8: 2c4203e9    sltiu   v0,v0,1001 # 判断[输入的值-1]($v0)是否小于1001,是则继续,否则引爆4019fc: 14400004    bnez    v0,401a10 <secret_phase+0x80>401a00: 00000000    nop401a04:  0c10087c    jal 4021f0 <explode_bomb>401a08:  00000000    nop401a0c:  8fdc0010    lw  gp,16(s8)401a10:    3c020041    lui v0,0x41401a14:  24443184    addiu   a0,v0,12676 # fun7的第一个参数0x413814 m[0x413814] = 0x24 = 36401a18:   8fc50018    lw  a1,24(s8) # fun7的第二个参数,即输入的数401a1c:  0c100629    jal 4018a4 <fun7> # 进入fun7401a20: 00000000    nop401a24:  8fdc0010    lw  gp,16(s8)401a28:    00401821    move    v1,v0401a2c:    24020007    li  v0,7401a30: 10620004    beq v1,v0,401a44 <secret_phase+0xb4> # fun7返回值为7 = 111B时才不会引爆401a34:    00000000    nop401a38:  0c10087c    jal 4021f0 <explode_bomb>401a3c:  00000000    nop401a40:  8fdc0010    lw  gp,16(s8)401a44:    3c020040    lui v0,0x40401a48:  244427b8    addiu   a0,v0,10168401a4c:  8f828038    lw  v0,-32712(gp)401a50:    00000000    nop401a54:  0040c821    move    t9,v0401a58:    0320f809    jalr    t9401a5c:   00000000    nop401a60:  8fdc0010    lw  gp,16(s8)401a64:    0c100899    jal 402264 <phase_defused>401a68: 00000000    nop401a6c:  8fdc0010    lw  gp,16(s8)401a70:    03c0e821    move    sp,s8401a74:    8fbf0024    lw  ra,36(sp)401a78:    8fbe0020    lw  s8,32(sp)401a7c:    27bd0028    addiu   sp,sp,40401a80: 03e00008    jr  ra401a84:   00000000    nop

总结

每个阶段对应的C++代码

只给出关键部分。简洁明了,一看就懂,理解炸弹大概流程用。

//输入ID
int ID;
cin>>ID;

phase_1

//input
string str;
cin>>str;//phase_1
string ans = "Let's begin now!";
if (str == ans) return ;
else explode_bomb();

phase_2

//input
int a[6];
for (int i = 0;i < 6;i++)cin>>a[i];//phase_2
if (a[0] != 1) explode_bomb();
for (int i = 0;i < 6;i++)if (a[i] * ((ID >> i) & 1) != a[i + 1])explode_bomb();

phase_3

//input
int a[2];
char c
cin>>a[0]>>c>>a[1];
//phase_3
char c0;
int b;
switch(a[0]) {case 0:c0 = 'q';b = 777;if ((ID & 1) * a[1] != b) explode_bomb();break;case 1:c0 = 'b';b = 214;if ((ID & 1) * a[1] != b) explode_bomb();break;case 2:c0 = 'b';b = 755;if ((ID & 1) * a[1] != b) explode_bomb();break;case 3:c0 = 'k';if ((ID & 1) * a[1] != 0) explode_bomb();break;case 4:c0 = 'o';b = 228;if ((ID & 1) * a[1] != b) explode_bomb();break;case 5:c0 = 't';b = 513;if ((ID & 1) * a[1] != b) explode_bomb();break;case 6:c0 = 'v';b = 780;if ((ID & 1) * a[1] != b) explode_bomb();break;case 7:c0 = 'b';b = 824;if ((ID & 1) * a[1] != b) explode_bomb();break;default: explode_bomb();
}
if (c != c0) explode_bomb();

phase_4

//input
int x;
cin>>x;
//fun4
int fun4(int x) {if (x < 2) return 1;return f(x - 1) + f(x - 2);
}
//phase_4
if (ID & 1) {if (fun4(x) != 8) explode_bomb();
}
else {if (fun4(x) != 13) explode_bomb();
}

phase_5

//input
char str[6];
cin>>str;
//phase_5
char res[6];
char S[16] = "isrveawhobpnutfg";
char ans[6] = "giants";
for (int i = 0;i < 6;i++) {int pos = str[i] & 15;//15D = FH = 1111Bres[i] = S[pos];
}
for (int i = 0;i < 6;i++)if (res[i] != ans[i])explode_bomb();

phase_6

//input
int a[6];
for (int i = 0;i < 6;i++)cin>>a[i];
//phase_6
for (int i = 0;i < 6;i++) {if (!(i > 0 && i < 7) explode_bomb();for (int j = i + 1;j < 6;j++)if (a[i] == a[j]) explode_bomb();
}
chain c = {0x0fd, 0x2d5, 0x12d, 0x3e5, 0x0d4, 0x1b0};
chainNode res[6];
for (int i = 0;i < 6;i++) {chainNode *node = c.firstNode;for (int j = 1;j < a[i];j++)node = node->next;res[i] = node;
}
chainNode *node = c.firstNode;
for (int i = 1;i < 6;i++) {node->next = res[i];node = res[i];
}
node->next = null;
if (ID & 1) {node = c.firstNode;for (int i = 1;i < 6;i++)if (node->element < node->next->element)explode_bomb();
}
else {node = c.firstNode;for (int i = 1;i < 6;i++)if (node->element > node->next->element)explode_bomb();
}

MIPS反汇编拆炸弹相关推荐

  1. MIPS - 反汇编 - 拆炸弹 - bomb

    MIPS - 反汇编 - 拆炸弹 - bomb 前言 整理文档发现了之前的实验报告,鉴于从17级开始才开始使用MIPS实验环境,取实验报告精华,整理主要思路如下.该博客叙述风格参考了窦优秀学长的博客. ...

  2. 汇编 二进制拆炸弹 r -t 3 -x 124

    文章目录 注 实验环境: 实验内容 实验步骤 调试过程及实验 总结 附录 注 QUT大二汇编最后一个作业:拆炸弹 通过两天中间隙来做这个实验,不能交个实验报告就完事了,毕竟是第一次接触逆向工程,老师为 ...

  3. CSAPP_实验二 拆炸弹 汇编知识应用

    CSAPP--实验二 拆炸弹 Phase1 disas phase_1, 反汇编 phase_1 函数 在 phase_1函数入口处 设置断点 break phase_1 run 开始运行,输入字符串 ...

  4. CSAPP 拆炸弹 中科大实验

    实验二 拆炸弹 准备工作 首先反汇编 objdump -s -d bomb > bomb.txt phase_1 开启gdb调试,并打断点到phase_1 >> gbd bomb ( ...

  5. 【LeetCode】1652. 拆炸弹(C++)

    1652. 拆炸弹(C++) 1 题目描述 2 示例描述 2.1 示例1 2.2 示例2 2.3 示例3 3 解题提示 4 解题思路 5 源码详解(C++) 1 题目描述 你有一个炸弹需要拆除,时间紧 ...

  6. 计算机系统实验拆炸弹,CSAPP 炸弹实验解析上

    CSAPP(Computer Systems A Programmer's Perspective),中译名为深入理解计算机系统,是一本优秀的计算机教材.该书配套了若干个课后实验,可供读者检验所学知识 ...

  7. bomblab 拆炸弹

    #南京航空航天大学<计算机组成原理Ⅱ课程设计>报告 姓名:xx 班级:1617 学号:1617 报告阶段:Bomblab 完成日期:2019.5.26 ##目录 文章目录 实验内容 1.B ...

  8. LeetCode简单题之拆炸弹

    题目 你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k . 为了获得正确的密码,你需要替换掉每一个数字.所有数字会 同时 被替换. 如果 k ...

  9. LeetCode 1652. 拆炸弹(前缀和)

    文章目录 1. 题目 2. 解题 1. 题目 你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k . 为了获得正确的密码,你需要替换掉每一个数字 ...

最新文章

  1. 安装openssl-devel
  2. mysql ormlite_Loogn.OrmLite
  3. 广义的B端产品人,都是什么职位?
  4. 删除个别主机的Know_hosts文件信息
  5. oracle的asmcmd获取归档日志,分析oracle的联机日志和归档日志
  6. Android studio编译出现Failed to finalize session : INSTALL_FAILED_INVALID_APK
  7. MySQL 配置错误
  8. 正则表达式捕获分组和非捕获分组及用法
  9. 使用Python编写简单网络爬虫抓取视频下载资源
  10. arailsdemo 1
  11. 瞬时电压示波器matlab,示波器测量瞬时电压的方法与步骤
  12. 当p.1引脚的电平正跳变c语言程序,数字电路笔试题目1
  13. Python+Pid实现车辆速度跟踪
  14. python中element什么意思_什么是Python中等效的’nth_element’函数?
  15. 文本挖掘基本流程概述 分词和TF-IDF值计算方法介绍
  16. 笔记本插入耳机依然外放,但开机前插上耳机可以使用耳机 (解决了我多年的问题)
  17. 深入理解HashMap
  18. mysql safe file priv_解决MySQL导入数据时遇到secure-file-priv的问题
  19. 解决webpack打包报错: Cannot find module '@webassemblyjs/wasm-parser'
  20. 【函数参数传递】编写一个函数,统计字符串中小写字母的个数,并把字符串中的小写字母转化成大写字母。

热门文章

  1. 西门子博图HMI与倍福进行PLC使用OPC DA服务器进行通讯配置
  2. 同轴电缆抗干扰措施(二)
  3. 中止执行后超过2年_执行中止后恢复执行的期限有什么规定
  4. 插入u盘计算机未响应,U盘插入win7电脑没反应如何解决 Win7插入U盘没反应怎么办...
  5. 规则在自然语言处理领域的重要地位
  6. python 桑基图_3行代码基于python的matplotlib绘制桑基图
  7. 推荐模型-上下文感知-2017:AFM模型【FM家族】【NFM的改进版】【引入Attention机制】
  8. 软件测试测试用例—用户注册界面
  9. mapbox-gl开发:deck.gl轨迹图效果
  10. 【环境搭建】Ubuntu18.04 nvidia显卡 OpenCL环境搭建