吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1081|回复: 15
上一主题 下一主题
收起左侧

[Android 分享] Android 逆向 Multi-Agent 系统设计

[复制链接]
跳转到指定楼层
楼主
rsds0duck 发表于 2026-6-2 09:50 回帖奖励

Android 逆向 Multi-Agent 系统设计

作者: 人生导师
日期: 2026 年 6 月 1 日
状态: 设计阶段,画饼中

这篇不是教程,是给自己画的饼。把之前几个月学 Agent、踩坑、想明白的东西落成一个可执行的系统设计。目标很明确:搞一个多 Agent 协作系统,专门干 Android 逆向的活。


核心理念

不搞主从调度那套。五个角色信息平权,像一个小组群聊:

  • 各自有独立上下文,不共享对话历史
  • 通过消息总线交换结论性信息,不是中间推理过程
  • 任何人可以 @任何人,不需要经过"领导"中转
  • 我(人)是 leader,但不是瓶颈——大部分时候系统自己跑

架构总览

┌─────────────────────────────────────────────────────┐
│                    消息总线(群聊)                 │
│         SQLite/Redis + HTTP API + @机制             │
└──────┬────────┬────────┬────────┬────────┬──────────┘
       │        │        │        │        │
  ┌────▼────┐┌───▼────┐┌──▼────┐┌──▼────┐┌──▼──┐
  │  主模型  ││IDA+Jadx ││Trace   ││Unidbg  ││  我  │
  │ 调度+搜索││静态分析 ││算法分析││补环境  ││Leader│
  └──────────┘└─────────┘└────────┘└── ─────┘└──────┘
       │        │        │        │
  ┌───▼────┐┌──▼────┐┌─▼───┐┌──▼───┐
  │搜索工具 ││IDA MCP ││trace ││unidbg │
  │网络判断 ││Jadx CLI││数据  ││Java   │
  └───── ───┘└────────┘└──────┘└───────┘

五个角色定义

角色 职责 工具 模型选择
主模型 任务分发、网络搜索、信息判断、进度总结 搜索引擎、文档读取 Claude/GPT(需要强推理)
IDA+Jadx 静态分析、函数识别、交叉引用、Java 层分析 IDA MCP、Jadx CLI Claude(代码理解强)
Trace 执行流分析、算法还原、handler 映射 trace 文件读取、模式匹配工具 Claude(长上下文+精确推理)
Unidbg 补环境、模拟执行、验证算法 unidbg Java API、编译执行 DS/Claude(代码生成)
终审、路径决策、质量把关 脑子 碳基模型

通信机制:群聊模型

为什么不用 A2A

Google 的 A2A 协议太早期了,生态几乎没有。用它等于自己实现大部分东西,协议本身反而成了额外负担。

实际方案:消息总线

本质就是一个"群":

# 消息结构
{
    "id": "msg_001",
    "from": "trace_agent",      # 发送者
    "to": "unidbg_agent",       # @谁,null=广播
    "type": "conclusion",       # conclusion/request/question/status
    "content": "sub_12A0 的算法是 HMAC-SHA256,salt 拼接规则如下...",
    "evidence": ["trace_line_47", "trace_line_128"],  # 支撑证据引用
    "confidence": "high",       # high/medium/low
    "timestamp": "2026-06-01T14:30:00Z"
}

@机制

  • @trace_agent:直接发给 trace agent,它下次被唤醒时看到
  • @all:广播,所有 agent 下次唤醒时都能看到
  • @human:上报给我,我来决策

每个 agent 的消息处理流程

1. 被唤醒(定时轮询 or 被@触发)
2. 拉取自己的未读消息
3. 结合自己的上下文处理
4. 输出结论/请求/问题
5. 发到消息总线
6. 回到等待状态

信息流设计:不仅传递结论,也传递可复用知识

最开始设计消息总线时,倾向于只传递结论,避免 Agent 之间互相污染上下文,也避免大量思维链导致上下文爆炸。

但在实际逆向场景中发现:

逆向工程中的很多高价值信息,在形成最终结论之前就已经具备协作价值。

