本文以 SimpleCrackme.exe 为例,完整演示从零开始逆向一个 Windows Crackme 的全流程,包括手动 IDA Pro 分析路径,以及借助 IDA Pro MCP + Claude Code 的 AI 辅助分析路径。
程序基本信息
| 项目 | 内容 |
|---|---|
| 文件名 | SimpleCrackme.exe |
| 作者 | arasreal |
| 架构 | x86 32位 PE |
| 大小 | 0x9000 bytes |
| 保护手段 | IsDebuggerPresent 反调试 |
| 目标 | 找到正确密码,触发 Access Granted |
运行程序后的界面:

一、手动分析路径
1. 用字符串定位关键逻辑
打开 IDA Pro,加载 SimpleCrackme.exe,等待自动分析完成。
打开字符串窗口:
1 | View → Open subviews → Strings(快捷键 Shift+F12) |
搜索 password,找到两条关键字符串:
1 | 0x4042b8 "\n[+] Access Granted!" |

双击 Wrong password 那条,跳到 .rdata 段。再按 X 查看交叉引用(xref):

双击 xref 列表中的引用行(显示 sub_401220),跳转到主逻辑函数的汇编代码。

2. F5 反编译,查看伪 C 代码
光标在函数内,按 F5,Hex-Rays 生成伪 C 代码:

注意:必须在反汇编窗口(汇编代码区域)内按 F5,在 xref 列表或字符串窗口里按 F5 无效。
3. 发现反调试保护
函数开头看到:

程序调用 IsDebuggerPresent() 检测调试器。如果被检测到,直接输出警告并退出。
IsDebuggerPresent 原理:该 API 读取 PEB(进程环境块)中的 BeingDebugged 字段,调试器附加时该字段为 1。
4. 分析密码构造逻辑
回到 F5 伪代码,看到大量类似这样的调用:




1 | sub_4023D0(Src, "succ"); |
完整拼接链:
1 | "succ" + "ess" = "success" |
5. 查看比较逻辑
在 0x4018dc 附近看到汇编级的字节对比:

所以整个逻辑是:
1 | ① 比较长度 → 不等 → 直接判定失败 |
这是 C++ std::string 比较的典型编译产物,手写的 strcmp 也是同样的模式:先判长度,再逐字节,任何一步不等就提前退出。
6. 输入密码,验证结果
1 | successgoodtrybutyouarefoundatrypass01 |

二、AI 辅助分析路径(IDA Pro MCP + Claude Code)
技术架构
1 | ┌─────────────────┐ stdio/MCP ┌──────────────────┐ HTTP:13337 ┌─────────────┐ |
Claude Code 通过 MCP 协议直接调用 IDA 的反编译、交叉引用、字符串搜索等功能,无需人工一步步操作。
1. 确认连接状态
在 Claude Code 中询问,触发 server_health 工具调用:
1 | { |
2. 全局扫描(survey_binary)
AI 调用 survey_binary 获取整体结构:
- 116 个函数,138 个字符串,5 个段
- 发现关键字符串:
IsDebuggerPresent、Access Granted、Wrong password、DEBUGGER DETECTED! - 导入表中有
IsDebuggerPresent、Sleep、SetConsoleTitleA
一次调用即可掌握程序全貌。
3. 交叉引用定位主函数(xref_query)
AI 对关键字符串批量查 xref:
1 | "\n[+] Access Granted!" → sub_401220 (0x4018e5) |
四条 xref 全部指向同一个函数,主逻辑定位完毕。
4. 反编译主函数(decompile)
AI 调用 decompile(addr="0x401220"),获取完整伪 C 代码,直接分析密码拼接逻辑和比较逻辑,无需手动逐行看汇编。
5. 深入子函数(decompile 递归)
对 sub_402190 和 sub_402240 分别反编译,确认:
sub_402240=std::string operator+sub_402190=std::string::append+ move
6. 精确查看比较汇编(disasm)
反编译器在比较区域的输出不准确,AI 直接调用 disasm 查看原始汇编,还原出真实的字节比较逻辑和分支跳转。
手动 vs AI 效率对比
| 步骤 | 手动 | AI 辅助 |
|---|---|---|
| 找到主函数 | 字符串 → xref → 双击 → F5,需要几步操作 | 一次 xref_query 批量查询,秒定位 |
| 理解子函数 | 逐个 F5 进入,手动阅读 | decompile 直接输出,AI 同步解释 |
| 识别密码拼接 | 需要认出 std::string 操作模式 | AI 直接识别并还原完整拼接链 |
| 比较逻辑 | 需要读懂 setz / sbb 等指令 | AI 解释每条指令语义 |
| 总耗时 | 30分钟~数小时(取决于经验) | 数分钟 |
三、核心知识点总结
反调试(IsDebuggerPresent)
最常见的初级反调试手段,检测 PEB.BeingDebugged 字段。Bypass 方法:
- Patch
jz → jmp(本文方法) - 调试器插件隐藏(ScyllaHide)
- 静态分析绕过(不运行程序)
字符串拆分混淆
把密码拆成多个碎片,运行时在栈上拼接,对抗 strings 等静态提取工具。识别方法:在 IDA 伪代码中找连续的字符串构造调用链。
SSO(Short String Optimization)
MSVC 的 std::string 实现中,长度 ≤ 15 的字符串直接存在栈对象内部,不需要堆分配。反编译时会看到大量 > 0xF 的判断,这是 SSO 的边界检查,不是业务逻辑。
MCP 协议在逆向中的应用
MCP 将 IDA 的能力标准化为工具接口,让 AI 可以像调用函数一样调用 IDA API,实现真正的 AI 驱动逆向分析,而不只是 AI 读文本描述。
最终答案
1 | 密码:successgoodtrybutyouarefoundatrypass01 |