双击 exe 秒闪,属于标准套路逆向。
main 函数非常干净,直接调用 solve:
int __fastcall main(int argc, const char **argv, const char **envp)
{
_main(argc, argv, envp);
solve();
return 0;
}
程序打印一句话后直接抛异常崩溃:
void __fastcall __noreturn solve()
{
std::logic_error *exception; // rbx
printf("my flag is hidden in this program. Can you find it?\n");
sub_114514();
exception = (std::logic_error *)_cxa_allocate_exception(0x10u);
std::logic_error::logic_error(exception, "nothing but error");
_cxa_throw(exception, (struct type_info *)&`typeinfo for'std::logic_error, refptr__ZNSt11logic_errorD1Ev);
}
核心逻辑在 sub_114514。
对 _data_start__ 进行逐字节加密:
__int64 __fastcall sub_114514()
{
__int64 result; // rax
int v1; // [rsp+28h] [rbp-8h]
unsigned int i; // [rsp+2Ch] [rbp-4h]
printf("try to catch me\n");
v1 = strlen(_data_start__);
for ( i = 0; ; ++i )
{
result = i;
if ( (int)i >= v1 )
break;
_data_start__[i] = enc(_data_start__[i]);
}
return result;
}
数据段拿到密文:
geoi~lq~bcyUcyUkUlkaoUlfkmw
enc 函数:异或 0x11
__int64 __fastcall enc(char a1)
{
return (unsigned int)(a1 ^ 0x11);
}
题目提示:
IDA pro 9.0 推出了针对 C++ exception 的优化 但是这并不意味着所有的 try catch 都能被正确反编译
直接异或解密会出乱码,因为这是Fake 加密!
字符串窗口发现疑似 flag 格式:
zbrpgs{F4z3_Ge1px_jvgu_@sybjre_qrfhjn}
直接丢解码工具:
Rot13 → moectf{S4m3_Tr1ck_with_@flower_desuwa}
moectf{S4m3_Tr1ck_with_@flower_desuwa}