例如:

  • IDA agent 发现某函数存在 64 轮循环
  • Trace agent 发现某段执行流存在 64 次状态更新
  • Unidbg agent 发现某个常量在运行时被频繁访问

这些信息单独看不足以形成结论,但多个 Agent 的观察组合后,可能快速收敛到正确方向。

因此消息总线不应只传递最终结论,而应该支持不同层级的信息流转。


信息层级模型

系统内部将信息分为四层:

Observation(观察)
↓
Fact(事实)
↓
Hypothesis(假设)
↓
Conclusion(已验证结论)
Observation(观察)

Agent 发现的现象。

特点:

  • 未经过验证
  • 不包含推测
  • 仅描述观察到的内容

示例:

{
"type": "observation",
"agent": "trace_agent",
"content": "sub_5200 存在 64 次重复状态更新"
}
{
"type": "observation",
"agent": "ida_agent",
"content": "sub_5200 存在 64 轮循环结构"
}
Fact(事实)

已经通过工具、代码或证据确认的信息。

特点:

  • 可复现
  • 可验证
  • 具有明确证据来源

示例:

{
    "type": "fact",
    "content": "sub_12A0 调用了 sub_5200",
    "evidence": [
        "xref_001"
    ]
}
{
    "type": "fact",
    "content": "trace 第 487 行出现常量 0x6A09E667",
    "evidence": [
        "trace_487"
    ]
}
Hypothesis(假设)

基于观察和事实形成的推测。

特点:

  • 明确标记为推测
  • 必须附带支撑证据
  • 后续需要验证

示例:

{
    "type": "hypothesis",
    "content": "sub_5200 可能实现了 SHA256",
    "evidence": [
        "fact_021",
        "fact_037"
    ],
    "confidence": "medium"
}
Conclusion(结论)

已经通过校验机制确认的信息。

特点:

  • 已通过验证
  • 可进入知识库
  • 可作为后续分析的可信前提

示例:

{
    "type": "conclusion",
    "content": "sub_5200 确认为 SHA256 实现",
    "verified": true,
    "verification_source": [
        "trace_agent",
        "unidbg_agent"
    ]
}
为什么这样设计

传统 Agent 系统更关注任务流:

任务
    ↓
执行
    ↓
结果

而逆向工程更接近知识流:

观察
    ↓
事实
    ↓
假设
    ↓
验证
    ↓
结论

系统的目标不是尽快产出答案,而是持续积累可信知识。

因此:

  • Observation 用于发现线索
  • Fact 用于沉淀证据
  • Hypothesis 用于驱动探索
  • Conclusion 用于构建最终知识库

Agent 之间共享的核心不是推理过程,而是这些经过结构化组织的信息。

这样既能避免上下文爆炸,也能最大限度保留逆向过程中最有价值的证据和知识。


三层校验机制

这是系统可靠性的核心。模型会编,但我们有办法拦住。

工作agent输出结论
    ↓
┌────────────────────────────────────┐
│ 第一层:自校验                     │
│  - 硬校验:代码验证具体值/常量/行号│
│  - 软校验:模型自查推理链完整性    │
│  - 过了 → 第二层                  │
│  - 没过 → 打回重做(最多3次)     │
└───────────────┬────────────────────┘
                ↓
┌────────────────────────────────────┐
│ 第二层:校验agent(无状态冷启动)  │
│  - 每次清空上下文,零先入为主      │
│  - 输入:结论 + 证据 + 原始数据    │
│  - 独立判断有没有矛盾              │
│  - PASS → 结论入库                │
│  - FAIL → 打回重做                │
│  - UNCERTAIN → 上报第三层         │
└───────────────┬────────────────────┘
                ↓
┌─────────────────────────────────┐
│ 第三层:我                      │
│  - 只看 UNCERTAIN 和反复 FAIL 的│
│  - 做路径决策和最终判断         │
└─────────────────────────────────┘

校验 agent 的设计要点

  • 无状态:每次任务完成后清空上下文,下次冷启动
  • 不知道历史:不知道之前谁说了什么,避免 confirmation bias
  • 只看证据:给它原始数据和结论,让它找矛盾
  • 输出格式固定:PASS / FAIL / UNCERTAIN + 理由

