ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用Codex CLI打造二进制分析智能体:从聊天到自动验证

用Codex CLI打造二进制分析智能体:从聊天到自动验证 拿到一个陌生二进制文件你会先做什么很多人的第一反应是把文件丢给大模型问它“这是什么”。结果通常让人失望AI 的回答要么过于笼统要么自信地编造细节——它说里面有一个加密算法却给不出任何能验证的证据。真正的问题不在模型本身而是你只给了它一个对话框没给它操作文件的权限。在 ChatGPT 时代AI 是一个“参谋”你提问它回答中间没有任何动手能力。但二进制安全这门手艺真正的成本恰恰在动手提取字符串、看汇编、识别关键函数、写脚本验证算法、为某个函数构造测试程序。每一步单独看都不难难的是把这些步骤一遍一遍地跑完。于是有了这一轮被社区称为“破甲”的变化让 AI 从聊天窗口里走出来变成能读写文件、能执行命令、能编译程序的智能体。如果你使用过 Codex CLI 或类似的编程智能体你会有一种很不一样的感觉它不是停在对话框里等你喂问题而是直接在一个项目目录里工作自动规划、修改文件、运行命令、观察输出再根据结果调整。把它放进二进制安全场景“AI 逆向”就从一个噱头变成了可以实际落地的工作方式——包括让 AI 在分析完关键函数后自动生成一段可编译的测试程序用运行结果验证它对二进制的理解。本文用一个最小示例讲清楚这件事从零搭建一个用于二进制分析的 Codex 智能体环境让 AI 分析一个我们自己编译的目标程序最后让 AI 生成测试程序并验证行为。文章不会教你绕开任何商业软件授权也不会把 AI 包装成“一键破解工具”它只讨论在合法授权、自编译目标的前提下编程智能体如何改变二进制安全研究的日常开销。1. 破甲到底破了什么从“聊天”到“执行”的边界先解释一个容易被误解的词破甲。在编程社区的语境里“破甲”并不是破解软件授权也不是绕过安全限制而是打破模型只能聊天、不能动手的交互边界。你可以把它理解成一种比喻过去大模型穿了一层“只读铠甲”它只能看你的问题不能碰你的文件、命令和运行环境现在 Codex 这一类的编程智能体把这层铠甲卸掉了。这个边界差异比大多数人想象的更重要。我经常看到有人在一个对话框里贴一段反汇编代码问 GPT“这个函数是干什么的”。模型确实能给出一个大致判断但当你追问“你确定吗给我一个测试程序验证一下”时它就无能为力了——它没有编译器没有目标二进制没有任何确认条件的手段。它对那段代码的理解本质上只是基于训练数据做的模式匹配而不是基于实际执行结果的推理。Codex CLI 改变了这个闭环。它的工作方式更像是你派了一个实习生进到项目目录里它能读取你指定目录下的文件包括二进制文件、源码、配置文件它能调用系统命令比如objdump、strings、gcc、python3它能新建和修改代码文件它能运行测试程序读取输出再根据失败信息继续调整它能把每一步操作记录在项目文件里方便你事后审查。对逆向工程来说这意味着 AI 第一次能在“理解”和“验证”之间形成闭环。它说某个函数是一个校验函数不是凭记忆猜而是先看反汇编、再写一个调用它的 C 程序、编译运行、把结果拿回来对比。这才是“AI 逆向”真正值得关注的地方。如果只看表面很多人会把 Codex 误认为是又一个“代码补全工具”。实际区别在架构层代码补全工具只改变你写代码时的击键成本而编程智能体改变的是整个任务执行流程——它把“获取信息、写代码、跑命令、看错误、修复、再跑”这条循环自动化了。在二进制安全这个场景里这个循环正是日常工作的主体。2. 二进制安全逆向的核心工作流哪些环节适合交给 AI二进制安全逆向通俗讲就是对一个没有源码的程序进行“考古”通过文件结构、汇编指令、运行时行为还原出它的逻辑、协议或者漏洞。标准工作流可以拆成四步。第一步收集信息。用file查看文件格式用strings提取可打印字符串用readelf或objdump查看节区信息、符号表和反汇编代码。这一步解决的是“这个程序是什么、大概由什么组成”。第二步定位关键函数。一个大型二进制可能有几千个函数你不可能全部读完。常规做法是先找入口点main、导出函数、处理用户输入的函数、调用系统 API 的函数、带有特殊字符串引用的函数然后顺着调用关系缩小范围。第三步理解算法逻辑。这就是真正烧脑的部分。面对一段反汇编你要还原出它是在做字符串比较、字节变换、状态机转移还是某个加密算法的轮函数。这里最需要经验也是新手最容易卡住的地方。第四步验证假设。逆向分析里有一句话没跑过就不算懂。你推测某个函数是校验函数就写一个小程序调用它输入预期的密钥看返回值是否符合推断。验证通过推断才成立。这四步里AI 最适合做的不是第三步的“深度理解”反而是第一步的信息收集、第二步的初步定位以及第四步的测试程序生成。原因很直接这三步是重复劳动规则明确结果可验证而第三步需要结合大量上下文和实战经验模型可以给出候选解释但必须靠第四步验证兜底。AI 逆向的真正价值不是替代逆向工程师而是把工程师从机械劳动中解放出来把精力集中到最需要判断力的环节。从模型能力角度看Codex 适合二进制分析场景还有一个关键原因它本身是为“长时间多步骤任务”设计的。它不会因为你让它运行两次命令就丢失上下文它会维护一份任务计划逐步执行遇到错误会尝试修复而不是每次都从头开始。这个特性恰恰符合逆向工程的真实工作方式。下面的表格是 AI 在各环节的适配度参考工作环节典型操作AI 适配度说明信息收集file / strings / readelf高规则固定AI 可批量执行并整理结果定位函数查找引用、梳理调用链中高小规模二进制表现好大型程序需人工约束范围理解算法分析反汇编、还原逻辑中能给出候选假设可能幻觉必须验证验证假设编写测试程序并运行高代码生成是 AI 强项验证结果客观明确3. 环境准备Codex CLI 加经典分析工具链在开始实战之前先把环境搭起来。本节会介绍一套最小可用的工具链覆盖代码生成、二进制分析和编译验证三个能力。版本信息请以实际安装时的官方说明为准不要死记某个版本号。3.1 工具清单工具作用安装方式Codex CLI编程智能体主程序负责理解任务、修改文件、执行命令npm 或 官方安装脚本Python 3运行 AI 生成的脚本处理二进制数据系统自带或包管理器GNU Binutils提供 file / objdump / readelf / strings / nmapt / yum / brewgcc / clang编译目标程序和 AI 生成的测试程序系统自带或包管理器git记录 AI 对项目文件的修改方便回滚系统自带或包管理器3.2 安装 Codex CLICodex CLI 在 macOS 和 Linux 上支持较好Windows 用户建议在 WSL 中运行因为后续要用到 GNU 工具链原生 Windows 环境的体验会差很多。典型安装命令如下# 使用 npm 全局安装 npm install -g openai/codex # 检查版本 codex --version如果还未登录 OpenAI 账号运行下面的命令完成认证codex login认证过程会打开浏览器获取访问令牌。如果你所在的环境无法直接访问对应模型服务请根据你所在地区和企业合规策略选择合法的模型端点不要使用来历不明的代理服务。Codex CLI 本身只是一个命令行工具安装没有地域限制API 调用的可用性和计费问题要以你实际使用的模型服务商为准。3.3 配置模型端点Codex CLI 的配置文件通常位于~/.codex/config.toml。默认情况下它使用 OpenAI 官方模型端点。一个最简配置如下# 文件路径~/.codex/config.toml model gpt-5-codex model_provider openai如果使用的是企业内部或自行部署的合规模型服务需要在配置中指定 provider 和 base URL。具体字段名称以当前版本 CLI 的--help输出或官方 README 为准。不要盲目复制网上的配置片段尤其是来源不明、声称能“解锁模型限制”的配置这类配置往往是安全风险的来源。3.4 准备二进制分析工具二进制分析工具是逆向工程的基础建议提前确认它们存在file --version objdump --version | head -n 1 readelf --version strings --version nm --version gcc --version python3 --version如果缺少某个工具在 Debian/Ubuntu 系系统中可以用以下命令安装sudo apt update sudo apt install binutils build-essential python3macOS 用户可以使用 Homebrewbrew install binutils gcc python3完成这一步后你的环境就具备了让 AI“看到二进制、分析二进制、编译测试程序”的完整能力。4. 搭建“二进制分析智能体”的最小架构有了工具链下一步不是直接把二进制扔给 Codex而是先想清楚项目目录怎么组织。编程智能体的能力是“作用于文件系统”的你的目录结构就是它的工作台。一个清晰的目录结构能显著提升 AI 任务执行的准确性和可审查性。4.1 推荐目录结构这里以分析一个名为demo_vault的 ELF 文件为例ai-reversing-lab/ ├── AGENTS.md # 给 AI 看的项目说明与工作约定 ├── target/ # 放置待分析的二进制文件 │ └── demo_vault ├── analysis/ # 存放 AI 生成的分析脚本和报告 ├── tests/ # 存放 AI 生成的测试程序 └── output/ # 存放运行结果和日志AGENTS.md是一个关键文件。Codex 这类编程智能体会自动读取它把它当作项目内的工作指南。你可以在里面写明任务边界只能分析target/下的文件不要修改target/里的原文件工作约定分析脚本放到analysis/测试程序放到tests/输出文件放到output/验证要求每次生成测试程序后必须编译并运行返回结果写入output/。4.2 AGENTS.md 示例# 项目工作约定 ## 目标目录 - target/ 目录存放待分析二进制只读禁止修改。 ## 输出目录 - 分析脚本写入 analysis/ - 测试程序写入 tests/ - 运行结果写入 output/ ## 分析流程 1. 先使用 file、readelf、strings 收集基本信息 2. 再使用 nm / objdump 定位关键函数 3. 对关键函数生成测试程序 4. 编译测试程序并运行 5. 将运行结果保存到 output/并给出结论。为什么要写这些因为编程智能体默认会尽量自主行动如果不设定边界它有可能直接修改target/下的原文件或者在项目根目录散落一堆临时脚本。给一份简洁的 AGENTS.md相当于给 AI 立了工作规矩也让你的审查变得容易。4.3 任务描述模板Codex 不是靠一句“分析这个二进制”就能自动完成全部工作的。它需要你给出结构化任务描述。一个适合二进制分析场景的模板如下请按以下步骤分析 target/demo_vault 文件 1. 使用 file 和 readelf 确认文件类型、架构、是否带符号表 2. 使用 strings 提取可打印字符串整理到 analysis/strings_report.txt 3. 使用 nm 或 objdump 查找导出函数和 main 函数 4. 重点分析 main 函数调用的关键函数给出反汇编摘要 5. 针对关键函数编写测试程序编写到 tests/verify_demo_vault.c 6. 编译测试程序并运行 7. 将运行结果和你的结论写入 output/final_report.md。这个模板的关键在于每一步都有明确产出。不是让 AI 空泛地“分析”而是让它把每个阶段的结果落到文件里。这样你事后可以逐文件审查AI 也不会在某个环节卡住时毫无产出。5. 完整示例让 AI 分析目标二进制并自动生成测试程序下面进入实战。为保证演示安全可控我们使用一个自己编译的目标程序。这个程序包含典型的逆向分析要素硬编码校验、位运算变换、导出函数。5.1 编写目标程序// 文件路径target/demo_vault.c #include stdio.h #include string.h static int secret_transform(int v) { return ((v ^ 0x5A) 0x2B) 0xFF; } static int check_key(const char *key) { if (strlen(key) 4) { return 0; } unsigned char expected[5] {0x46, 0x63, 0x94, 0xA6, 0x00}; for (int i 0; i 4; i) { int c (unsigned char)key[i]; if (secret_transform(c) ! expected[i]) { return 0; } } return 1; } int verify_license(const char *key) { return check_key(key); } int main(int argc, char *argv[]) { if (argc 2) { fprintf(stderr, usage: %s key\n, argv[0]); return 1; } if (verify_license(argv[1])) { printf(Access granted.\n); return 0; } else { printf(Access denied.\n); return 1; } }编译成目标文件cd ai-reversing-lab gcc -o target/demo_vault target/demo_vault.c验证一下它能正常运行./target/demo_vault Ab3!输出为Access granted.这样我们就有了一个“待分析”的目标二进制。它本身没有恶意代码非常适合做智能体逆向实验。5.2 先用基础命令人工摸底在把任务交给 AI 之前建议先手动跑一遍基础命令对目标有一个大致印象。这也是排查后续问题的最佳起点。file target/demo_vault strings target/demo_vault | head -n 20 nm target/demo_vault | grep -E verify_license|main从输出中你会看到文件类型ELF 64-bit 可执行文件字符串包含Access granted.、Access denied.、usage: %s key符号表verify_license是导出的main存在。这说明目标程序没有去除符号表属于逆向入门难度的样本。如果 AI 后续给出的分析结果和你看到的符号矛盾你可以立刻发现问题。5.3 把分析任务交给 Codex在项目根目录运行codex然后输入前面的任务描述例如请分析 target/demo_vault。先做信息收集再定位关键校验函数最后编写一个测试程序验证该校验函数的行为。测试程序写到 tests/ 目录分析报告写到 output/ 目录。Codex 会按照AGENTS.md中的约定先读取文件结构再逐步执行命令。你不需要在每一步都干预但应该在旁边观察它执行了什么命令、修改了什么文件、有没有偏离任务边界。5.4 AI 生成的分析脚本示例在类似任务中智能体通常会在analysis/目录下生成一个信息收集脚本。它的职责是自动执行file、strings、nm、objdump等命令并把结果汇总成一份报告。下面给出一个参考形态#!/usr/bin/env python3 # 文件路径analysis/generate_report.py import subprocess import sys from pathlib import Path TARGET Path(target/demo_vault) OUTPUT Path(output) OUTPUT.mkdir(exist_okTrue) def run(cmd): print([*] running:, .join(cmd)) r subprocess.run(cmd, capture_outputTrue, textTrue) if r.returncode ! 0: print([!] command failed:, .join(cmd), filesys.stderr) print(r.stderr, filesys.stderr) return r.stdout def main(): if not TARGET.exists(): print(f[!] target not found: {TARGET}, filesys.stderr) sys.exit(1) report [] report.append( file ) report.append(run([file, str(TARGET)])) report.append( strings ) report.append(run([strings, -n, 4, str(TARGET)])) report.append( symbols ) report.append(run([nm, str(TARGET)])) report.append( main disassembly ) report.append(run([objdump, -d, --disassemblemain, str(TARGET)])) (OUTPUT / analysis_report.txt).write_text(\n.join(report), encodingutf-8) print([] report written to output/analysis_report.txt) if __name__ __main__: main()运行方式python3 analysis/generate_report.py这个脚本的每一部分都对应人工逆向中的标准操作。它的价值不在于算法复杂而在于把散乱的命令统一成可复现的报告。AI 在代码生成任务上非常擅长做这类“脚本组装”工作这也是它能在二进制安全场景中提高效率的原因之一。5.5 AI 生成的测试程序示例重点来了。Codex 在分析完verify_license后会自动生成一个测试程序来验证它的行为。参考实现如下// 文件路径tests/verify_demo_vault.c #include stdio.h #include string.h extern int verify_license(const char *key); int main(void) { const char *test_keys[] { Ab3!, wrong, , AAAA, Ab3! }; int expected[] { 1, 0, 0, 0, 1 }; int failed 0; for (unsigned long i 0; i sizeof(test_keys) / sizeof(test_keys[0]); i) { int result verify_license(test_keys[i]); printf(key%-8s - result%d (expected %d)\n, test_keys[i], result, expected[i]); if (result ! expected[i]) { printf([!] test %lu failed\n, i); failed; } } printf(%s\n, failed ? SOME TESTS FAILED : ALL TESTS PASSED); return failed ? 1 : 0; }编译并运行gcc -o tests/verify_demo_vault tests/verify_demo_vault.c target/demo_vault.c ./tests/verify_demo_vault预期输出keyAb3! - result1 (expected 1) keywrong - result0 (expected 0) key - result0 (expected 0) keyAAAA - result0 (expected 0) keyAb3! - result1 (expected 1) ALL TESTS PASSED为什么让 AI 生成测试程序这一步这么重要因为它是整个智能体闭环里最接近“证明自己”的环节。AI 如果说verify_license是一个校验函数它必须通过实际调用来证明这个判断。测试程序只要编译不过或者运行结果和预期不符它的分析就是不可信的。实际上一个可靠的编程智能体会自动完成“分析 → 写代码 → 编译 → 运行 → 根据失败信息修复 → 再运行”的循环。你在这次实验里观察到的正是这个循环在二进制安全领域的应用。6. 运行结果与效果验证智能体任务结束后不要只看它最后一句“分析完成”。你需要主动验证结果。6.1 验证输出文件清单一个规范任务结束时项目目录中至少应该出现文件内容验证标准output/analysis_report.txt文件格式、字符串、符号、反汇编摘要信息与手动执行命令的结果一致tests/verify_demo_vault.c对关键函数的调用测试能正常编译无未声明标识符output/final_report.mdAI 对该二进制的结论结论与反汇编和运行结果一致6.2 验证思路最直接的验证方式是抽查 AI 报告中的关键断言。比如它说“verify_license内部存在一个对secret_transform的调用”你就手动用objdump -d --disassembleverify_license看看汇编里是否有对应的异或指令和加法指令。它说“正确密钥是Ab3!”你就直接运行./target/demo_vault Ab3! ./target/demo_vault wrong第一个输出Access granted.第二个输出Access denied.它的结论才成立。这种验证方式本质上是用动态分析去校验静态分析的结论。无论 AI 说得多么自信最终都需要在真实进程里得到确认。6.3 如果测试程序编译失败如果gcc报错通常有以下几个原因verify_license符号没有声明检查目标程序是否用了static修饰导出函数或者编译命令是否把target/demo_vault.c加进来了依赖头文件缺失测试程序用到了stdio.h、string.h确认它们存在链接顺序问题把target/demo_vault.c放在测试程序后面避免undefined reference。如果 AI 生成的代码编译失败你可以直接把这些失败信息粘贴给 Codex让它继续修复。这也正是“多步骤自主容错”的价值AI 不会因为一次失败就放弃任务而是会把失败当作输入继续调整代码。7. 常见问题与排查思路下面整理一套 Codex CLI 在二进制分析场景中经常遇到的问题和排查方法。这些内容不完全局限于逆向任务很多是编程智能体工具的通病。问题现象可能原因排查方式解决方案codex命令找不到npm 全局 bin 目录不在 PATH 中运行npm prefix -g查看全局路径把对应的 bin 目录追加到 PATH或重新安装提示codex cannot load organization settings登录账号无组织信息或权限不足运行codex login确认账号状态检查账号权限个人用户可忽略组织相关配置出现cc switch local proxy failed while handling codex endpoint /responses本地网络代理配置与 Codex 端点通信失败检查代理环境变量、本地代理服务和模型端点地址统一代理配置确保模型端点地址可访问不要使用来源不明的代理服务API 请求返回 401缺少凭据或凭据过期运行codex login重新认证更新 API Key 或重新登录API 请求返回 429请求频率超限或账户额度不足查看模型服务商控制台降低任务并发度等待限流窗口恢复后重试AI 生成的代码编译报错对目标函数理解错误或遗漏头文件把编译错误信息反馈给 Codex让 AI 继续修复或人工修正原型声明nm找不到目标符号目标二进制被 strip 过运行file确认是否有符号表改用objdump -t查动态符号或从字符串引用定位VMware 挂载分析镜像时报vmware-mount 不支持 GPT 分区工具/宿主环境不支持当前分区表格式确认镜像文件和分区表类型用支持 GPT 的专用工具挂载分析镜像或在线分析副本中处理排查问题时有一个基本原则先看原始输出再问 AI。很多开发者遇到错误后的第一反应是把问题丢给模型但更高效的做法是先用file、nm、objdump等基础工具收集背景信息再在大模型里给出上下文。盲目追问只会得到盲目的答案。8. 安全边界与最佳实践编程智能体给逆向工作带来效率提升的同时也引入了新的工程风险。以下是几个必须养成的习惯。8.1 永远在隔离环境运行未知代码AI 生成的脚本和测试程序本质上是不可信代码。它可能因为理解偏差调用危险 API或者在你操作的文件目录之外产生副作用。建议使用 Docker 容器、虚拟机或至少是独立工作目录来运行实验。即使目标程序是自编译的“玩具程序”也要养成隔离运行的习惯——因为你无法确定 AI 在迭代过程中会生成什么样的中间代码。# 示例使用 Docker 创建隔离实验环境 docker run --rm -it -v $PWD:/workspace -w /workspace ubuntu:22.04 bash在容器内安装基础工具后再进行 Codex 分析。这样可以最大程度避免 AI 的操作影响宿主机。8.2 用 git 记录每一次 AI 修改在实验开始前初始化仓库git init git add AGENTS.md target/ git commit -m init: project structure and target binary每次让 AI 执行完一个任务后都查看 diffgit status git diff如果发现 AI 修改了不该修改的文件直接回滚git checkout -- target/这个习惯尤其重要因为编程智能体在多次迭代中可能产生大量临时文件没有 git 的话你很难追踪哪些变更来自 AI、哪些来自你自己。8.3 任务拆分要足够小很多人第一次用 Codex 分析二进制时会输入一段很长的描述期望它一口气完成所有工作。结果往往不理想因为任务描述越宏大智能体的自主决策空间就越大出错概率也越高。推荐的做法是把任务拆成三轮第一轮只做信息收集产出analysis_report.txt第二轮定位关键函数给出反汇编摘要和调用关系第三轮针对确认过的函数生成测试程序编译运行并输出结论。每轮结束都检查产出再进入下一轮。这个流程人工逆向是这样让 AI 逆向也应该这样。8.4 合规与授权边界这是最重要的一点必须反复强调。本文演示的是自编译目标程序读者做二进制安全研究时应确保分析对象来源合法、有明确授权编程智能体可以用来分析自己开发、CTF 比赛、企业内部授权的软件也可以用于漏洞研究但不应当被用来绕开商业软件授权机制“破甲”在本文语境中指的是打破对话式 AI 的交互边界而不是绕过任何产品的安全授权。安全问题不是 AI 带来的新问题而是逆向工程本身固有的边界问题。工具只是放大了研究者的生产力并没有改变研究行为合规与否的判断标准。8.5 正确性验证的三个层次当 AI 给出结论时建议按三个层次验证层次方法可靠性静态验证用 objdump / readelf 对照 AI 的结论中等能证明 AI 没有编造符号动态验证运行测试程序看返回值是否符合预期高直接证明行为正确交叉验证用不同的工具如 Ghidra、radare2复核 AI 的汇编摘要最高能发现单一工具偏差只要有可能尽量做到第三层。AI 可能因为工具输出格式差异产生误判但多个独立工具交叉验证后结论的可信度会显著提升。9. 总结AI 逆向能做什么、不能做什么这篇文章写到这里你应该已经看到了一条清晰的分界线。AI 逆向能做的自动执行信息收集命令并整理成报告节省大量机械劳动从反汇编中快速定位关键函数生成可读的汇编摘要为关键函数生成可编译的测试程序动态验证模型对二进制的理解在一次任务中完成“分析 → 编码 → 编译 → 运行 → 修复”的完整循环这是传统 AI 聊天工具做不到的。AI 逆向目前还做不到的替代有经验的安全研究员做最终判断。复杂混淆、加壳、反调试逻辑仍然需要人工介入自动保证合规。分析对象是否授权、研究是否越界这个责任永远在操作者手里处理超出任务描述边界的模糊请求。如果你自己都不知道想让 AI 做什么它给出的结果大概率也是混乱的。如果你现在还没试过让 AI 自动分析二进制建议先不要碰任何别人给你的样本。自己写一个十几行的 C 程序编译出来让 Codex 去分析再让它生成测试程序。跑通这个最小闭环之后你自然会理解为什么调试提示词、约束沙箱、检查 AI 修改记录这些“工程习惯”比模型本身更重要。编程智能体不会终结二进制安全这个领域但它一定会改变这个领域里“重复劳动”的定义。把机械的部分交给 AI把判断力留给自己——这可能是这一轮工具变革给我们最实际的一条经验。
返回列表