用exeinfo打开,发现是32位的程序。
直接用ida打开看看:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ecx
int *v4; // eax
int v5; // ecx
int *v6; // eax
char *v7; // esi
signed int v8; // edi
unsigned int v9; // kr00_4
_BYTE *v10; // ecx
_QWORD *v11; // ecx
int *v12; // ecx
__int128 *v13; // edx
unsigned int v14; // edi
int v15; // eax
int v16; // eax
bool v17; // cf
unsigned __int8 v18; // al
unsigned __int8 v19; // al
unsigned __int8 v20; // al
const char *v21; // edx
int *v22; // eax
char *v23; // eax
void *v25; // [esp+24h] [ebp-A0h]
int v26; // [esp+34h] [ebp-90h]
unsigned int v27; // [esp+38h] [ebp-8Ch]
__int128 v28; // [esp+3Ch] [ebp-88h]
__int128 v29; // [esp+4Ch] [ebp-78h]
int v30; // [esp+5Ch] [ebp-68h]
__int128 v31; // [esp+60h] [ebp-64h]
__int128 v32; // [esp+70h] [ebp-54h]
int v33; // [esp+80h] [ebp-44h]
__int64 v34; // [esp+84h] [ebp-40h]
int v35; // [esp+8Ch] [ebp-38h]
__int16 v36; // [esp+90h] [ebp-34h]
int v37; // [esp+94h] [ebp-30h]
int v38; // [esp+98h] [ebp-2Ch]
int v39; // [esp+9Ch] [ebp-28h]
int v40; // [esp+A0h] [ebp-24h]
int v41; // [esp+A4h] [ebp-20h]
int v42; // [esp+A8h] [ebp-1Ch]
int v43; // [esp+ACh] [ebp-18h]
int v44; // [esp+B0h] [ebp-14h]
int v45; // [esp+C0h] [ebp-4h]
v26 = 0;
v27 = 15;
LOBYTE(v25) = 0;
v45 = 0;
LOBYTE(v45) = 1;
v4 = printff(v3, "Please input your flag: ");
sub_403050((int)v4);
scanf(&dword_430068, &v25);
v35 = 1413701433;
v34 = qword_42B9A0;
v36 = 70;
if ( v26 == 32 )
{
v41 = -1173078761;
v42 = 494076752;
v43 = -1811652486;
v44 = 688582768;
v8 = 0;
v31 = 0i64;
v33 = 0;
v32 = 0i64;
v9 = strlen((const char *)&v34);
do
{
v10 = &v25;
if ( v27 >= 0x10 )
v10 = v25;
v10[v8] ^= *((_BYTE *)&v34 + v8 % v9);
++v8;
}
while ( v8 < 32 );
v11 = &v25;
v7 = (char *)v25;
if ( v27 >= 0x10 )
v11 = v25;
v30 = 0;
v28 = 0i64;
v29 = 0i64;
*(_QWORD *)&v31 = *v11;
*((_QWORD *)&v31 + 1) = v11[1];
*(_QWORD *)&v32 = v11[2];
*((_QWORD *)&v32 + 1) = v11[3];
sub_4025C0();
v37 = -133220429;
v38 = 1571732668;
v12 = &v37;
v39 = -2041750854;
v13 = &v28;
v40 = -748513468;
v14 = 28;
v41 = 371505743;
v42 = 443719435;
v43 = 644704357;
v44 = 1741188026;
while ( 1 )
{
v15 = *v12;
if ( *v12 != *(_DWORD *)v13 )
break;
++v12;
v13 = (__int128 *)((char *)v13 + 4);
v17 = v14 < 4;
v14 -= 4;
if ( v17 )
{
v16 = 0;
goto LABEL_19;
}
}
v17 = (unsigned __int8)v15 < *(_BYTE *)v13;
if ( (_BYTE)v15 != *(_BYTE *)v13
|| (v18 = *((_BYTE *)v12 + 1), v17 = v18 < *((_BYTE *)v13 + 1), v18 != *((_BYTE *)v13 + 1))
|| (v19 = *((_BYTE *)v12 + 2), v17 = v19 < *((_BYTE *)v13 + 2), v19 != *((_BYTE *)v13 + 2))
|| (v20 = *((_BYTE *)v12 + 3), v17 = v20 < *((_BYTE *)v13 + 3), v20 != *((_BYTE *)v13 + 3)) )
{
v16 = -v17 | 1;
}
else
{
v16 = 0;
}
LABEL_19:
if ( v16 )
v21 = "Try again!\r\n";
else
v21 = "Congratulations! I always knew you could do it.";
v22 = printff((int)v12, v21);
sub_403050((int)v22);
sub_40ADBE("pause");
}
else
{
v6 = printff(v5, "Try again!\r\n");
sub_403050((int)v6);
sub_40ADBE("pause");
v7 = (char *)v25;
}
if ( v27 >= 0x10 )
{
v23 = v7;
if ( v27 + 1 >= 0x1000 )
{
v7 = (char *)*((_DWORD *)v7 - 1);
if ( (unsigned int)(v23 - v7 - 4) > 0x1F )
_invalid_parameter_noinfo_noreturn(v27 + 36);
}
sub_4064DE(v7);
}
return 0;
}
前面有几个函数不知道是啥,通过动态调试,发现第三个函数和输入有关,先猜测是scanf。 经过动态调试后,确定了,最终v25是字符串地址,V26是长度。
接下来就是与将input与SWPU_2019_CTF进行异或操作。
接下来就是一个看起来很复杂的加密函数sub_4025C0(),由于不懂是啥意思,通过动态调试下断点的方法看看。
在调用这个函数前。先锁定两个字符串地址。
其中一个是经过前面异或变换的字符串:
另一个是空的,最终这个函数会将结果放到这个字符串中,因此我们下一个硬件断点。
最终在了这。这一段循环就是一段异或操作。异或的字符串是[esi+eax]。
异或的字符串为:
最后就是和v38往下这一群字符串进行比对了。
所以说现在就很明确了。写脚本即可。
附上C语言脚本:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
int main() {
unsigned int fina[10] = { 0xF80F37B3 ,0x5DAEBCBC ,0x864D5ABA ,0xD3629744 ,0x1624BA4F ,0x1A729F0B,0x266D6865,0x67C86BBA };
unsigned int med[10] = { 0xca3e0c86,0x19aed798,0xa66b77e2,0xb077a16a,0x05379169,0x307bf97a,0x104b5a43,0x28d47d86 };
char SWPU_2019_CTF[20] = "SWPU_2019_CTF";
char answer[50] = { 0 };
for (int i = 0; i < 8; i++) {
fina[i] = fina[i] ^ med[i];
}
for (int i = 0; i < 32; i++) {
answer[i] = SWPU_2019_CTF[i%13] ^ *((char *)fina + i);
}
printf("%s", answer);
}
//ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`