ScreenShot_2026-04-07_120354_786.png
直接放die
ScreenShot_2026-04-07_112523_786.png
32位,放ida看主要代码
ScreenShot_2026-04-07_113100_600.png
这里出意外了,反编译失败,难道说要我看汇编?不懂,问了ai
ScreenShot_2026-04-07_120529_249.png
感觉有道理,但是感觉有点麻烦,还是选择看题解
题解说的是直接定位到报错的地方,然后点进去单独反汇编,再出来main函数就可以直接反汇编了。
问ai得出来的原因:

在初始状态下,如果没有符号表,IDA 对子函数 sub_401020 的分析可能是不完全的,
或者猜测是错误的。由于反编译器无法确定这个 Call 执行完之后堆栈指针的状态(即堆栈不平衡),
为了防止生成完全错误的代码,它选择了直接报错终止。

当你退回到 sub_401090 再次按 F5 时,反编译器再次走到 call sub_401020。但这一次不同了,
它去查数据库时,发现 sub_401020 的函数原型已经非常明确。堆栈偏移计算正确了,
“Call 分析”自然就通过了,整个外部函数也就顺利反编译出来了。

ScreenShot_2026-04-07_114751_648.png
这样子就能看到主函数了,代码也比较简单,分析一手

if ( strlen(byte_4212C0) != 27 )
判断输入长度要是27

do
  {
    if ( ((unsigned __int8)v0 ^ (unsigned __int8)byte_4212C0[v0]) != byte_41EA08[v0] )
      goto LABEL_6;
    ++v0;
  }
while ( v0 < 0x1B );
每个输入的int和对应的下标异或,结果要和byte_41EA08相等

看看byte_41EA08
ScreenShot_2026-04-07_114929_546.png
这里手动输入数组的时候一定要小心QAQ,空格不要漏了,最后的0不是字符,还有十六进制表示的4Dh也是属于字符数组的数据

所以exp:

#include<iostream>
#include<string>

using namespace std;
int main()
{
    char ans[] = { 0x4D,'S','A','W','B','~','F','X','Z',':','J',':','`','t','Q','J','"','N','@',' ','b','p','d','d','}','8','g'};
    char* flag = new char[0x1B+1];
    flag[0x1B] = '\0';
    for (int i = 0; i < 0x1B; i++)
    {
        flag[i] = ans[i] ^ i;
    }
    cout << flag << endl;
    return 0;
}