打破传统AI逆向的新思路 多Agent、自主管理上下文 - 逆向思路

发布时间:2026/7/18 1:09:41
打破传统AI逆向的新思路 多Agent、自主管理上下文 - 逆向思路 前言本人使用AI逆向和AI开发已经两年时间目前是在做Agent开发从纯粹网页时代的GPT辅助逆向到Claude3.5到后面的AI爆发时代的GLM5.1Claude4.7等等。看到很多人用ai逆向的思路和手法还是过于局限和原始纯粹的流式对话。想分享一些新思路。作者本身是做算法逆向还原所以文章就以我自己的方向为主进行抛砖引玉。如何高效的逆向。本文章零AI注水请放心食用除开绘图使用了AIAI逆向过程中难点在AI逆向中结合经验我认为存在一下几个问题传统的以古法为主导Ai辅助的一种工作模式。会导致工作效率不高大量的工作都是古法进行的。比如前期的定位前期的勘探等等。希望的是AI为主导人只做决策。这样可以同时进行多个任务。上下文管理太弱。AI逆向经常会出现一个问题就是人再通过N轮对话后发现定位或者已经拿到了我们想要东西的核心算法点位风控协议的点位等等。但是在链路上可能会存在一些相关联的信息才能吧整个工作完成。或者一个对话不够的情况下会有N次压缩。然后发现信息丢失需要再次回头去看这些辅助信息这样也很低效。AI逆向是发散太强。当我们给了一个指令后AI通过思维链工具调用后可能已经偏离了正确的轨道。逆向很多时候会有N个的路径需要去看去逆向分析。AI走了一条错误的路径后我们总是要打断纠正往往大量的时间还是浪费在叮他的思维链中了并没有真正的解放出来。并且打断后很有可能由于上下文的问题导致这些分析路径都丢失了中途如果出现意外情况在启动一个窗口几乎是从头再来。Ai逆向不知道正确的逆向手法虽然认识汇编但是不懂汇编如何转高级代码。很有可能用了一个低效的方法再去逆向分析。并且逆向过程中极其依赖IDA F5极易产生错误。尤其是在精度极高的算法还原下很有可能就是0.2%的精度问题导致无法完成任务。这个问题国产模型最为严重。猜测还是训练集对这类太少了。虽然claude 4.7有改善。爆上下文问题。AI在读取较大函数或者是汇编的时候会产生上下文爆掉的情况虽然有No mcp这种工具但是由于AI的自身的问题没法关注1w行汇编。claude的注意力机制一般都是前和最后。如何解决这几个问题也是苦恼我很久了。结合总结了一套方法构建一套上下文管理机制任何Ai的产出必须要规范管理。必须要有明确的方向以及要避免模糊的提示词输入。在基模比较好的情况下可以让Ai拆解用户进行多轮自主的信息了解从制定方案进行分析定位。多Agent隔离。好处是隔离上下文防止爆掉。避免汇编污染AI的决策。同时可以使用多个模型的进行操作类似Git上很火的ohmycode这种项目。半自动化的决策必须要有HOOK来打断ai的在特定情况下需要让人工进行决策不然完全野蛮的发散。框架设计基于上面思考我设计了一套逆向RE的工程框架只要参与大型的逆向工程我会使用我这套框架来进行。设计图如下设计了一套多Agent的框架由主脑来进行决策还任务的派发。主Agent直接与用户进行交互拆解用户的语义分析并且指挥下面的小弟干活。并且吧上下文管理逆向分析审查。拆分成几个Agent完成如果说后续任务复杂度增加已经继续增加我们的子agent继续拆分细化任务。上下文管理设计我吧Ai产物分成两个部分AI分析过程中的还原信息如类信息成员信息函数信息函数的高精度反汇编结构体等等。.artifactsAI分析过程中的逆向路径思维链都进行存储。防止二次返工。.investigations用图解释一下有考虑用sqllite或者rag的那种向量数据库管理但是笔者认为这些方式都太重而且存在大量的工具调用sql生成。对于逆向来说不是很好原因是浪费token并且如果在国产模型上做这么多复杂会不会出现漂移问题这里需要打个问号了。具体设计是这样的lt;projectgt;/ ├── CLAUDE.md ← init 从模板拷贝项目自包含 ├── .mcp.json ← 项目级 MCP 注册IDA / frida / dbg-* ├── README.md │ ├── .artifacts/ ═══ AI 产物 ═══ │ ├── index.yaml 主索引地址 → 路径 │ ├── lt;binarygt;/ 每个目标 binary 一个目录 │ │ ├── classes/ │ │ │ └── lt;Classgt;/ │ │ │ ├── class.yaml 类元数据 │ │ │ └── methods/ │ │ │ ├── speak.yaml 主文件 当前活跃 │ │ │ ├── speak.v1.yaml 历史版本 │ │ │ └── speak.b1.yaml fan-out 分支 │ │ └── functions/ │ │ └── 0x140xxxxx.yaml 未归类函数 │ └── cross_refs/ │ ├── index.yaml 跨引用内部索引 │ └── xref_001.yaml 单条跨引用 │ └── .investigations/ ═══ AI 思考过程 ═══ ├── 000-定位-lt;binarygt;/ Phase 1 产出 │ ├── 任务.md │ ├── 发现*.md │ └── 待挖清单.md └── 001-任务名/ Phase 2 任务 ├── 任务.md 任务简报Phase 0 写 ├── 假设A-*.md 多假设并行 ├── 假设B-*.md └── 结论.md 结案后写并且设计了如下几种文件格式用来存储我们的逆向中的信息schema_version: 1 # 1) 项目里有哪些目标 binary binaries: - name: foo.dll sha256: 8f3a2b1c00000000000000000000000000000000000000000000000000000000 arch: x64 - name: bar.exe sha256: a12b3c4d00000000000000000000000000000000000000000000000000000000 arch: x64 # 2) 每个分析过的地址当前文件在哪核心 addresses: foo.dll:0x1400077c0: path: foo.dll/classes/Animal/methods/speak.yaml kind: method # method | function foo.dll:0x140007740: path: foo.dll/classes/Animal/methods/get_age.yaml kind: method foo.dll:0x140007550: path: foo.dll/functions/0x140007550.yaml kind: function # 还没归类 bar.exe:0x140003200: path: bar.exe/functions/0x140003200.yaml kind: function # 3) 已识别的类轻量列表 classes: - id: foo.dll:Animal path: foo.dll/classes/Animal/ - id: foo.dll:Dog path: foo.dll/classes/Dog/由一个树形结构一个主索引我们的具体的逆向信息。一共有四类产物class类文件方法文件 未归类函数或者说是面向过程中用到的。类文件格式字段含义类名RTTI 真名优先无 RTTI 用Class_140xxxx临时名状态status 值见第五节版本时间线版本号大小sizeof(类) 字节数vtable虚表地址 槽位数无虚函数则 null父类直接继承的基类列表无继承则 []字段成员变量列表偏移、类型、名字、初值、证据方法清单方法名引用列表详情在methods/lt;namegt;.yaml方法文件格式字段含义类所属类名方法名speak/Animal/~Animal地址函数地址十六进制字符串状态status 值版本时间线版本号签名推断出的 C 签名证据判别依据列表C 源码反编译出的 C 代码多行字符串未归类函数字段含义地址函数地址状态status 值一般是 draft 或 candidate版本时间线版本号签名推断出的签名不确定时填???证据判别依据列表C 源码反编译出的 C 代码status 状态机这里介绍一下status 值这个实际上就是我们的逆向的置信度在AI逆向中任何ai逆向的产出都是不可靠的都是存在置信度的如果一旦100%信任你肯定会出大问题。所以我们需要给每个结果打上一个置信度当有足够证据多维度验证后才能是可信的。否则agent在阅读这些信息的都是有一定的怀疑态度去对待。这个状态的更改是由审查agent负责 半人工的方式完成的。(这一步主要是解决幻觉问题)所以设计了如下几个状态状态含义谁能写draftAI 单线程初稿未经验证workerwip正在分析中尚未完成workercandidatefan-out 候选 / judge 选中待审worker / judge 选confirmed已经过用户拍板的最终结论仅用户rejected经验证或拍板被驳回judge / 审查 / 用户superseded被新版本取代历史归档常用librarian / agent 升级新版本时常见的流程是这样的[worker / fan-out 产出] 状态: candidate ↓ [审查 agent 独立审查] 读candidate yaml 关联 .investigations/ 推理 出同意 / 不同意 / 需补证据 ↓ [主 agent 转给用户] 附带审查意见 ↓ [用户拍板] confirmed / rejected / 保持 candidate要求补证据再审最后给我们的不同的agent上不同的权限但是confirmed一定要有人来审查也就是意味着这个点完全没有问题。- worker 自己产出的最高只能是 draft 或 candidate - judge 评判 fan-out 后只出意见不直接改 status - 审查 agent** 只输出审查意见不直接改 status - confirmed 必须由用户亲自拍板 —— AI 永远写不到这一档跨文件关联分析在上面设计的情况下我们是一个单一的一对一管理。但是我们知道逆向一般都是多个so或者dll进行的互相引入的所以这种引入如何解决用一个cross_refs文件来管理跨dll之间的关系表达格式如下字段含义编号形如xref_001状态status 值版本时间线版本号从引用发起方binary 地址到引用目标binary 类 方法 地址关系类型调用 / 引用虚表 / 引用数据 / 字符串引用 / 继承证据判别依据举例一下编号: xref_001 状态: confirmed 版本: 1 从: binary: bar.exe 地址: 0x140003200 到: binary: foo.dll 目标类型: 方法 类: Animal 方法名: speak 地址: 0x1400077c0 关系类型: 调用 证据: 间接调用 [rcx8]rcx 在 0x14000312A 处加载 Animal::vftable??_7Animal6B版本管理由于我们不可能一轮对话就可以吧一个任务完成所以这里存在一个版本迭代问题。当我们逆向的第一版是这样的 但是由于各种问题导致我们推翻了我们之前的分析过程和逆向过程。但是不确定第二个方向是对的情况下就需要对版本进行管理。格式如下命名含义何时产生lt;namegt;.yaml当前活跃版本主文件索引指向这个总是存在lt;namegt;.v1.yamllt;namegt;.v2.yamllt;namegt;.vN.yaml时间线历史版本已被新版本替代升级新版本时旧主文件改名为.vNlt;namegt;.b1.yamllt;namegt;.b2.yamllt;namegt;.bN.yamlfan-out 分支候选同时刻互斥假设scout 出 N 候选 → 主 agent 派 N 个 worker → 各产出一个.bN文件真实的情况是这样的classes/Animal/methods/ ├── speak.yaml ← 当前主文件v3 内容confirmed从 b3 复制来 ├── speak.v1.yaml ← 第一次分析status: rejected把它当成普通函数 ├── speak.v2.yaml ← 第二次分析status: superseded识别为 Animal::speak 但还原不准 ├── speak.b1.yaml ← fan-out 候选 1djb2 假设status: rejected ├── speak.b2.yaml ← fan-out 候选 2strcmp 假设status: rejected └── speak.b3.yaml ← fan-out 候选 3CRC32 假设status: superseded已被 speak.yaml 取代为活跃文件迁移机制通常笔者遇到的都是大型商业软件的逆向所以遇到面向过程的的极少都是面向对象的设计模型。传统那几种吧。所以逆向到最后一定是一个类方法虚方法等等。这里面就存在一个 最早期的函数到面向过程的转行问题比如一个核心算法他最后肯定是一个类不是一个函数。在我们的上下文管理中就存在从函数状态的上下文到类对象的迁移过程。设计是这样的1. 写新位置 classes/lt;Xgt;/methods/lt;namegt;.yaml加上 类 和 方法名 两个字段 2. 更新主索引 addresses 里对应那条 - path 改为新位置 - kind 从 function 改为 method 3. 更新类的 class.yaml**在 方法清单 数组里加上 lt;namegt; 4. 删除旧位置** functions/lt;addrgt;.yaml主要是做文件的迁移吧之前的旧文件删除迁移到对应的类下面.AI思维分析上下文管理这个部分是非常杂的所以不能做那么精细化的区分。这里拿一个真实项目举例从任务出发到最后的定位总结分析 整套链路。设计如下:--- 编号: 001 任务: 分析 foo.dll 的 USB HID 协议 任务类型: 协议分析 # 还原 / debug / patch / 协议分析 / 行为分析 / ... 模式档位: 轻量 # 轻量 / 重量重量启动前必须用户同意 状态: 进行中 # 进行中 / 已结案 / 已放弃 创建时间: 2026-04-30 更新时间: 2026-04-30 ---knowledge 设计在说完我们的上下文管理后讲一下在我自己的任务中存在的高精度还原问题。首先我蒸馏我自己将所有的最基础的RE和编译原理进行蒸馏成一个知识库。INDEX是整个知识库的索引目录用来读取Agent遇到问题的时候所需要的知识。Skills上面我说过AI是不懂逆向的他懂的是F5以及汇编不明白如何还原一个类或者一个算法。所以这里我整理了两个skills一个是类分析和lift也就是我说的人肉f5.这个位置就是我们需要技能ai不会的但是人为指点后就可以完成的事情。比如脱壳去花等等。。。。lift skills在高精度的还原我们人是通过汇编的骨架还原。流程如下步骤 1 骨架还原 控制流壳if/while/for/switch条件和函数体用占位符 ↓ 步骤 2 逐行机械翻译 asm → C 伪代码变量名直接用寄存器名不识别不优化 ↓ 步骤 3 签名草稿 从调用方视角推断调用约定 参数个数待修正 ↓ 步骤 4 优化 约定寄存器识别 / 折叠中间寄存器 / 内存操作分类 / lea 处理 ↓ 步骤 5 语义折叠 识别算法模式 改有意义变量名 修正签名这里产物一定是一个cpp文件也就是对应上面的上下文的产物管理的部分。Class-identify Skill由于我工作中大量需要设计类和对象的整个项目的工程化的评估我需要有一个系统的评估技能。根据我自己的业务制作了一个Skills工作流简版 1. **RTTI 优先** → 有 RTTI 的话整套继承图、类名、虚函数表都能直接拿到 2. **没 RTTI 时用户给起点** → 用户给某个 ctor / thiscall 方法的地址作为分析起点 3. **通过 vtable 列虚方法** 4. **thiscall 偏移聚类列非虚方法** 5. **配合方法体粗还原汇总 [thisN] 偏移得成员清单** 输出强制 yaml schema测试成功这里我拿我之前网页AI时期的半古法分析的一个的帖子作为测试Gtuner软件协议分析可以去看我自己的其他文章看我这套东西是否能跑通。最后产物几乎是没用我多少时间全程agent就自主完成了中间打断了我四次打了一把游戏agent就完成了结尾针对我自己的工作目前就这样设计的目前还有动态调试的部分没有讲如何融入进来。这里主要是讲解设计虽然我会把我的工程发到附件里面去但是不推荐直接使用可以利用我这种设计打造属于自己的逆向工程sln。这里推荐使用opencode可以把主脑配置到deep seek v4干活可以使用glm5.1这样可以使用国产甚至是内网模型来完成工作不再受制于claude 虽然它目前还是最强的。感谢您看到这里了如果觉得有帮助可以点个赞吗对于有啥意见和感受都可以在评论区讨论关于Python学习指南如果你对Python感兴趣想通过学习Python获取更高的薪资那下面这套Python学习资料一定对你有用资料包括Python安装包激活码、Python web开发Python爬虫Python数据分析人工智能、机器学习等学习教程。0基础小白也能听懂、看懂跟着教程走带你从零基础系统性地学好Python一、Python所有方向的学习路线Python所有方向路线就是把Python常用的技术点做整理形成各个领域的知识点汇总它的用处就在于你可以按照上面的知识点去找对应的学习资源保证自己学得较为全面。二、Python学习软件工欲善其事必先利其器。学习Python常用的开发软件都在这里了三、Python操作实例学python就与学数学一样是不能只看书不做题的直接看步骤和答案会让人误以为自己全都掌握了但是碰到生题的时候还是会一筹莫展。因此在学习python的过程中一定要记得多动手写代码教程只需要看一两遍即可。四、Python就业项目实战我们学习Python必然是为了找到高薪的工作或者高报酬的兼职下面是一些公司所能用到的实战项目学完这些相信大家一定可以找到满意的工作。领取方式我会放在下面希望领取了的朋友不要忘了下方名片放心添加*)