拆炸弹解题报告
时间原因先写这些,占坑,持久更新。
2016级山东大学计算机基Frankdura
掌握好gdb的方法对你很重要
x/s $r3 可以查看寄存器
如果上述命令不行可以使用:
p $r3
此外
b *0x10878设置指定位置断点
c 该命令是设置断点后继续进行
si 是逐步运行
【答案】Let’s begin now!
【答案】(id:123456111111)111111
下面通过查看寄存器内容来验证我们想法
【答案】(多种)4 o 228
先比较后面的228 然后再比较中间的 %c;
还是照例先看一下是不是id最后一位是奇数、偶数
如果是奇数那么和8比较
如果是偶数那么和13比较
然后看一下fun4;
很显然
注意r0是函数的“返回”值
关键是这里如果 fun4(n) = fun4(n-1) + fun4(n-2);
(其实连分析都不用分析了)
这是一个单调递增的函数(数列);而且范围无非是 0 – 8或者 0 – 12
那么我直接二分即可,二分枚举 得到5即可。
如果正规分析:
斐波那契数列:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
13 –》index = 6;
8 -》index = 5;
【答案】(id:123456111111)5
【答案】o`ekma或者opekma
先后四位截取;
可以查看一波:
输入 o 对应的ascii码为 103(g)
第一轮第一个数字必须大于0 小于等于6
注意该炸弹有双重计数,一个是r11 – I = r11 - 12这种。
还有一个r11 – k这种, = r11 – 16;
r3 = [r11 - 12] 即为恢复为计数数据 0()
要求第一个数据和第二个数据不相等;其实整个左半部分都是判断后面的五位是不是和第一位相同。更进一步是一个二重循环判断每一位都不相同。右侧是将这六个数看作链表数据的index,要求指定的位置的index必须有序:
1->253 ->node1
2->725 ->node2
3->301 ->node3
4->997 ->node4
5->212 ->node5
6->432 ->node6
最后一段:
有个判断最后一位是奇数还是偶数的
如果是奇数
从大到小
4 2 6 3 1 5
如果是偶数
从小到大
5 1 3 6 2 4
然后选择List cross references to …
点击ok
进入:
他在左下角,在phrase_defuse中,在其中再次使用上述操作:
看到每个阶段结束后会有这个函数,在main函数中:
通过查看phase_defused里面的验证机制,可以知道是在读一个%d的时候还会额外读一个%s。(判断读入的是不是两个)
然后判断第二个字符是不是和austinpowers相同。
所以我们找到了炸弹
Curses, you've found the secret phase!
But finding it and solving it are quite different...
下面开始拆弹:
直接右键看一下谁调用了fun7
发现一个位置然后查看数据:
这里r3是我们的转换后的“数字”
关键是1001代表啥呢?
是func7 的读入参数:
为 r1的内容,就是我们转换后的数字
r0为第二个参数 也就是数据内存地址(反复出现:618872 618848)
我们强行查看内容:
每次func7调用完后会乘2加1;
最后的结束标准是 7 所以
我们看如何得到7?
换言之经过了多少次递归后得到了7?
还需要的注意的是 当调用Loc_10F10的时候返回为0;没有其他的数字的返回值所以 7 –> 3 -> 1->0;
也就是说深入到“最深”处你返回值应该是 0;
如何返回零?
注意到当 r2(数据) 比r3(你输入的数字)大或者相等的时候才调用Loc_10F10,返回为0。而我们需要前三次都继续递归,最后一次才大于等于,所以我们每次查看一下r2 r3并调节我们的数值。即可。
【第一组】
123456111111
Let’s begin now!
1 1 1 1 1 1
4 o 228
5 austinpowers
opekma
4 2 6 3 1 5
【第二组】
123456111112
Let’s begin now!
1 2 2 2 2 2
4 o 114
5 austinpowers
opekma
5 1 3 6 2 4
【附录】
求解ascii码后四位的and操作:
#include
#include
#include
using namespace std;
int main(void)
{
int ch[16]={0}; //存放二进制数0和1
int i,j;
int variable,index;
printf ("Please enter a value(0~32767):\n");
printf (" (Enter any letter to quit.)\n");
string str;
while (cin >> str)
{
variable = str[0];
for (index=0;index<15;index++)
{
i=variable%2; //取2的余数
j=variable/2; //取被2整除的数
variable=j;
ch[index]=i; //将余数存放在数组中
}
for(index=15;index>=0;index--)
{
printf ("%d",ch[index]);
if (index%4 == 0)
{
printf (" ");
//每输出4个元素,输出一个空格
}
}
printf ("-->");
for(index=15;index>=0;index--)
{
printf ("%d",ch[index]&1);
if (index%4 == 0)
{
printf (" ");
//每输出4个元素,输出一个空格
}
}
printf ("\n");
}
system ("pause");
return 0;
}
求解16位长数组array.7503
#include
#include
using namespace std;
int main(int argc, char const *argv[])
{
int a;
while(cin>> a)
{
printf("%c\n", a);
}
return 0;
}