由于比较忙,时间紧,先把分析过程中主要的代码贴上来先
int __cdecl sub_4156F0(_DWORD *a1, int a2, int (__fastcall *a3)(int, int *), int a4, unsigned int a5, int a6, int a7, int a8, int *a9, int a10, int a11, int a12, int a13)
{
int v13; // ecx
int v14; // ecx
unsigned int v15; // ebx
int *v16; // edx
int v17; // ecx
int v18; // eax
void *retaddr[2]; // [esp+0h] [ebp+0h]
v14 = v13 - 1;
v15 = 1;
v16 = &a7;
if ( a5 >= 1 )
{
v14 = a7;
if ( a5 >= 2 )
{
v16 = a9;
if ( a5 >= 3 && a5 >= 4 )
{
v14 = a13 - 1;
v16 = &a9[2 * (a5 - 1) - 2];
}
}
}
while ( 1 )
{
v17 = v14 - 1;
if ( a5 < v15 )
break;
v18 = *v16;
v16 -= 2;
v14 = v17 - 3;
++v15;
}
*a1 = a3(v17, v16) - 4;
return MK_FP(retaddr[0], retaddr[0])();
}
signed int sub_4155AC()
{
char *v0; // ebp
__m128i v1; // xmm1
unsigned int v2; // edx
char v3; // al
int v4; // ecx
int v5; // eax
_BYTE *v6; // ecx
int v7; // ecx
_BYTE *v8; // edx
int v9; // ecx
unsigned int v12; // edx
bool v13; // zf
char v14; // al
unsigned int v15; // ecx
unsigned int v16; // eax
int v17; // eax
char v18; // al
unsigned int v19; // ecx
unsigned int v20; // eax
int v21; // eax
char v23[5]; // [esp+Ch] [ebp-34h]
_BYTE v24[3]; // [esp+11h] [ebp-2Fh]
__int128 v25; // [esp+20h] [ebp-20h]
__int128 v26; // [esp+30h] [ebp-10h]
int savedregs; // [esp+40h] [ebp+0h]
v0 = (char *)&savedregs + 1;
v1 = _mm_load_si128((const __m128i *)0xFFFFFE50);
*(_DWORD *)&v23[1] = 44;
v2 = 0;
_mm_storeu_si128((__m128i *)v24, _mm_load_si128((const __m128i *)0xFFFFFE4B));
_mm_storeu_si128((__m128i *)((char *)&v26 + 1), _mm_load_si128((const __m128i *)0xFFFFFE12));
_mm_storeu_si128((__m128i *)((char *)&v25 + 1), v1);
do
{
v3 = v2 - 52;
v4 = v2++;
v24[v4] ^= v3;
v5 = *(_DWORD *)&v23[1];
}
while ( v2 < *(_DWORD *)&v23[1] );
v24[*(_DWORD *)&v23[1]] = 0;
v6 = (_BYTE *)(v4 + 2);
LOBYTE(v5) = *v6;
if ( *v6 )
{
v7 = (int)(v6 - 1);
v0 = (char *)&savedregs;
v8 = &v24[-v7];
do
{
v9 = v7 + 1;
if ( (_BYTE)v5 != v8[v9] )
break;
--v5;
v7 = v9 + 1;
++v8;
LOBYTE(v5) = *(_BYTE *)v7;
}
while ( *(_BYTE *)v7 );
}
_EAX = v5 - 1;
__asm { arpl dx, ax }
*(v0 - 56) = -48;
v12 = 1;
v13 = *(char *)(_EAX + v0[_EAX - 48]) == v0[_EAX - 48];
*((_DWORD *)v0 - 16) = 4;
if ( v13 )
{
*((_DWORD *)v0 - 15) = 2013671449;
*(_WORD *)(v0 - 55) = 0;
*(v0 - 53) = 0;
do
{
v14 = v12 - 52;
v15 = v12++;
v0[v15 - 60] ^= v14;
v16 = *((_DWORD *)v0 - 16);
}
while ( v12 < v16 );
v0[v16 - 60] = 0;
LOBYTE(v15) = *(v0 - 60);
if ( (_BYTE)v15 )
{
v17 = (int)(v0 - 60);
do
{
*(_BYTE *)(2 * v17) = ++v15;
LOBYTE(v15) = *(_BYTE *)v17;
}
while ( *(_BYTE *)v17 );
}
}
else
{
*((_DWORD *)v0 - 15) = 1006641272;
*(_WORD *)(v0 - 55) = 0;
*(v0 - 53) = 0;
do
{
v18 = v12 - 52;
v19 = v12++;
v0[v19 - 60] ^= v18;
v20 = *((_DWORD *)v0 - 16);
}
while ( v12 < v20 );
v0[v20 - 60] = 0;
LOBYTE(v19) = *(v0 - 60);
if ( (_BYTE)v19 )
{
v21 = (int)(v0 - 60);
do
{
*(_BYTE *)(2 * v21) = ++v19;
LOBYTE(v19) = *(_BYTE *)v21;
}
while ( *(_BYTE *)v21 );
}
}
return -1;
}
int __cdecl sub_41E530(int a1, int a2)
{
int v2; // eax
char v3; // bl
char v4; // bl
char v5; // bl
char v7; // [esp+8h] [ebp-70h]
_DWORD *v8; // [esp+20h] [ebp-58h]
_DWORD *v9; // [esp+24h] [ebp-54h]
int v10; // [esp+28h] [ebp-50h]
int v11; // [esp+2Ch] [ebp-4Ch]
char v12; // [esp+30h] [ebp-48h]
char v13; // [esp+31h] [ebp-47h]
char v14; // [esp+32h] [ebp-46h]
char v15; // [esp+33h] [ebp-45h]
char v16; // [esp+34h] [ebp-44h]
char v17; // [esp+35h] [ebp-43h]
char v18; // [esp+36h] [ebp-42h]
char v19; // [esp+37h] [ebp-41h]
char v20; // [esp+38h] [ebp-40h]
char v21; // [esp+39h] [ebp-3Fh]
char v22; // [esp+3Ah] [ebp-3Eh]
char v23; // [esp+3Bh] [ebp-3Dh]
char v24; // [esp+3Ch] [ebp-3Ch]
char v25; // [esp+3Dh] [ebp-3Bh]
char v26; // [esp+3Eh] [ebp-3Ah]
char v27; // [esp+3Fh] [ebp-39h]
int i; // [esp+40h] [ebp-38h]
char v29; // [esp+44h] [ebp-34h]
char v30; // [esp+5Ch] [ebp-1Ch]
char v31; // [esp+64h] [ebp-14h]
char v32; // [esp+65h] [ebp-13h]
char v33; // [esp+66h] [ebp-12h]
char v34; // [esp+67h] [ebp-11h]
int v35; // [esp+74h] [ebp-4h]
v10 = 0;
sub_41D5D0(&v30, 8);
sub_41E400((int)&v30);
v35 = 0;
sub_41ECA0(&v29);
LOBYTE(v35) = 1;
for ( i = 0; ; i += v11 )
{
v2 = sub_41EB50((_DWORD *)a2);
v11 = v2 - i;
v27 = 64;
v31 = *(_BYTE *)sub_41E970(&v30, (int)&v27);
v26 = 64;
v32 = *(_BYTE *)sub_41E970(&v30, (int)&v26);
v25 = 64;
v33 = *(_BYTE *)sub_41E970(&v30, (int)&v25);
v24 = 64;
v34 = *(_BYTE *)sub_41E970(&v30, (int)&v24);
if ( !v11 )
break;
if ( v11 == 1 )
{
v23 = ((signed int)*(unsigned __int8 *)sub_41EB70(i) >> 2) & 0x3F;
v31 = *(_BYTE *)sub_41E970(&v30, (int)&v23);
v22 = 16 * *(_BYTE *)sub_41EB70(i) & 0x3F;
v32 = *(_BYTE *)sub_41E970(&v30, (int)&v22);
v21 = 64;
v33 = *(_BYTE *)sub_41E970(&v30, (int)&v21);
v20 = 64;
v34 = *(_BYTE *)sub_41E970(&v30, (int)&v20);
}
else if ( v11 == 2 )
{
v19 = ((signed int)*(unsigned __int8 *)sub_41EB70(i) >> 2) & 0x3F;
v31 = *(_BYTE *)sub_41E970(&v30, (int)&v19);
v3 = 16 * *(_BYTE *)sub_41EB70(i);
v18 = (((signed int)*(unsigned __int8 *)sub_41EB70(i + 1) >> 4) | v3) & 0x3F;
v32 = *(_BYTE *)sub_41E970(&v30, (int)&v18);
v17 = 4 * *(_BYTE *)sub_41EB70(i + 1) & 0x3F;
v33 = *(_BYTE *)sub_41E970(&v30, (int)&v17);
v16 = 64;
v34 = *(_BYTE *)sub_41E970(&v30, (int)&v16);
}
else
{
v15 = ((signed int)*(unsigned __int8 *)sub_41EB70(i) >> 2) & 0x3F;
v31 = *(_BYTE *)sub_41E970(&v30, (int)&v15);
v4 = 16 * *(_BYTE *)sub_41EB70(i) & 0x3F;
v14 = (((signed int)*(unsigned __int8 *)sub_41EB70(i + 1) >> 4) & 0x3F | v4) & 0x3F;
v32 = *(_BYTE *)sub_41E970(&v30, (int)&v14);
v5 = 4 * *(_BYTE *)sub_41EB70(i + 1);
v13 = (((signed int)*(unsigned __int8 *)sub_41EB70(i + 2) >> 6) | v5) & 0x3F;
v33 = *(_BYTE *)sub_41E970(&v30, (int)&v13);
v12 = *(_BYTE *)sub_41EB70(i + 2) & 0x3F;
v34 = *(_BYTE *)sub_41E970(&v30, (int)&v12);
v11 = 3;
}
v9 = sub_41EC00(&v7, (int)&v31, 4u);
v8 = v9;
LOBYTE(v35) = 2;
sub_41EB90((int)v9);
LOBYTE(v35) = 1;
sub_41D700(&v7);
}
sub_41EBB0((void *)a1, &v29);
v10 |= 1u;
LOBYTE(v35) = 0;
sub_41D700(&v29);
v35 = -1;
sub_41E510(&v30);
return a1;
}
_DWORD *__userpurge sub_41D2D0@<eax>(_DWORD *this@<ecx>, int ebx0@<ebx>, int a3@<edi>, int a4@<esi>, int a2)
{
_DWORD *result; // eax
void *v6; // eax
int v7; // eax
int v8; // eax
LPVOID v9[17]; // [esp+4h] [ebp-100h]
char v10; // [esp+48h] [ebp-BCh]
int v11; // [esp+60h] [ebp-A4h]
void *v12; // [esp+64h] [ebp-A0h]
void *v13; // [esp+68h] [ebp-9Ch]
_DWORD *v14; // [esp+6Ch] [ebp-98h]
char v15; // [esp+70h] [ebp-94h]
char v16; // [esp+88h] [ebp-7Ch]
__m128i v17[6]; // [esp+90h] [ebp-74h]
int v18; // [esp+100h] [ebp-4h]
v14 = this;
result = this;
if ( this[346] == *(_DWORD *)(a2 + 136) )
{
v6 = (void *)(*(int (__thiscall **)(_DWORD, LPVOID *))(*(_DWORD *)v14[347] + 40))(v14[347], v9);
v13 = v6;
v12 = v6;
v18 = 0;
v7 = sub_427595(v6);
sub_41D760(&v15, v7);
LOBYTE(v18) = 2;
sub_42748E(v9);
v11 = sub_41E530((int)&v10, (int)&v15);
sub_41D720(v11);
sub_41D700(&v10);
sub_41D660(&v16, (int)&(*off_48F970)[109], (unsigned __int64)&(*off_48F970)[109] >> 32);
sub_470DB0(v17, 0, 0x64u);
v8 = sub_41D6E0(&v15);
sub_41D600(&v16, ebx0, a3, a4, v8, (int)v17);
(*(void (__thiscall **)(_DWORD, __m128i *))(*(_DWORD *)v14[347] + 44))(v14[347], v17);
v18 = -1;
result = (_DWORD *)sub_41D700(&v15);
}
return result;
}
通过分析和动态跟踪编码转换函数,将编码表找出来了
0055EF0C |0055EF18 ASCII "prvo9CHSJOcPIb6xRVUXQz0qBGDE72LNZduaefYT5K_8-4FAhlimjkngt1yMWs3w!"
主要的流程是将输入的序列号,通过上面的编码表,用base64的编码规则,得到
GYldGg-iIoJlPX9hPXpjPqfdEY21B01TBTzeGqfKNR!!,就成功了
在网上找到一份base64的源码,将里面的编码表替换掉,然后将经过编码的结果做解码,得到正确的序列号明文
flag{2021-10-04-yangyangbudeyi}
分析过程中发现自己有很多技术盲区,感谢一位热心的朋友指点。
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
最后于 2021-12-3 11:23
被yegu编辑
,原因: