好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 geesehoward 于 2026-3-6 10:26 编辑
总体来说难度不太大,c++的IDA的伪代码比C要复杂一些。
[C++] 纯文本查看 复制代码 // Hidden C++ exception states: #wind=1
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v3; // edi
__int64 v4; // r8
__int64 v5; // rax
__int64 v6; // r8
__int64 v7; // rax
__int64 v8; // r8
__int64 v9; // rax
__int64 v10; // r8
__int64 v11; // rax
__int64 v12; // r8
__int64 v13; // rdx
unsigned __int8 v14; // al
size_t v15; // r8
size_t v16; // rax
__int64 v17; // rax
void *v18; // rcx
void *v19; // rcx
void **v20; // rdx
void **v21; // rcx
size_t v22; // rbx
void *v23; // rcx
void *v24; // rcx
__int64 v25; // rax
__int64 v26; // r8
__int64 v27; // rax
__int64 v28; // r8
__int64 v29; // rax
__int64 v30; // r8
void *v31; // rcx
void **v32; // rsi
char *v33; // rsi
void **v34; // rbx
size_t v35; // rsi
void **v36; // rdx
char *v37; // rbx
void *v38; // rcx
void **v39; // rdx
void **v40; // rcx
char *v41; // rbx
unsigned __int64 v42; // rsi
char *v43; // rax
void *v44; // rcx
void *v45; // rcx
__int64 v46; // rax
__int64 v47; // r8
__int64 v48; // rax
__int64 v49; // r8
__int64 v50; // rax
char *v51; // rax
void *v52; // rcx
void *Block[2]; // [rsp+38h] [rbp-71h] BYREF
__m128i si128; // [rsp+48h] [rbp-61h]
void *v56[2]; // [rsp+58h] [rbp-51h] BYREF
__int64 v57; // [rsp+68h] [rbp-41h]
void *Buf1[2]; // [rsp+70h] [rbp-39h] BYREF
size_t Size; // [rsp+80h] [rbp-29h]
unsigned __int64 v60; // [rsp+88h] [rbp-21h]
__int128 v61; // [rsp+90h] [rbp-19h] BYREF
__int128 v62; // [rsp+A0h] [rbp-9h]
__int128 v63; // [rsp+B0h] [rbp+7h]
__int128 v64; // [rsp+C0h] [rbp+17h]
void *v65[2]; // [rsp+D0h] [rbp+27h] BYREF
size_t v66; // [rsp+E0h] [rbp+37h]
unsigned __int64 v67; // [rsp+E8h] [rbp+3Fh]
v3 = 0;
sub_7FF72D611C40(std::cout, &unk_7FF72D614478, envp);
v5 = sub_7FF72D611C40(std::cout, &unk_7FF72D614480, v4);
std::ostream::operator<<(v5, sub_7FF72D611E20);
v7 = sub_7FF72D611C40(std::cout, &unk_7FF72D6144D8, v6);
std::ostream::operator<<(v7, sub_7FF72D611E20);
v9 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v8);
std::ostream::operator<<(v9, sub_7FF72D611E20);
std::ostream::operator<<(std::cout, sub_7FF72D611E20);
*(_OWORD *)Buf1 = 0;
Size = 0;
v60 = 15;
LOBYTE(Buf1[0]) = 0;
v11 = sub_7FF72D611C40(std::cout, &unk_7FF72D614568, v10);
std::ostream::operator<<(v11, sub_7FF72D611E20);
sub_7FF72D611C40(std::cout, "Enter the flag: ", v12);
LOBYTE(v13) = 10;
v14 = std::ios::widen((char *)&std::cin + *(int *)(std::cin + 4LL), v13);
sub_7FF72D611FD0(std::cin, Buf1, v14);
v16 = Size;
if ( !Size )
{
v17 = sub_7FF72D611C40(std::cout, "[-] Input cannot be empty!", v15);
std::ostream::operator<<(v17, sub_7FF72D611E20);
std::ostream::operator<<(std::cout, sub_7FF72D611E20);
v16 = Size;
}
if ( v16 != 25 )
goto LABEL_28;
v61 = 0;
v62 = 0;
v63 = 0;
v64 = 0;
*(_OWORD *)v56 = 0;
v57 = 0;
*(_OWORD *)Block = 0;
si128 = _mm_load_si128((const __m128i *)&xmmword_7FF72D614790);
LOBYTE(Block[0]) = 0;
sub_7FF72D6121E0(&v61, Block, (__int64)v56);
if ( si128.m128i_i64[1] > 0xFuLL )
{
v18 = Block[0];
if ( (unsigned __int64)(si128.m128i_i64[1] + 1) >= 0x1000 )
{
v18 = (void *)*((_QWORD *)Block[0] - 1);
if ( (unsigned __int64)((char *)Block[0] - (char *)v18 - 8) > 0x1F )
invalid_parameter_noinfo_noreturn();
}
j_j_free(v18);
}
v19 = v56[0];
if ( v56[0] )
{
if ( v57 - (unsigned __int64)v56[0] >= 0x1000 )
{
v19 = (void *)*((_QWORD *)v56[0] - 1);
if ( (unsigned __int64)((char *)v56[0] - (char *)v19 - 8) > 0x1F )
goto LABEL_66;
}
j_j_free(v19);
}
v20 = &Buf2;
if ( *((_QWORD *)&xmmword_7FF72D6177B8 + 1) > 0xFu )
v20 = (void **)Buf2;
v21 = Buf1;
if ( v60 > 0xF )
v21 = (void **)Buf1[0];
v22 = Size;
if ( Size == (_QWORD)xmmword_7FF72D6177B8 && (!Size || !memcmp(v21, v20, Size)) )
{
v23 = (void *)*((_QWORD *)&v63 + 1);
if ( *((_QWORD *)&v63 + 1) )
{
if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
{
v23 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v23 - 8LL) > 0x1F )
goto LABEL_75;
}
j_j_free(v23);
*((_QWORD *)&v63 + 1) = 0;
v64 = 0;
}
if ( *((_QWORD *)&v62 + 1) <= 0xFu )
{
LABEL_28:
v25 = sub_7FF72D611C40(std::cout, &unk_7FF72D6145E0, v15);
std::ostream::operator<<(v25, sub_7FF72D611E20);
v27 = sub_7FF72D611C40(std::cout, &unk_7FF72D614668, v26);
std::ostream::operator<<(v27, sub_7FF72D611E20);
v29 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v28);
std::ostream::operator<<(v29, sub_7FF72D611E20);
std::ostream::operator<<(std::cout, sub_7FF72D611E20);
sub_7FF72D611C40(std::cout, "\nPress Enter to exit...", v30);
std::istream::get(std::cin);
v3 = 1;
goto LABEL_29;
}
v24 = (void *)v61;
if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) < 0x1000
|| (v24 = *(void **)(v61 - 8), (unsigned __int64)(v61 - (_QWORD)v24 - 8) <= 0x1F) )
{
LABEL_27:
j_j_free(v24);
goto LABEL_28;
}
goto LABEL_75;
}
v32 = Buf1;
if ( v60 > 0xF )
v32 = (void **)Buf1[0];
v33 = (char *)v32 + v22;
v34 = Buf1;
if ( v60 > 0xF )
v34 = (void **)Buf1[0];
*(_OWORD *)v56 = 0;
v57 = 0;
v35 = v33 - (char *)v34;
if ( v35 )
{
sub_7FF72D612950(v56, v35);
v36 = v34;
v37 = (char *)v56[0];
memmove(v56[0], v36, v35);
v56[1] = &v37[v35];
}
sub_7FF72D6123D0(&v61, v65, v56);
v38 = v56[0];
if ( v56[0] )
{
if ( v57 - (unsigned __int64)v56[0] >= 0x1000 )
{
v38 = (void *)*((_QWORD *)v56[0] - 1);
if ( (unsigned __int64)((char *)v56[0] - (char *)v38 - 8) > 0x1F )
goto LABEL_66;
}
j_j_free(v38);
}
v39 = &::Block;
if ( *((_QWORD *)&xmmword_7FF72D6177D8 + 1) > 0xFu )
v39 = (void **)::Block;
v40 = v65;
v41 = (char *)v65[0];
v42 = v67;
if ( v67 > 0xF )
v40 = (void **)v65[0];
v15 = v66;
if ( v66 != (_QWORD)xmmword_7FF72D6177D8 || v66 && memcmp(v40, v39, v66) )
{
if ( v42 > 0xF )
{
v51 = v41;
if ( v42 + 1 >= 0x1000 )
{
v41 = (char *)*((_QWORD *)v41 - 1);
if ( (unsigned __int64)(v51 - v41 - 8) > 0x1F )
goto LABEL_66;
}
j_j_free(v41);
}
v66 = 0;
v67 = 15;
LOBYTE(v65[0]) = 0;
v52 = (void *)*((_QWORD *)&v63 + 1);
if ( *((_QWORD *)&v63 + 1) )
{
if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
{
v52 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v52 - 8LL) > 0x1F )
goto LABEL_75;
}
j_j_free(v52);
*((_QWORD *)&v63 + 1) = 0;
v64 = 0;
}
if ( *((_QWORD *)&v62 + 1) <= 0xFu )
goto LABEL_28;
v24 = (void *)v61;
if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) < 0x1000 )
goto LABEL_27;
v24 = *(void **)(v61 - 8);
if ( (unsigned __int64)(v61 - (_QWORD)v24 - 8) <= 0x1F )
goto LABEL_27;
LABEL_75:
invalid_parameter_noinfo_noreturn();
}
if ( v42 <= 0xF )
goto LABEL_54;
v43 = v41;
if ( v42 + 1 >= 0x1000 )
{
v41 = (char *)*((_QWORD *)v41 - 1);
if ( (unsigned __int64)(v43 - v41 - 8) > 0x1F )
LABEL_66:
invalid_parameter_noinfo_noreturn();
}
j_j_free(v41);
LABEL_54:
v66 = 0;
v67 = 15;
LOBYTE(v65[0]) = 0;
v44 = (void *)*((_QWORD *)&v63 + 1);
if ( *((_QWORD *)&v63 + 1) )
{
if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
{
v44 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v44 - 8LL) > 0x1F )
goto LABEL_75;
}
j_j_free(v44);
*((_QWORD *)&v63 + 1) = 0;
v64 = 0;
}
if ( *((_QWORD *)&v62 + 1) > 0xFu )
{
v45 = (void *)v61;
if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) >= 0x1000 )
{
v45 = *(void **)(v61 - 8);
if ( (unsigned __int64)(v61 - (_QWORD)v45 - 8) > 0x1F )
goto LABEL_75;
}
j_j_free(v45);
}
v46 = sub_7FF72D611C40(std::cout, &unk_7FF72D6145E0, v15);
std::ostream::operator<<(v46, sub_7FF72D611E20);
v48 = sub_7FF72D611C40(std::cout, &unk_7FF72D614638, v47);
std::ostream::operator<<(v48, sub_7FF72D611E20);
v50 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v49);
std::ostream::operator<<(v50, sub_7FF72D611E20);
LABEL_29:
if ( v60 > 0xF )
{
v31 = Buf1[0];
if ( v60 + 1 >= 0x1000 )
{
v31 = (void *)*((_QWORD *)Buf1[0] - 1);
if ( (unsigned __int64)((char *)Buf1[0] - (char *)v31 - 8) > 0x1F )
invalid_parameter_noinfo_noreturn();
}
j_j_free(v31);
}
return v3;
}
main函数中,96行确定flag长度是25,137行有个迷惑项,但输入和base64字符串比较,显然无视就可以。
核心校验在195行和216行,216行是和目标字符串比对,查看函数sub_7FF72D6123D0
[C++] 纯文本查看 复制代码 // Hidden C++ exception states: #wind=1
_QWORD *__fastcall sub_7FF72D6123D0(__int64 *a1, _QWORD *a2, _QWORD *a3)
{
_QWORD *v3; // r9
unsigned __int64 v6; // r13
unsigned __int64 v7; // r12
unsigned __int64 v8; // r14
int v9; // r8d
unsigned __int8 *v10; // rcx
unsigned __int64 v11; // rdx
unsigned int v12; // r8d
char v13; // r9
char v14; // r10
char v15; // r11
unsigned __int64 v16; // r15
char v17; // r8
__int64 v18; // rsi
__int64 v19; // rbp
unsigned __int64 v20; // rsi
unsigned __int8 *v21; // rbp
unsigned __int64 v22; // rsi
__int64 v23; // r15
__int64 *v24; // rcx
char v25; // r9
__int64 v26; // r9
__int64 *v27; // rax
unsigned __int64 v28; // rdx
unsigned __int64 v29; // rcx
_QWORD *v30; // rax
unsigned __int64 v31; // rcx
unsigned __int64 v32; // rdx
_QWORD *v33; // rax
unsigned __int64 v34; // rcx
unsigned __int64 v35; // rdx
_QWORD *v36; // rax
_BYTE v38[4]; // [rsp+20h] [rbp-58h] BYREF
int v39; // [rsp+24h] [rbp-54h]
_QWORD *v40; // [rsp+28h] [rbp-50h]
_QWORD *v41; // [rsp+30h] [rbp-48h]
v3 = a3;
v40 = a3;
v41 = a2;
*(_OWORD *)a2 = 0;
a2[2] = 0;
a2[3] = 0;
a2[2] = 0;
a2[3] = 15;
*(_BYTE *)a2 = 0;
v39 = 1;
v6 = a3[1] - *a3;
v7 = 0;
if ( v6 )
{
while ( 1 )
{
v8 = 3;
if ( v6 - v7 < 3 )
v8 = v6 - v7;
v9 = 0;
if ( v8 )
{
v10 = (unsigned __int8 *)(v7 + *v3);
v11 = v8;
do
{
v9 = *v10++ | (v9 << 8);
--v11;
}
while ( v11 );
}
v12 = v9 << (8 * (3 - v8));
v13 = (v12 >> 12) & 0x3F;
v14 = (v12 >> 6) & 0x3F;
v15 = v12 & 0x3F;
v16 = a2[2];
v17 = (v12 >> 18) & 0x3F;
v18 = a1[6];
v19 = a1[5];
if ( v19 != v18 )
{
v20 = v18 - v19;
v17 = v16 ^ *(_BYTE *)(v16 % v20 + v19) ^ __ROR1__(v17, 7);
v13 = (v16 + 1) ^ *(_BYTE *)((v16 + 1) % v20 + v19) ^ __ROR1__(v13, 7);
v14 = (v16 + 2) ^ *(_BYTE *)((v16 + 2) % v20 + v19) ^ __ROR1__(v14, 7);
v15 = (v16 + 3) ^ *(_BYTE *)((v16 + 3) % v20 + v19) ^ __ROR1__(v15, 7);
}
v38[2] = v14;
v38[1] = v13;
v38[0] = v17;
v38[3] = v15;
v21 = v38;
v22 = 0;
v23 = 4;
do
{
if ( v22 > v8 )
{
if ( *((_BYTE *)a1 + 33) )
{
v26 = rand() % 64;
v27 = a1;
if ( (unsigned __int64)a1[3] > 0xF )
v27 = (__int64 *)*a1;
v25 = *((_BYTE *)v27 + v26);
}
else
{
v25 = *((_BYTE *)a1 + 32);
}
}
else
{
v24 = a1;
if ( (unsigned __int64)a1[3] > 0xF )
v24 = (__int64 *)*a1;
v25 = *((_BYTE *)v24 + *v21);
}
v28 = a2[3];
v29 = a2[2];
if ( v29 >= v28 )
{
sub_7FF72D611E60(a2);
}
else
{
a2[2] = v29 + 1;
v30 = a2;
if ( v28 > 0xF )
v30 = (_QWORD *)*a2;
*((_BYTE *)v30 + v29 + 1) = 0;
*((_BYTE *)v30 + v29) = v25;
}
++v22;
++v21;
--v23;
}
while ( v23 );
if ( !*((_BYTE *)a1 + 33) || v8 >= 3 )
goto LABEL_39;
if ( v8 == 1 )
break;
if ( v8 == 2 )
{
v34 = a2[2];
v35 = a2[3];
if ( v34 < v35 )
{
a2[2] = v34 + 1;
v36 = a2;
if ( v35 > 0xF )
v36 = (_QWORD *)*a2;
*(_WORD *)((char *)v36 + v34) = 64;
goto LABEL_39;
}
LABEL_38:
sub_7FF72D611E60(a2);
}
LABEL_39:
v7 += 3LL;
v3 = v40;
if ( v7 >= v6 )
return a2;
}
v31 = a2[2];
v32 = a2[3];
if ( v31 < v32 )
{
a2[2] = v31 + 1;
v33 = a2;
if ( v32 > 0xF )
v33 = (_QWORD *)*a2;
*(_WORD *)((char *)v33 + v31) = 33;
goto LABEL_39;
}
goto LABEL_38;
}
return a2;
}
明显是个base64编码,但码表不是默认的,而是通过第一个参数传入的,[@WP!3C75LfM8iwR2UO;(N>A6*&ut%#SIBhY1$j|kD{]0lx,.md9<4HayrzbXsg_
目标结果是*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==
写一个base64解码过程就可以。
[C] 纯文本查看 复制代码 unsigned char revchar(char ch)
{
for (int i = 0; i < 64; i++)
{
if (ch == charset[i])
return i;
}
return 0;
}
size_t base64_decode(const char in[], unsigned char out[], size_t len)
{
size_t idx, idx2, blks, blk_ceiling, left_over;
if (in[len - 1] == '=')
len--;
if (in[len - 1] == '=')
len--;
blks = len / 4;
left_over = len % 4;
if (out == nullptr) {
if (len >= 77 && in[NEWLINE_INVL] == '\n') // Verify that newlines where used.
len -= len / (NEWLINE_INVL + 1);
blks = len / 4;
left_over = len % 4;
idx = blks * 3;
if (left_over == 2)
idx++;
else if (left_over == 3)
idx += 2;
}
else {
blk_ceiling = blks * 4;
for (idx = 0, idx2 = 0; idx2 < blk_ceiling; idx += 3, idx2 += 4) {
if (in[idx2] == '\n')
idx2++;
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2);
out[idx + 2] = (revchar(in[idx2 + 2]) << 6) | revchar(in[idx2 + 3]);
}
if (left_over == 2) {
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
idx++;
}
else if (left_over == 3) {
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2);
idx += 2;
}
}
return(idx);
}
int main(int argc, char** argv) {
system("chcp 65001");
size_t decode_len = base64_decode("*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==", NULL, 37);
unsigned char* decode_buf = (unsigned char*)malloc(decode_len);
if (decode_buf)
{
base64_decode("*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==", decode_buf, 37);
printf("%s\n", decode_buf);
free(decode_buf);
}
system("pause");
return 0;
}
运行获得flag |
|