首先查个壳无壳,32bit,那就丢进ida32中进行反编译,进入之后,函数一大堆,直接shift+f12搜索字符找到关键词,请输入pass,双击进入然后鼠标选中这一字符串,ctrl+x进入,再按tap,转换为c代码,再分析如图,打上注释,由图中分析可得,给v5数组赋值的str数组为flag,进入最后那个函数搞到v5最关键的就是while循环中那一句话,已知最后得到的str1数组为比较函数右侧的那个字符串,Str1[v4] = aAbcdefghiabcde[*(a1 + 4 * v4)]; 左侧为已知, aAbcdefghiabcde为一个数组,双击进入,可得其值,复制出来,这句话大概意思就是,从数组aAbcdefghiabcde中随机取值赋值给str1,最后构成一个字符串,这字符串现在又是已知,这个随机取值又和a1有关,a1是传进来的v5,所以得a1就是得v5,那么接下来,可以写代码了
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
char str[]="KanXueCTF2019JustForhappy";
int s=sizeof(str)/sizeof(char);
int v4=0,j=0;
char aA[]="abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
int a=sizeof(aA)/sizeof(char);
while(s){
for(int i=0;i<a;i++){
if(str[j]==aA[i]){ //此处i和j不一样,挨个取str中的值,遍历他是aA数组中的哪一个
//cout<<i<<","; 这边输出i之后,复制下来,结果存在下方的数组num
}
}
j++; //这边两步不要忘
s--;
}
int num[]={19,0,27,59,44,4,11,55,14,30,28,
29,37,18,44,42,43,14,38,41,7,0,39,39,48,62,};
int m;
for(int i=0;i<sizeof(num)/sizeof(int);i++){
m=num[i];
if((m+48)>57||(m+48)<48){
if((m+87)>122||(m+87)<97){
if((m+29)>90||(m+29)<65){
cout<<"输入错误";
} else {
num[i]+=29;
}
} else {
num[i]+=87;
}
} else {
num[i]+=48;
}
printf("%c",num[i]);
} //按照ida中的代码进行逆向推
return 0;
}
最后运行得到的结果为j0rXI4bTeustBiIGHeCF70DDM,加上flag{}提交即可成功,这道题难度还好,更多的看的是c语言的底子,要分析出代码含义,会逆向推,就不难做出了^_^