赛后知道是smc(Self Modifying Code,动态代码加密技术),瞬间恍然大悟
打开文件到main函数后可以看到主要判断语句

smc自解密函数
void *__fastcall sub_140018420(__int64 a1, __int64 a2, __int64 a3) { char *v3; // rdi __int64 i; // rcx void *result; // rax char v6; // [rsp+0h] [rbp-20h] BYREF char v7[10]; // [rsp+30h] [rbp+10h] char v8[8]; // [rsp+3Ah] [rbp+1Ah] BYREF char v9[94]; // [rsp+42h] [rbp+22h] BYREF char v10[128]; // [rsp+A0h] [rbp+80h] char v11[104]; // [rsp+120h] [rbp+100h] void *lpAddress; // [rsp+188h] [rbp+168h] void *v13; // [rsp+1A8h] [rbp+188h] void *v14; // [rsp+1C8h] [rbp+1A8h] int j; // [rsp+1E4h] [rbp+1C4h] int k; // [rsp+204h] [rbp+1E4h] int m; // [rsp+224h] [rbp+204h] DWORD flOldProtect[101]; // [rsp+244h] [rbp+224h] BYREF v3 = &v6; for ( i = 250i64; i; --i ) { *(_DWORD *)v3 = -858993460; v3 += 4; } j___CheckForDebuggerJustMyCode(&unk_14002F034, a2, a3); v7[0] = 23; v7[1] = -36; v7[2] = -77; v7[3] = 31; ......... v11[70] = -91; lpAddress = malloc(0x4Aui64); v13 = malloc(0x57ui64); v14 = malloc(0x47ui64); j_memset(lpAddress, 0, 0x4Aui64); j_memset(v13, 0, 0x57ui64); j_memset(v14, 0, 0x47ui64); for ( j = 0; (unsigned __int64)j < 0x4A; ++j ) *((_BYTE *)lpAddress + j) = v7[j] ^ 0x5F; for ( k = 0; (unsigned __int64)k < 0x57; ++k ) *((_BYTE *)v13 + k) = v10[k] ^ 0x77; for ( m = 0; (unsigned __int64)m < 0x47; ++m ) *((_BYTE *)v14 + m) = v11[m] ^ 0x66; flOldProtect[0] = 0; VirtualProtect(lpAddress, 0x1000ui64, 0x40u, flOldProtect); VirtualProtect(v13, 0x1000ui64, 0x40u, flOldProtect); VirtualProtect(v14, 0x1000ui64, 0x40u, flOldProtect); qword_140029370 = (__int64 (__fastcall *)(_QWORD))lpAddress; qword_140029378 = (__int64 (__fastcall *)(_QWORD))v13; result = v14; qword_140029380 = (__int64 (__fastcall *)(_QWORD))v14; return result; }
使用IDA连接到local windows debugger进行动调

在核心判断处下断点,然后运行,随便输入一些字符


可以看到三个判断函数的地址

跳转到地址直接c转换成代码,再按p生成函数
得到三个函数
注意这里第一个函数的明文字符的顺序是反的(不确定的话在函数内下断点,然后打开本地变量窗口查看,打开方式Debugger => Debugger windows => Locals)


__int64 __fastcall sub_2C84FBD6CE0(__int64 a1) { if ( a1 == 'f_uoy_ho' ) return 0i64; else return -1i64; }
__int64 __fastcall sub_2C84FBD6F90(__int64 a1) { __int64 v1; // rcx __int64 v3[2]; // [rsp+0h] [rbp-40h] int v4[12]; // [rsp+10h] [rbp-30h] BYREF v3[0] = a1; qmemcpy(v4, "ound_our", 8); v1 = 0i64; while ( *((_BYTE *)v3 + v1) == *((_BYTE *)v4 + v1) ) { if ( ++v1 >= 8 ) return 0i64; } return -1i64; }
第三个函数的明文也是反的
__int64 __fastcall sub_2C84FBE0190(__int64 a1) { if ( a1 == 'ynn3x_' ) return 0i64; else return -1i64; }
可以判断为简单cmp,拼接得flag
oh_you_found_our_x3nny

大佬,问一下问什么我下载下来的文件不能直接调试呢?