前言
比赛的时候没做出来,但和调试时看到的运算差不多,复现吧,菜逼
分析
主函数代码中仅是对输入挨个异或0x401,然后就没了。。。所以静态调试终究还只是参照,还得动调,发现是将v5,v6函数压在了retn返回地址处从而调用了他们
此时指向函数
sub_2c1220
每次加上下标的开方,注意给函数传入的v1 +40即为4 *i=40,从第十位开始
sub_2C1560
异或i*(i +1)然后将结果保存在74中,一个函数中的一部分代码也被保留在70地址,并作为返回结果
sub_2c11a0
主要起跳转作用,进入2c4470函数中,由于他是一个函数一部分,不能直接看伪代码了
sub汇编码起主要作用,即遍历减去下标值,但43a8存放的是从下标零开始
然后循环遍历乘3,imul,然后回到sub_2c1100函数
sub_2c1100
继续从第十位开始,前后字节相互异或,异或三次,en…实际上就是交换顺序
sub_2c1290
他将correct与error加密了,怪不得字符串定位检查不到,这里是在对他们解密,主要有用的就是这一长串数组用作加密完成后的比对
这就是所有的加密流程了:
- a =input ^0x401
- b =a +i*i
- b[10:] ^=i*(i+1) #10-20
- c =b[i] -i
- d =c *3
- 10-20的元素每两个一组互换顺序
wp
#include"stdio.h"
int main(){
int v3[40];
v3[0] = 3279;
v3[1] = 3264;
v3[2] = 3324;
v3[3] = 3288;
v3[4] = 3363;
v3[5] = 3345;
v3[6] = 3528;
v3[7] = 3453;
v3[8] = 3498;
v3[9] = 3627;
v3[10] = 3708;
v3[11] = 3675;
v3[12] = 3753;
v3[13] = 3786;
v3[14] = 3930;
v3[15] = 3930;
v3[16] = 4017;
v3[17] = 4173;
v3[18] = 4245;
v3[19] = 4476;
v3[20] = 4989;
v3[21] = 4851;
v3[22] = 5166;
v3[23] = 5148;
v3[24] = 4659;
v3[25] = 4743;
v3[26] = 4596;
v3[27] = 5976;
v3[28] = 5217;
v3[29] = 4650;
v3[30] = 6018;
v3[31] = 6135;
v3[32] = 6417;
v3[33] = 6477;
v3[34] = 6672;
v3[35] = 6891;
v3[36] = 7056;
v3[37] = 7398;
v3[38] = 7650;
v3[39] = 7890;
int tmp =0;
for(int i=10;i <30;i+=2){
// printf("%d,",v3[i]);
tmp =v3[i+1];
v3[i+1] =v3[i];
v3[i] =tmp;
}
for(int j=0;j<40;j++){
v3[j] /=3;
v3[j] +=j;
}
for(int k=0;k<20;k++)
v3[k+10] ^=k*(k+1);
for(int m=0;m<40;m++){
v3[m] -=m*m;
v3[m] ^=0x401;
putchar(v3[m]&0xff);
}
return 0;
}
DASCTF{TWpnemRuSTRkVzVsWVhOMmJqZzNOREoy}