校验 prompt 模板

你是一个独立的校验员。你不知道之前发生了什么。
以下是一个分析结论和支撑证据。

【结论】
{conclusion}

【原始证据】
{evidence}

请验证:
1. 结论中引用的具体数据(地址、值、行号)是否在证据中存在且一致
2. 结论的推理链是否有跳跃(A→B→C,每一步是否有依据)
3. 是否存在证据中的信息与结论矛盾
4. 结论是否遗漏了证据中的关键信息

输出格式:
- 判定:PASS / FAIL / UNCERTAIN
- 理由:(具体说明哪里有问题或为什么通过)
- 建议:(如果FAIL,建议从哪个方向重新分析)

硬校验示例(代码实现)

def hard_verify(conclusion: dict, trace_data: list) -> bool:
    """验证结论中引用的具体值是否在trace中存在"""
    for assertion in conclusion["assertions"]:
        if assertion["type"] == "register_value":
            line = trace_data[assertion["line_number"]]
            if assertion["register"] not in line or \
               line[assertion["register"]] != assertion["value"]:
                return False
        elif assertion["type"] == "constant":
            # 在trace中搜索这个常量
            found = any(assertion["value"] in line for line in trace_data)
            if not found:
                return False
    return True

工作流示例:分析一个签名算法

用一个典型场景走一遍整个系统怎么协作:

目标:还原 libxxx.so 中的 sign 签名算法

1. 我 @主模型:"分析 libxxx.so 的签名生成逻辑"

2. 主模型:
   - 搜索网上有没有现成分析文章
   - 判断:没有直接可用的,需要自己分析
   - @ida_agent:"定位签名入口函数,从 JNI_OnLoad 开始找"
   - @all:"任务启动,目标是 sign 算法还原"

3. IDA+Jadx agent:
   - 通过 IDA MCP 找到 JNI 注册表
   - 定位到 native 函数 Java_com_xxx_Sign_generate
   - 分析调用链,发现核心逻辑在 sub_12A0
   - @trace_agent:"入口确认为 sub_12A0,请收集执行 trace"
   - @all:"入口函数定位完成:sub_12A0,调用了 sub_3F00 和 sub_5200"

4. Trace agent:
   - 读取 sub_12A0 的执行 trace
   - 分析数据流和运算模式
   - 识别出 HMAC-SHA256 特征(初始值匹配)
   - 自校验:在 trace 中确认 SHA256 的 H0-H7 初始值存在 ✓
   - 校验agent验证:PASS
   - @unidbg_agent:"算法是 HMAC-SHA256,key 来自 sub_3F00 返回值,请补环境验证"
   - @all:"算法识别完成:HMAC-SHA256,salt 拼接规则为 timestamp + device_id"

5. Unidbg agent:
   - 搭建 unidbg 环境,加载 libxxx.so
   - 补 JNI 环境(GetStringUTFChars 等)
   - 调用 sub_12A0,输入已知参数
   - 对比输出和抓包结果
   - 匹配 → @all:"验证通过,算法还原正确"
   - 不匹配 → @trace_agent:"验证不通过,输出差异如下..."

6. 主模型:
   - 收到所有 agent 的结论
   - 整合成最终报告
   - @human:"分析完成,结果如下..."

持久化设计

逆向一个目标可能跨好几天,进度不能丢。

项目状态文件

每个逆向项目一个目录,核心状态文件:

project_xxx/
├── status.json          # 整体进度和状态
├── conclusions/         # 已确认的结论(通过校验的)
│   ├── func_sub_12A0.json
│   └── func_sub_3F00.json
├── messages/            # 消息历史(消息总线的持久化)
├── traces/              # trace 数据
├── unidbg/              # unidbg 项目代码
└── failed_attempts/     # 失败的尝试(防止重蹈覆辙)

status.json 结构

