[Reverse] Catch

Fake 加密 + 真实 Rot13 套路题

Reverse / IDA / Fake加密 / Rot13 难度:简单

0x00 题目描述

双击 exe 秒闪,属于标准套路逆向。

0x01 IDA 打开看 main

main 函数非常干净,直接调用 solve:

int __fastcall main(int argc, const char **argv, const char **envp)
{
  _main(argc, argv, envp);
  solve();
  return 0;
}

0x02 进入 solve 函数

程序打印一句话后直接抛异常崩溃:

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

0x03 进入 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;
}

0x04 加密数据 & 加密函数

数据段拿到密文:

geoi~lq~bcyUcyUkUlkaoUlfkmw

enc 函数:异或 0x11

__int64 __fastcall enc(char a1)
{
  return (unsigned int)(a1 ^ 0x11);
}

0x05 坑点:IDA 编译错误 + Fake 加密

题目提示:

IDA pro 9.0 推出了针对 C++ exception 的优化
但是这并不意味着所有的 try catch 都能被正确反编译

直接异或解密会出乱码,因为这是Fake 加密

0x06 正确思路:字符串查找 Rot13

字符串窗口发现疑似 flag 格式:

zbrpgs{F4z3_Ge1px_jvgu_@sybjre_qrfhjn}

直接丢解码工具:

Rot13 → moectf{S4m3_Tr1ck_with_@flower_desuwa}

0x07 Flag

moectf{S4m3_Tr1ck_with_@flower_desuwa}