Justdoit
这个小程序的链接:https://pan.baidu.com/s/1Xyg5U5uj9rX8Un_b0fbYzw 提取码:acwt
仅用于学习交流!
这个是老师在课堂上给的一个练手题,是没有壳的,所以我并没有用peid去对他进行去壳(其实我傻乎乎的去壳了),打开之后是这个页面
那么我就把这个东西拉到了od里面,试了试水,运行,结果是这样的:
作为一个小白,我确实没有看懂这是个啥,然后我就顺便输了两个数,不出意外,error!
然后我就想看看这到底是是什么东西,所以我就在od里面,往上翻(因为我分析了一下,老师给的这个东西,应该不会太难,也不会有flag提示,那么只有一种可能,就是flag就在注释里面),果然,在我快要翻的绝望的时候,看见了一个注释:
看见了Hello Word,所以我就确定了,这就是题解,果然,输进去,是这个;
总结,这一题真的好水,虽然我啥都不会,但是就是感觉好水,老师的意思应该是让我们了解一下od是怎么用的,应该还可以用ida吧…不是太确定,但是这确实不难;
迷宫
做出来了一道1+1等于二的题目,我感觉到了些许膨胀(菜的一批),然后老师又给了一道入门级的迷宫题,emmm,题目链接如下:
链接:https://pan.baidu.com/s/1HItSC6T6YifCHlkl0pAIAw 提取码:6rtl
打开这个exe是这样的
仔细一想,这不是一个矩阵迷宫题嘛,了解过算法的人一眼就能看出来,甚至于还可以写出来一个更为牛逼的迷宫题(显然我还没达到这种牛逼的程度),心理有个大概的了解,那接下来就是先尝试输入几个字试试喽,首先输入了1,啊~我死了;重新,输入2,一点问题都没得,说明这个东西是有道道可寻的,不过这样一直试可不行(这道题是可以的,后来知道这是个55矩阵,就一条路,所以一个一个试着来是可以的),万一这个东西是个200200的矩阵,就不行了,所以果断ida,拉进去之后,长这个样子:
然后空格看一下流程图,f5看一下了伪代码(这些基本用法自行百度嗷):
诶!发现伪代码有点好理解啊,首先是定义的数据,一个字符型(后面的是地址),然后都是32位的int(中间有一个是short int 16位),而且地址是连着的(如果不懂地址的话可以百度先学一下地址的知识),接下来就是赋值了,但是那个qmemcpy又是个啥,所以我去百度了一下,将以第二个参数地址为首地址的后面25个(0x19u按一下h就可以变为十进制)字符赋值给以v3(char)为首地址的25个字节,那么去看一下_data_start_是什么,双击它,跳过来了这个页面,
emmm,这玩意好像是111…这一串,也恰好是25个,诶~会不会这个就是地图呢?矩阵形式大概是这个样子:
* 1 1 1 1
0 1 0 0 0
0 1 0 1 0
0 0 0 1 0
1 1 1 1 #
这是我猜的,因为算法里面会有这种图,让走迷宫,再难一点的我都见过,所以如果我没猜错(为什么一定要猜呢?做题嘛!直觉很重要),从出发,然后到达#,而观察图得出结论,0代表可以走,而1代表不可以走,所以我按照这个试试,输入222441144222,发现直接没了,机敏的我想到,要么是成功了,要么是失败了(废话),成功的话就是一闪而过,没有停在这个窗口,而我又输入了这么多,我就感觉是成功了!(后来分析后果然是成功了),如果在比赛中或者其他时间做这题,到这里就可以了,得到了flag,那么还管什么为什么,但是作为小白的我不能这样,我要努力,所以我又分析一下为什么:
首先分析出,有一个25位字符串,而v3也是字符型,往后复制25位;
然后,屏幕中捕获的是v6,v6是一个16位的字类型,判断v6,如果输入为2,v4++,3的话v5–,4的话v5++,而1的话,是v4–;而下面的for就很好理解了,为了限制数据大小,v4取地址,加上i,然后取值,也就是v4,v5均要大于等0,小于等4,而至于那个v5是怎么来的,就是v4+i,i不是1嘛?i是int类型,(强行解释!等我去查一下),接下来就有意思了,v8取地址,后加上5v4+v5-41==49,什么意思?就是v8的地址,减去41,算一下,恰好是v3的首地址,然后5v4+v5,如果v4是x,而v5是y,那么就好办了,也就是5v4是走了几行(其实是直接往下走),比如一个字符串111101000
* 1 1 1 1
0 1 0 0 0
从走到0,你是直接走到下就行,表示到字符中就是走了15,同理(v4,v5)就表示你当前的位置,那么就可以理解了,v4++就是x,向下就是x+1,所以这道题就出来了,后来我根据这个功能,反写了一个c++,就是这样的:
#include<iostream>
using namespace std;
int main()
{
char c; //捕获输入
string s="*11110100001010000101111#"; //迷宫数列
int x=0,y=0; //1,2,3,4对应的x,y
int z; //s的下标
cout<<"* 是起点,#是终点,0表示可以走,1表示有墙,不可以走!"<<endl;
for(int i=0;i<s.size();i++)
{
cout<<s[i];
if((i+1)%5==0)
cout<<endl;
}
while(1)
{
cout<<"you can choose one action to execute"<<endl;
cout<<"1 up"<<endl;
cout<<"2 down"<<endl;
cout<<"3 left"<<endl;
cout<<"4 right\n:";
cin>>c;
if(c=='1')
x--;
if(c=='2')
x++;
if(c=='3')
y--;
if(c=='4')
y++;
if(x<0 || x>5 || y<0 || y>5)
break;
z=5*x+y;
//cout<<z<<endl;
if(s[z]=='1')
break;
if(s[z]=='#')
{
cout<<"OK,you find the flag!"<<endl;
break;
}
}
return 0;
}
呼~结束了!