{
    "target": "libxxx.so",
    "goal": "还原 sign 签名算法",
    "started": "2026-06-01",
    "phase": "algorithm_identification",
    "progress": {
        "entry_located": true,
        "call_chain_mapped": true,
        "algorithm_identified": false,
        "implementation_done": false,
        "verified": false
    },
    "confirmed_facts": [
        "入口函数: sub_12A0 (Java_com_xxx_Sign_generate)",
        "调用链: sub_12A0 → sub_3F00 (key生成) → sub_5200 (加密核心)"
    ],
    "blocked_paths": [
        "sub_7000-sub_8000 是 VMP 保护,静态分析无效"
    ],
    "next_steps": [
        "trace agent 分析 sub_5200 的执行流"
    ]
}

Agent 恢复机制

每个 agent 启动时:

  1. 读 status.json 了解全局进度
  2. 读自己相关的 conclusions/ 了解已确认信息
  3. 拉取未读消息
  4. 继续工作

不需要记住对话历史,状态全在文件里。


技术选型

语言:Python

理由:

  • AI SDK 生态最好(anthropic、openai、litellm)
  • FastAPI 做后端接口简单
  • 逆向工具链大部分有 Python binding
  • 启动快,几百行代码毫秒级

模型调用:litellm

统一接口切模型,想用 Claude 用 Claude,想用 DS 省钱用 DS:

import litellm

# trace agent 用 Claude(需要精确推理)
response = litellm.completion(
    model="claude-sonnet-4-20250514",
    messages=[...]
)

# unidbg agent 用 DS(代码生成,便宜)
response = litellm.completion(
    model="deepseek/deepseek-chat",
    messages=[...]
)

消息总线:SQLite + FastAPI

不需要 Redis 那么重,SQLite 够用:

# 消息表
CREATE TABLE messages (
    id INTEGER PRIMARY KEY,
    from_agent TEXT,
    to_agent TEXT,        -- NULL = 广播
    type TEXT,            -- conclusion/request/question/status
    content TEXT,
    evidence TEXT,        -- JSON array
    confidence TEXT,
    created_at TIMESTAMP,
    read_by TEXT          -- JSON array,谁已读
);

工具集成:MCP

每个 agent 挂自己的 MCP server:

  • IDA agent → ida-pro-mcp
  • Unidbg agent → 自己写一个 unidbg MCP(或者直接 subprocess 调用)
  • Trace agent → 文件读取 + 自定义分析工具
  • 主模型 → 搜索工具

开发路线图

Phase 1:最小可行版本(先跑通通信)

我(CLI输入)+ 1个 trace agent + 消息总线
- 验证消息收发机制
- 验证 agent 能正确处理 @消息
- 验证自校验流程
预计:1-2 周

Phase 2:加入校验机制

在 Phase 1 基础上加入:
- 硬校验(代码验证)
- 校验 agent(无状态冷启动)
- 重试和上报机制
预计:1 周

Phase 3:扩展到完整系统

加入其他 agent:
- 主模型(调度+搜索)
- IDA+Jadx agent
- Unidbg agent
- 持久化机制
预计:2-3 周

Phase 4:实战打磨

拿真实目标跑:
- 先跑一个简单的(非VMP、标准算法)
- 再跑中等难度(魔改算法)
- 最后挑战 VMP 保护的
根据实战调整设计
预计:持续迭代

已知的坑和待解决问题

模型能力边界

  • trace 分析在第四五层(跨 handler 状态传递、全局 VM 结构还原)模型会飘
  • 提示词工程能扩大可用范围,但天花板还在
  • 需要实测 DS 在各层的表现,决定哪些任务可以用便宜模型

上下文管理

  • 单个 trace 可能几百万行,不可能全塞给模型
  • 需要设计"渐进式喂数据"的策略:先给摘要,模型要细节再给
  • 滑动窗口?摘要+按需展开?这个要实验

校验的校验

  • 校验 agent 本身也可能犯错
  • 硬校验能覆盖的范围有限(只能验证具体值,验不了逻辑)
  • 需要设计"校验覆盖率"指标——一个结论有多少比例被硬校验覆盖了

