一,我的白月光
BOOK框还叉不掉,主函数很长
int __cdecl main(int argc, const char **argv, const char **envp)
{
__m128 si128; // xmm6
__int128 *v4; // rax
int v5; // r13d
unsigned int v6; // ecx
__m128 v7; // xmm0
_DWORD *v8; // rax
HMODULE ModuleHandleA; // rdi
unsigned int *v10; // rbx
_QWORD *v11; // r12
__int64 v12; // rax
char *v13; // rbx
size_t v14; // rdi
unsigned __int64 v15; // rsi
void *v16; // r14
size_t v17; // rax
__int64 v18; // rax
unsigned __int64 v19; // rbx
void **v20; // rcx
size_t v21; // r8
__int64 v22; // r15
_BYTE *v23; // rax
__int64 v24; // rdi
char *v25; // rbx
_DWORD *v26; // rcx
unsigned int v27; // eax
__m128 v28; // xmm0
__int64 i; // rbx
const WCHAR *v30; // rdx
char v32[10]; // [rsp+20h] [rbp-E0h] BYREF
__int64 *v33; // [rsp+30h] [rbp-D0h]
unsigned int *v34; // [rsp+38h] [rbp-C8h]
void *Buf1[2]; // [rsp+40h] [rbp-C0h] BYREF
size_t v36; // [rsp+50h] [rbp-B0h]
unsigned __int64 v37; // [rsp+58h] [rbp-A8h]
HMODULE v38; // [rsp+60h] [rbp-A0h]
char v39[1024]; // [rsp+80h] [rbp-80h] BYREF
DWORD flOldProtect[2]; // [rsp+480h] [rbp+380h] BYREF
char Buf2[8]; // [rsp+488h] [rbp+388h] BYREF
char v42[16]; // [rsp+490h] [rbp+390h] BYREF
__int128 v43[63]; // [rsp+4A0h] [rbp+3A0h] BYREF
char v44[1008]; // [rsp+890h] [rbp+790h] BYREF
sub_1400025D0(0x280u, 0x1E0u, 0);
sub_140002650(0xFFFFFFi64);
sub_140002580();
sub_140002670(0xAA00u); //这个好像是初始窗口
sub_140002660(1u);
sub_140002690(0xAAu);
v43[0] = _mm_load_si128(&xmmword_14000ADE0);
v43[1] = _mm_load_si128(&xmmword_14000ADF0);
v43[2] = _mm_load_si128(&xmmword_14000AD70);
v43[3] = _mm_load_si128(&xmmword_14000ADC0);
v43[4] = _mm_load_si128(&xmmword_14000AE30);
v43[5] = _mm_load_si128(&xmmword_14000AD80);
v43[6] = _mm_load_si128(&xmmword_14000ADD0);
v43[7] = _mm_load_si128(&xmmword_14000ADB0);
v43[8] = _mm_load_si128(&xmmword_14000AD90);
v43[9] = _mm_load_si128(&xmmword_14000AE00);
v43[10] = _mm_load_si128(&xmmword_14000ADA0);
v43[11] = _mm_load_si128(&xmmword_14000AD60);
v43[12] = _mm_load_si128(&xmmword_14000AE20);
v43[13] = _mm_load_si128(&xmmword_14000AE10);
*&v43[14] = 0x4E5C0000809Bi64;
DWORD2(v43[14]) = 21245;
memset(&v43[14] + 12, 0, 0xA4ui64);
si128 = _mm_load_si128(&xmmword_14000AD50);
v4 = &v43[1];
v5 = 0;
v6 = 0;
do
{
v7 = _mm_loadu_si128(v4 - 1);
v4 += 4;
v6 += 16;
*(v4 - 5) = _mm_xor_ps(si128, v7);
*(v4 - 4) = _mm_xor_ps(_mm_loadu_si128(v4 - 4), si128);
*(v4 - 3) = _mm_xor_ps(si128, _mm_loadu_si128(v4 - 3));
*(v4 - 2) = _mm_xor_ps(si128, _mm_loadu_si128(v4 - 2));
}
while ( v6 < 0x60 );
if ( v6 < 0x64 )
{
v8 = v43 + v6;
do
{
*v8++ ^= 0x66u;
++v6;
}
while ( v6 < 0x64 );
}
sub_140002630(0i64, 0i64, &unk_14000A5F8);
sub_140002630(50i64, 50i64, &unk_14000A620);
sub_140002630(100i64, 100i64, &unk_14000A648);
sub_140002630(150i64, 150i64, &unk_14000A668);
sub_140002630(200i64, 200i64, &unk_14000A688);
sub_140002630(250i64, 250i64, &unk_14000A6A8);
sub_140002630(300i64, 300i64, &unk_14000A6D8);
sub_140002630(350i64, 350i64, aFlagL0v3);
MessageBoxA(0i64, "LOOK_ME_AGAIN", "BOOB", 0);
ModuleHandleA = GetModuleHandleA(0i64);
v38 = ModuleHandleA;
v10 = (ModuleHandleA + *(ModuleHandleA + *(ModuleHandleA + 15) + 144));
v34 = v10;
if ( v10[3] )
{
while ( 1 )
{
if ( LoadLibraryA(ModuleHandleA + v10[3]) )
{
v33 = (ModuleHandleA + *v10);
v11 = (ModuleHandleA + v10[4]);
v12 = *v33;
if ( *v33 )
break;
}
LABEL_44:
v10 += 5;
v34 = v10;
if ( !v10[3] )
goto LABEL_45;
}
while ( 1 )
{
qmemcpy(v32, "essigiLozU", sizeof(v32));
v42[3] = 0;
v13 = ModuleHandleA + v12;
*Buf1 = 0i64;
v14 = -1i64;
do
++v14;
while ( v13[v14 + 2] );
if ( v14 > 0x7FFFFFFFFFFFFFFFi64 )
sub_140001270();
if ( v14 <= 0xF )
{
v36 = v14;
v37 = 15i64;
memcpy(Buf1, v13 + 2, v14);
*(Buf1 + v14) = 0;
v15 = v37;
v14 = v36;
v16 = Buf1[0];
goto LABEL_26;
}
v15 = v14 | 0xF;
if ( (v14 | 0xF) > 0x7FFFFFFFFFFFFFFFi64 )
break;
if ( v15 < 0x16 )
v15 = 22i64;
if ( v15 + 1 >= 0x1000 )
{
v17 = v15 + 40;
if ( v15 + 40 <= v15 + 1 )
sub_1400011D0();
goto LABEL_20;
}
if ( v15 == -1i64 )
v16 = 0i64;
else
v16 = sub_1400081BC(v15 + 1);
LABEL_25:
Buf1[0] = v16;
v36 = v14;
v37 = v15;
memcpy(v16, v13 + 2, v14);
*(v16 + v14) = 0;
LABEL_26:
v19 = -1i64;
Buf2[0] = 77;
Buf2[1] = (v32[0] - 1) ^ 1;
Buf2[2] = (v32[1] - 2) ^ 2;
Buf2[3] = (v32[2] - 3) ^ 3;
Buf2[4] = (v32[3] - 4) ^ 4;
Buf2[5] = (v32[4] - 5) ^ 5;
Buf2[6] = (v32[5] - 6) ^ 6;
Buf2[7] = (v32[6] - 7) ^ 7;
v42[0] = (v32[7] - 8) ^ 8;
v42[1] = (v32[8] - 9) ^ 9;
v42[2] = (v32[9] - 10) ^ 0xA;
do
++v19;
while ( Buf2[v19] );
v20 = Buf1;
v21 = v14;
if ( v15 > 0xF )
v20 = v16;
if ( v19 < v14 )
v21 = v19;
LODWORD(v22) = memcmp(v20, Buf2, v21);
if ( !v22 )
{
if ( v14 >= v19 )
v22 = v14 > v19;
else
LODWORD(v22) = -1;
}
if ( v15 > 0xF )
{
v23 = v16;
if ( v15 + 1 >= 0x1000 )
{
v16 = *(v16 - 1);
if ( (v23 - v16 - 8) > 0x1F )
LABEL_56:
invalid_parameter_noinfo_noreturn();
}
j_j_free(v16);
}
if ( !v22 )
{
flOldProtect[0] = 0;
VirtualProtect(v11, 8ui64, 4u, flOldProtect);
*v11 = sub_140001470;
}
++v11;
ModuleHandleA = v38;
v12 = *++v33;
if ( !*v33 )
{
v10 = v34;
goto LABEL_44;
}
}
v15 = 0x7FFFFFFFFFFFFFFFi64;
v17 = 0x8000000000000027ui64;
LABEL_20:
v18 = sub_1400081BC(v17);
if ( !v18 )
goto LABEL_56;
v16 = ((v18 + 39) & 0xFFFFFFFFFFFFFFE0ui64);
*(v16 - 1) = v18;
goto LABEL_25;
}
LABEL_45:
v24 = 440i64;
v25 = v39;
do
{
v26 = 0i64;
v43[0] = _mm_load_si128(&xmmword_14000AC40);
v43[2] = _mm_load_si128(&xmmword_14000AC50);
v43[1] = _mm_load_si128(&xmmword_14000AB10);
v43[4] = _mm_load_si128(&xmmword_14000AC30);
v43[3] = _mm_load_si128(&xmmword_14000AD20);
v43[6] = _mm_load_si128(&xmmword_14000AC10);
v43[5] = _mm_load_si128(&xmmword_14000ABB0);
v43[8] = _mm_load_si128(&xmmword_14000ABF0);
v43[7] = _mm_load_si128(&xmmword_14000AB60);
v43[10] = _mm_load_si128(&xmmword_14000AD30);
v43[9] = _mm_load_si128(&xmmword_14000AD40);
v43[12] = _mm_load_si128(&xmmword_14000ABE0);
v43[11] = _mm_load_si128(&xmmword_14000AD10);
v43[14] = _mm_load_si128(&xmmword_14000AC70);
v43[13] = _mm_load_si128(&xmmword_14000AC20);
v43[16] = _mm_load_si128(&xmmword_14000AB20);
v43[15] = _mm_load_si128(&xmmword_14000AB30);
v43[18] = _mm_load_si128(&xmmword_14000AB90);
v43[17] = _mm_load_si128(&xmmword_14000AC60);
LODWORD(v43[20]) = 22;
v27 = 0;
*(&v43[20] + 4) = 0i64;
*(&v43[24] + 4) = 0i64;
*(&v43[21] + 4) = 0i64;
HIDWORD(v43[24]) = 0;
*(&v43[22] + 4) = 0i64;
*(&v43[23] + 4) = 0i64;
v43[19] = _mm_load_si128(&xmmword_14000AC00);
do
{
v28 = _mm_loadu_si128((v43 + 4 * v26));
v26 += 4;
v27 += 16;
*&v39[4 * v26 + 992] = _mm_xor_ps(si128, v28);
*&v39[4 * v26 + 1008] = _mm_xor_ps(_mm_loadu_si128(&v39[4 * v26 + 1008]), si128);
*&flOldProtect[v26] = _mm_xor_ps(_mm_loadu_si128(&flOldProtect[v26]), si128);
*&v42[4 * v26] = _mm_xor_ps(_mm_loadu_si128(&v42[4 * v26]), si128);
}
while ( v27 < 0x60 );
if ( v27 < 0x64 )
{
v26 = v43 + v26;
do
{
*v26++ ^= 0x66u;
++v27;
}
while ( v27 < 0x64 );
}
sub_1400024A0(v26, LODWORD(v43[0]));
*v25++ = (MessageBoxA(0i64, &byte_14000A758, &byte_14000A748, 4u) & 1) == 0;
--v24;
}
while ( v24 );
for ( i = 0i64; i < 440; i += 8i64 )
{
sub_140001070(&v44[v5 / 4], 0x3E8ui64, "%02x");
v5 += 8;
}
v44[55] = 0;
memset(v43, 0, 0x3E8ui64);
sub_140001290(v44, v43);
if ( !memcmp(
v43,
"1YmNkZTN2QmNmdjM3kTNmZTZ2UzN2YTN3ITNmZzN2YWNmZDN2YmNlZTN1YmN2YTO2UmNxYzY2M2N5UjZ3QjN4YTM2UmNidTO2Y2N1UjZ3gjN5Y"
"TM2Y2N3YTM2UmN3cDN2YmNlZzN3gzN1YTN3QG=",
0x94ui64) )
{
v30 = &unk_14000A840;
}
else
{
MessageBoxW(0i64, &word_14000A998, L"BOOB", 0);
v30 = L"I_AM_NOT_EXIT_HOPE_YOU_CAN_BE_BETTER_SEE_YOU_AGAIN_JUST_LIKE_I_WAS_BEING_REPLACED";
}
MessageBoxW(0i64, v30, L"BOOB", 0);
return 0;
}
二,记忆中的时光机
00055EEFC204018这报红了,
不对,P可以,但报更多红了。
好像又只能看汇编了
通过在栈上存放地址,每次执行一段操作后,读栈上保存的地址并跳转,实现函数内的控制流。动态调试一下 check 函数第一次 jmp 后可以知道 flag 长度为 48 走到 enc 被调用处,edi 寄存器是用户输入的字符串指针,esi 寄存器是即将比对的字符下标,每次调用 enc 将加密一个字符,手动记录关键 ,额,不是太懂。
edi = (char*)Input
esi = (int)Idx
r10 = esi
esi += 6
r11 = (char*)Key
r8d = (char)Input[Idx]
r8d ^= esi
r8d ^= 0x66
r8d -= 6
r9d = (char)Key[Idx]
r8d ^= r9d
eax = r8d
cpp
#include <stdio.h>
unsigned char ans[] =
{
0x69, 0x58, 0x61, 0x63, 0x67, 0x4C, 0x4D, 0x32, 0x98, 0x20,
0x4D, 0x51, 0x7B, 0x25, 0x75, 0x51, 0xA3, 0x58, 0x60, 0x72,
0x42, 0x62, 0x67, 0x66, 0x37, 0x6C, 0x30, 0x46, 0x66, 0x4F,
0x5D, 0x03, 0x5D, 0xA4, 0x66, 0x01, 0x43, 0x68, 0x7D, 0x7C,
0x55, 0x4F, 0x7A, 0x3F, 0x6C, 0x12, 0x21, 0x09};
const char *key = "i_have_get_shell_but_where_is_you_my_dear_baby!!";
int main() {
for (int i = 0; i < 48; i++) {
ans[i] ^= key[i];
ans[i] += 6;
ans[i] ^= 0x66;
ans[i] ^= (i + 6);
}
printf(ans);
return 0;
}
三,简爱
又不晓得什么问题,包括文件路径不正确、文件格式不受支持、调试器插件配置错误等
zsh: exec format error: ./简爱
file '/root/Desktop/简爱'
/root/Desktop/简爱: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
给出的是可重定位目标文件(只编译了、没有链接),链接一下
最好先改成英文的,中文字符串是国标码,打印出来全是问号
对几个字符串的复制与引用很混乱(问了出题人发现是因为用了栈上的可变长度数组),动态调试才知道每一处分别用的是哪个地址的字符串 TEA 是骗人的,真正的加密逻辑在 howtolove 函数(参数是用户输入原样),密文需要与 fake flag 一致,z3 梭了
好像还是一个vm题,啊!
四,相逢已是上上签
好像又是16位的,拖ida,也打不开。用010分析一下
发现这并不是一个16位的程序,他有标准的PE头的不知道哪里被魔改了,打开一个正常的PE文件看一下:
对照修改一下:看见30h行的C位00被改成了10
成功了。
cpp
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+8h] [ebp-50h]
int i; // [esp+Ch] [ebp-4Ch]
int v6[8]; // [esp+10h] [ebp-48h]
char Str[4]; // [esp+30h] [ebp-28h] BYREF
int v8; // [esp+34h] [ebp-24h]
int v9; // [esp+38h] [ebp-20h]
int v10; // [esp+3Ch] [ebp-1Ch]
int v11; // [esp+40h] [ebp-18h]
int v12; // [esp+44h] [ebp-14h]
int v13; // [esp+48h] [ebp-10h]
int v14; // [esp+4Ch] [ebp-Ch]
char v15; // [esp+50h] [ebp-8h]
*(_DWORD *)Str = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
v12 = 0;
v13 = 0;
v14 = 0;
v15 = 0;
v6[0] = 0x66697271;
v6[1] = 0x896E2285;
v6[2] = 0xC5188C1B;
v6[3] = 0x72BCFD03;
v6[4] = 1400902090;
v6[5] = 0x4DA146AC;
v6[6] = 0x86630D6B;
v6[7] = 0xF89797F0;
print("Please enter your key:");
scan("%s", &key);
if ( 532 * *(&key + 5) + 829 * *(&key + 4) + 258 * *(&key + 3) + 811 * *(&key + 2) + 997 * *(&key + 1) + 593 * key == 292512
&& 576 * *(&key + 5) + 695 * *(&key + 4) + 602 * *(&key + 3) + 328 * *(&key + 2) + 686 * *(&key + 1) + 605 * key == 254496
&& 580 * *(&key + 5) + 448 * *(&key + 4) + 756 * *(&key + 3) + 449 * *(&key + 2) + (*(&key + 1) << 9) + 373 * key == 222479
&& 597 * *(&key + 5) + 855 * *(&key + 4) + 971 * *(&key + 3) + 422 * *(&key + 2) + 635 * *(&key + 1) + 560 * key == 295184
&& 524 * *(&key + 5) + 324 * *(&key + 4) + 925 * *(&key + 3) + 388 * *(&key + 2) + 507 * *(&key + 1) + 717 * key == 251887
&& 414 * *(&key + 5) + 495 * *(&key + 4) + 518 * *(&key + 3) + 884 * *(&key + 2) + 368 * *(&key + 1) + 312 * key == 211260 )
{
print(&unk_41B19C);
}
else
{
_loaddll(0);
}
print("Please enter your flag:");
scan("%s", Str);
if ( strlen(Str) != 32 )
{
print("Wrong length\n");
_loaddll(0);
}
v4 = (int)strlen(Str) / 4;
sub_401000((int)Str, v4);
for ( i = 0; i < v4; ++i )
{
if ( v6[i] != *(_DWORD *)&Str[4 * i] )
{
print("Wrong!!!\n");
_loaddll(0);
}
}
print("congratulations\n");
sub_40B48E("pause");
return 0;
}
先z3求出key:XYCTF ,然后还有一个重要函数
cpp
int __cdecl sub_401000(_DWORD *a1, int a2)
{
int v2; // ecx
int v3; // eax
int v4; // edx
int result; // eax
int v6; // [esp+4h] [ebp-1Ch]
int v7; // [esp+Ch] [ebp-14h]
unsigned int v8; // [esp+10h] [ebp-10h]
unsigned int v9; // [esp+18h] [ebp-8h]
unsigned int i; // [esp+1Ch] [ebp-4h]
if ( a2 > 1 )
{
v7 = 52 / a2 + 6;
v8 = 0;
v9 = a1[a2 - 1];
do
{
v8 -= 1640531527;
v6 = (v8 >> 2) & 5;
for ( i = 0; i < a2 - 1; ++i )
{
v2 = ((v9 ^ key[v6 ^ i & 5]) + (a1[i + 1] ^ v8)) ^ (((16 * v9) ^ (a1[i + 1] >> 3))
+ ((4 * a1[i + 1]) ^ (v9 >> 5)));
v3 = a1[i];
a1[i] = v2 + v3;
v9 = v2 + v3;
}
v4 = (((v9 ^ key[v6 ^ i & 5]) + (*a1 ^ v8)) ^ (((16 * v9) ^ (*a1 >> 3)) + ((4 * *a1) ^ (v9 >> 5)))) + a1[a2 - 1];
a1[a2 - 1] = v4;
result = v4;
v9 = v4;
--v7;
}
while ( v7 );
}
return result;
}
cpp
#include <stdio.h>
#define u32 unsigned int
char* Key = "XYCTF!";
void sub_401000(u32 *a1, int a2)
{
int v2; // ecx
int v3; // eax
int v4; // edx
int v5; // [esp+4h] [ebp-1Ch]
int v6; // [esp+Ch] [ebp-14h]
unsigned int v7; // [esp+10h] [ebp-10h]
unsigned int v8; // [esp+18h] [ebp-8h]
unsigned int i; // [esp+1Ch] [ebp-4h]
if (a2 > 1)
{
v6 = 52 / a2 + 6;
v7 = 0;
v8 = a1[a2 - 1];
do
{
v7 -= 0x61C88647;
v5 = (v7 >> 2) & 5;
for (i = 0; i < a2 - 1; ++i)
{
v2 = ((v8 ^ Key[v5 ^ i & 5]) + (a1[i + 1] ^ v7)) ^ (((16 * v8) ^ (a1[i + 1] >> 3)) + ((4 * a1[i + 1]) ^ (v8 >> 5)));
v3 = a1[i];
a1[i] = v2 + v3;
v8 = v2 + v3;
}
v4 = (((v8 ^ Key[v5 ^ i & 5]) + (*a1 ^ v7)) ^ (((16 * v8) ^ (*a1 >> 3)) + ((4 * *a1) ^ (v8 >> 5)))) + a1[a2 - 1];
a1[a2 - 1] = v4;
v8 = v4;
--v6;
} while (v6);
}
}
void decrypt(u32 *a1, int a2)
{
int v5; // [esp+4h] [ebp-1Ch]
int v6; // [esp+Ch] [ebp-14h]
unsigned int v7; // [esp+10h] [ebp-10h]
unsigned int v8; // [esp+18h] [ebp-8h]
int i; // [esp+1Ch] [ebp-4h]
if (a2 > 1)
{
v7 = (-0x61C88647) * (52 / a2 + 6);
for (v6 = 0; v6 < 52 / a2 + 6; ++v6)
{
v5 = (v7 >> 2) & 5;
for (i = a2 - 1; i >= 0; --i)
{
v8 = a1[(i - 1 + a2) % a2];
a1[i] -= ((v8 ^ Key[v5 ^ i & 5]) + (a1[(i + 1) % a2] ^ v7)) ^ (((16 * v8) ^ (a1[(i + 1) % a2] >> 3)) + ((4 * a1[(i + 1) % a2]) ^ (v8 >> 5)));
}
v7 += 0x61C88647;
}
}
}
int main() {
int v6[8];
v6[0] = 1718186609;
v6[1] = -1989270907;
v6[2] = -988247013;
v6[3] = 1924988163;
v6[4] = 1400902090;
v6[5] = 1302415020;
v6[6] = -2040328853;
v6[7] = -124282896;
decrypt(v6, 8);
printf("%s\n", v6);
return 0;
}
总体来说,这四个题都很难,还有很多还没搞懂。这年头,舔狗都不好当了。