PE查壳
无壳,ida打开
Shift+F12查看字符串,定位到关键字符
双击跟进
Ctrl+X(交叉引用)
F5查看伪代码,来到main函数
分析伪代码
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
size_t v3; // eax
const char *v4; // eax
int v5; // edx
int v6; // ecx
size_t v7; // eax
int v8; // edx
int v9; // ecx
int v10; // edx
int v12; // [esp-4h] [ebp-18Ch]
char v13; // [esp+0h] [ebp-188h]
char v14; // [esp+0h] [ebp-188h]
signed int j; // [esp+DCh] [ebp-ACh]
int i; // [esp+E8h] [ebp-A0h]
signed int v17; // [esp+E8h] [ebp-A0h]
char Destination[108]; // [esp+F4h] [ebp-94h] BYREF
char Str[28]; // [esp+160h] [ebp-28h] BYREF
char v20[8]; // [esp+17Ch] [ebp-Ch] BYREF
int v21; // [esp+184h] [ebp-4h]
int savedregs; // [esp+188h] [ebp+0h] BYREF
for ( i = 0; i < 100; ++i )
{
if ( (unsigned int)i >= 0x64 )
sub_411154();
Destination[i] = 0;
}
printf("please enter the flag:", v13);
sub_411375("%20s", (char)Str);
v3 = j_strlen(Str);
v4 = (const char *)sub_4110BE((int)Str, v3, (int)v20);// 计算编码的结果赋值给V4 至于是什么编码要跟进sub_4110BE函数分析
strncpy(Destination, v4, 40u);
sub_411127(v6, v5);
v17 = j_strlen(Destination);
for ( j = 0; j < v17; ++j )
Destination[j] += j;
v7 = j_strlen(Destination);
strncmp(Destination, Str2, v7); // 双击可查看str2 str2="e3nifIH9b_C@n@dH"
if ( sub_411127(v9, v8) )
printf("wrong flag!\n", v14);
else
printf("rigth flag!\n", v14);
v12 = v10;
sub_41126C((int)&savedregs, (int)&dword_415890, 0);
return sub_411127((unsigned int)&savedregs ^ v21, v12);
}
双击跟进sub_411AB0函数
太长了啊!!!!不过多次出现 aAbcdefghijklmn数组,双击跟进查看
等号!!!!!
虽然看不懂全部代码,但基本可以断定是base64编码
int __fastcall sub_411AB0(int a1, int a2, _BYTE *a3, unsigned int a4, int *a5)
{
int v5; // edx
int v6; // ecx
int v8; // [esp+D4h] [ebp-38h]
int v9; // [esp+D4h] [ebp-38h]
int v10; // [esp+D4h] [ebp-38h]
int v11; // [esp+D4h] [ebp-38h]
int i; // [esp+E0h] [ebp-2Ch]
unsigned int v13; // [esp+ECh] [ebp-20h]
int v14; // [esp+ECh] [ebp-20h]
int v15; // [esp+ECh] [ebp-20h]
void *v16; // [esp+F8h] [ebp-14h]
_BYTE *v17; // [esp+104h] [ebp-8h]
if ( a3 && a4 )
{
v13 = a4 / 3;
if ( (int)(a4 / 3) % 3 )
++v13;
v14 = 4 * v13;
*a5 = v14;
malloc(v14 + 1);
v16 = (void *)sub_411127(v6, v5);
if ( v16 )
{
j_memset(v16, 0, v14 + 1);
v17 = a3;
v15 = a4;
v8 = 0;
while ( v15 > 0 )
{
byte_41A144[2] = 0;
a1 = 1;
byte_41A144[1] = 0;
a2 = 1;
byte_41A144[0] = 0;
for ( i = 0; i < 3 && v15 >= 1; ++i )
{
a1 = (int)v17;
LOBYTE(a2) = *v17;
byte_41A144[i] = *v17;
--v15;
++v17;
}
if ( !i )
break;
switch ( i )
{
case 1:
*((_BYTE *)v16 + v8) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
v9 = v8 + 1;
*((_BYTE *)v16 + v9) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
a2 = ++v9;
*((_BYTE *)v16 + v9) = aAbcdefghijklmn[64];
a1 = (int)v16 + ++v9;
LOBYTE(a2) = aAbcdefghijklmn[64];
*((_BYTE *)v16 + v9) = a2;
v8 = v9 + 1;
break;
case 2:
*((_BYTE *)v16 + v8) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
v10 = v8 + 1;
*((_BYTE *)v16 + v10) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
a2 = (int)v16 + ++v10;
*((_BYTE *)v16 + v10) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | (4 * (byte_41A144[1] & 0xF))];
a1 = (int)v16 + ++v10;
LOBYTE(a2) = aAbcdefghijklmn[64];
*((_BYTE *)v16 + v10) = a2;
v8 = v10 + 1;
break;
case 3:
*((_BYTE *)v16 + v8) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
v11 = v8 + 1;
*((_BYTE *)v16 + v11) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
*((_BYTE *)v16 + ++v11) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | (4 * (byte_41A144[1] & 0xF))];
a2 = (int)v16 + ++v11;
*((_BYTE *)v16 + v11) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
a1 = v11 + 1;
v8 = v11 + 1;
break;
}
}
*((_BYTE *)v16 + v8) = 0;
}
}
return sub_411127(a1, a2);
}
分析到这里已经很清晰了
将Str2字符串减去 j,再将其base64逆运算(base64是一个可逆的加密算法)就可以得到结果!
python脚本如下
import base64
str2 = 'e3nifIH9b_C@n@dH'
flag = ''
for i in range(len(str2)):
flag += chr(ord(str2[i]) - i)
flag = base64.b64decode(flag)
print(flag)
"""
for对应
for ( j = 0; j < v11; ++j )
Destination[j] += j;
"""