成本控制

  • Claude 贵,不能所有 agent 都用顶配
  • 需要实测各模型在各任务上的性价比
  • 可能的策略:简单任务用 DS,关键判断用 Claude

人的介入点设计

  • 现在还没想清楚什么时候该打断我
  • 太频繁 → 我成了瓶颈
  • 太少 → 系统可能在错误方向上跑很远
  • 暂定:UNCERTAIN + 连续 FAIL 3 次 → 上报

跟现有方案的对比

维度 Claude Code Hermes 我的方案
模型自由度 只能用 Claude 任意 任意,按任务选
多 agent 协作 团队模式(封闭) delegate_task 群聊模型(平权)
逆向工具集成 需要自己搞 MCP MCP
校验机制 三层校验
持久化 git checkpoint memory+session 项目状态文件
启动速度 3-5 秒 毫秒级
定制程度 完全自定义

这个饼能不能吃到

说实话,这个系统的核心难点不在代码量——可能总共就几千行 Python。难的是:

  1. prompt 设计:每个 agent 的系统提示词怎么写,直接决定它能不能干好活
  2. 任务拆分粒度:给模型的任务太大它搞不定,太小又没效率
  3. 校验规则设计:什么算"可验证的断言",这个需要逆向经验来定义
  4. 实战调优:设计再好,跑起来肯定一堆问题,需要反复迭代

但这些都是可以逐步解决的问题,不是原理性障碍。先把 Phase 1 跑通,后面一步步来。

最坏情况:系统跑不起来,但过程中积累的 prompt 模板、校验方法、工具集成经验,单独拿出来也有用。

最好情况:系统能自动完成 70% 的分析工作,我只需要在关键节点做决策。那逆向效率直接翻几倍。

也写了一些些吧,把开源的GitHub链接拿出来给各位看看
https://github.com/djskncxm/DuckAgent

免费评分

参与人数 7吾爱币 +14 热心值 +6 收起 理由
aisrs + 1 + 1 我很赞同!
ALLALONE + 1 + 1 我很赞同!
FJFJ + 1 + 1 我很赞同!
正己 + 8 + 1 用心讨论,共获提升!
PokerS429 + 1 + 1 谢谢@Thanks!
293a + 1 + 1 用心讨论,共获提升!
shengruqing + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
xjwp 发表于 2026-6-2 14:20
1. @mention 平权路由 — Agent 之间互相 @agent_id 点名,不设中心路由器。比我们的 sessions_spawn 层级调度更灵活。

2. MessageBus ABC — 抽象消息总线接口,Local(asyncio.Queue+SQLite)和 HTTP(FastAPI+WebSocket)可无缝切换。

3. 双重验证 — hard_verify(结构检查:conclusion 必须有 evidence)+ self_check(LLM 自审推理链)。比我们的 gate-precheck 更轻量。

4. 上下文隔离 — 每次 think() 从零开始,不累积跨消息上下文。防止上下文污染。

5. 状态广播 — Agent 工作时广播 thinking/tool_calling/idle 状态,UI 实时显示。

6. 自愈机制 — self_check 失败 → 把失败原因发回 LLM 重试 → 连续 3 次失败上报人工。  我已经复用以上功能,感谢分享
沙发
pjxdr 发表于 2026-6-2 09:55
3#
echo2000 发表于 2026-6-2 10:30
4#
sesine 发表于 2026-6-2 10:59
大佬,当初学Android开发,Multi-Agent都云里雾里,这直接给逆向还分析了
5#
2090387835 发表于 2026-6-2 12:26
楼主加油,我先拉取到本地让gpt看看
6#
 楼主| rsds0duck 发表于 2026-6-2 12:36 |楼主

这还早啊,我也是摸石头过河了
8#
hansxia 发表于 2026-6-2 15:12
烧Token的进度如何?

我目前用codex没有添加任何的Agent去辅助,AI容易跑偏

9#
qq196796483 发表于 2026-6-2 20:50
学习了第一次意识到ai接入安卓,我先去研究研究代码了,谢谢分享加油兄弟
10#
正己 发表于 2026-6-2 20:56
坐等师傅开源狠狠star
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-6-4 03:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表