这道题先 放到 IDA 分析
int __thiscall sub_402810(void *this)
{
int v1; // eax
int v2; // ecx
int v3; // eax
int v4; // esi
signed int idx; // edi
unsigned int len_buf1; // kr00_4
int *v7; // ecx
int *v8; // ecx
int *arr_; // ecx
__int128 *v10; // edx
unsigned int v11; // edi
int v12; // eax
int v13; // eax
bool flag; // cf
unsigned __int8 v15; // al
unsigned __int8 v16; // al
unsigned __int8 v17; // al
const char *v18; // edx
int v19; // eax
int v20; // eax
int v22; // [esp-14h] [ebp-D8h]
int v23; // [esp-10h] [ebp-D4h]
int *input; // [esp+24h] [ebp-A0h]
int v25; // [esp+34h] [ebp-90h]
unsigned int v26; // [esp+38h] [ebp-8Ch]
__int128 v27; // [esp+3Ch] [ebp-88h]
__int128 v28; // [esp+4Ch] [ebp-78h]
int v29; // [esp+5Ch] [ebp-68h]
__int128 input__; // [esp+60h] [ebp-64h]
__int128 v31; // [esp+70h] [ebp-54h]
int v32; // [esp+80h] [ebp-44h]
__int64 buf1; // [esp+84h] [ebp-40h]
int v34; // [esp+8Ch] [ebp-38h]
__int16 v35; // [esp+90h] [ebp-34h]
int arr[8]; // [esp+94h] [ebp-30h]
int v37; // [esp+C0h] [ebp-4h]
v25 = 0;
v26 = 0xF;
LOBYTE(input) = 0;
v37 = 0;
LOBYTE(v37) = 1;
v1 = copy(this, "Please input your flag: ");
print(v1);
read_input(&dword_430068, &input);
v34 = 'TC_9';
buf1 = str1; // SWPU_2019_CTF
v35 = 'F';
if ( v25 == 32 )
{
arr[4] = 0xBA143D17;
arr[5] = 0x1D730350;
arr[6] = 0x9404607A;
arr[7] = 0x290AF070;
idx = 0;
input__ = 0i64;
v32 = 0;
v31 = 0i64;
len_buf1 = strlen(&buf1);
do
{
v7 = &input;
if ( v26 >= 0x10 )
v7 = input;
*(v7 + idx) ^= *(&buf1 + idx % len_buf1); // 异或 "SWPU_2019_CTF"
++idx;
}
while ( idx < 32 );
v8 = &input;
v4 = input;
if ( v26 >= 0x10 )
v8 = input;
v29 = 0;
v27 = 0i64;
v28 = 0i64;
*&input__ = *v8;
*(&input__ + 1) = *(v8 + 1);
*&v31 = *(v8 + 2);
*(&v31 + 1) = *(v8 + 3); // 将 flag 异或后的 值 放到 input__ 对应的地址去
func(v22, v23, 0x100, &input__, &v27); // input 于一个 数组进行 异或 返回保存在 v27中 再与 arr 数组进行比较
arr[0] = 0xF80F37B3;
arr[1] = 0x5DAEBCBC;
arr_ = arr;
arr[2] = 0x864D5ABA;
v10 = &v27;
arr[3] = 0xD3629744;
v11 = 28;
arr[4] = 0x1624BA4F;
arr[5] = 0x1A729F0B;
arr[6] = 0x266D6865;
arr[7] = 0x67C86BBA;
while ( 1 )
{
v12 = *arr_;
if ( *arr_ != *v10 ) // v27 = arr
break;
++arr_;
v10 = (v10 + 4);
flag = v11 < 4;
v11 -= 4;
if ( flag ) // flag = 1
{
v13 = 0;
goto LABEL_19;
}
}
flag = v12 < *v10;
if ( v12 != *v10
|| (v15 = *(arr_ + 1), flag = v15 < *(v10 + 1), v15 != *(v10 + 1))
|| (v16 = *(arr_ + 2), flag = v16 < *(v10 + 2), v16 != *(v10 + 2))
|| (v17 = *(arr_ + 3), flag = v17 < *(v10 + 3), v17 != *(v10 + 3)) )
{
v13 = -flag | 1;
}
else
{
v13 = 0;
}
LABEL_19:
if ( v13 )
v18 = "Try again!\\r\\n";
else
v18 = "Congratulations! I always knew you could do it.";
v19 = copy(arr_, v18);
print(v19);
system("pause");
}
else
{
v3 = copy(v2, "Try again!\\r\\n");
print(v3);
system("pause");
v4 = input;
}
if ( v26 >= 0x10 )
{
v20 = v4;
if ( v26 + 1 >= 0x1000 )
{
v4 = *(v4 - 4);
if ( (v20 - v4 - 4) > 0x1F )
sub_40AFF7(v26 + 36);
}
sub_4064DE(v4);
}
return 0;
}
发现 我们输入的 长度应该为 32 位。
第一层加密: 我们的输入 按位 和 字符串 "SWPU_2019_CTF" 进行异或
然后进入 func 函数。
我们经过 func 处理后 与 数组 进行 比较。
程序的 整体 逻辑是。
input ^ "SWPU_2019_CTF" ^ buf == arr
可以推出
input = arr ^ buf ^ "SWPU_2019_CTF"
我们 动态调试dump buf 和 arr
arr=[0xB3,0x37,0x0F,0xF8,0xBC,0xBC,0xAE,0x5D,
0xBA,0x5A,0x4D,0x86,0x44,0x97,0x62,0xD3,
0x4F,0xBA,0x24,0x16,0x0B,0x9F,0x72,0x1A,
0x65,0x68,0x6D,0x26,0xBA,0x6B,0xC8,0x67
]
str="SWPU_2019_CTF"
buf=[0x86,0x0C,0x3E,0xCA,0x98,0xD7,0xAE,0x19,0xE2,0x77,0x6B,0xA6,0x6A,0xA1,0x77,0xB0,0x69,0x91,0x37,0x05,0x7A,0xF9,0x7B,0x30,0x43,0x5A,0x4B,0x10,0x86,0x7D,0xD4,0x28]
flag = ""
for i in range(len(buf)):
flag += chr(ord(str[i%len(str)])^buf[i]^arr[i])
print flag
# flag{Y0uaretheB3st!#@_VirtualCC}