泰山杯 reverse_re4
拿到程序还是先查壳,发现无壳,32位程序,使用ida静态分析(也可先运行看看)
解析失败了,没有函数,向下找找哪里出现了问题
直接将这两行NOP掉,后面也全是此类型的错误,全部处理完毕后,将整个main函数部分创建函数,就可以反编译查看伪代码,发现上边还有,也处理一下
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4[8]; // [esp+Ch] [ebp-CCh]
int v5; // [esp+2Ch] [ebp-ACh]
int v6; // [esp+30h] [ebp-A8h]
int i; // [esp+34h] [ebp-A4h]
int j; // [esp+38h] [ebp-A0h]
int v9; // [esp+3Ch] [ebp-9Ch]
int v10[4]; // [esp+40h] [ebp-98h] BYREF
int v11[8]; // [esp+50h] [ebp-88h] BYREF
char v12[100]; // [esp+70h] [ebp-68h] BYREF
memset(v12, 0, sizeof(v12));
memset(v11, 0, sizeof(v11));
v10[0] = 57315;
v10[1] = 4414;
v10[2] = 22679;
v10[3] = 13908;
v4[0] = -2052683475;
v4[1] = -1585989955;
v4[2] = -1992153835;
v4[3] = 362473584;
v4[4] = 1539350109;
v4[5] = -1052825282;
v4[6] = 632752207;
v4[7] = -1380898228;
sub_401050("welcome to the reversing world!\n");
sub_4010C0("%32s", v12); //输入32位flag
v9 = 0;
v6 = 0;
while ( v9 < 32 )
{ //每4个字符组成一个unsigned int 数据,注意先输入的在低位
v5 = (v12[v9 + 3] << 24) + (v12[v9 + 2] << 16) + (v12[v9 + 1] << 8) + v12[v9];
v11[v6] = v5; //如abcd--->64636261
v9 += 4;
++v6;
}
for ( i = 0; i < 4; ++i )
(sub_401100)(&v11[2 * i], v10); //tea 加密,但是注意delta值改变了,v10[4]是加密密钥
for ( j = 0; j < 8; ++j )
{
if ( v11[j] != v4[j] ) //加密结果与v4[8]相同则代表输入正确
return 1;
}
sub_401050("Correct.\n");
return 0;
}
函数sub401100 就是稍有改动的tea加密函数
对v4的数据进行解密,得到flag组成的unsigned int型数据,再还原成flag即可
解密结果:36666366,39636634,65306363,37656630,31373930,66366466,66663663,32303666
char f[]="6665663634666339636330653066653730393731666436666336666666363032";
int ff[32]={0x36,0x66,0x63,0x66,0x39,0x63,0x66,0x34,0x65,0x30,0x63,0x63,0x37,0x65,0x66,0x30,0x31,0x37,0x39,0x30,0x66,0x36,0x64,0x66,0x66,0x66,0x36,0x63,0x32,0x30,0x36,0x66};
char flag[32];
for(int i=0;i<strlen(f);i=i+2)
{
//printf("0x%c%c,",f[i],f[i+1]); 将字符串转为ascii 16进制,存在ff中
}
printf("\n");
for(int i=0;i<32;i=i+4)
{
printf("%c%c%c%c",ff[i+3],ff[i+2],ff[i+1],ff[i]);
}
flag{fcf64fc9cc0e0fe70971fd6fc6fff602}