English · 简体中文
能力 · 结构 · 安装 · 环境要求 · 失败目录 · 范围 · 维护 · 免责声明
apk-reverse
面向 Android APK 逆向工程、去臃肿、去广告、外科式 dex 补丁、重打包,以及运行时/服务端分析的 Agent Skill。
它是一个 skill,不是教程:它是写给 agent(Claude Code、Codex,或任何支持 Agent Skills 格式的 harness)在工作过程中加载的,因此按 progressive disclosure(渐进披露)来组织——一份简短、面向决策的 SKILL.md,只在某一步真正需要时才加载的详细 references,以及可直接运行的参数化脚本。
Agent 应当如何使用它
SKILL.md 刻意写成一份带 gate 的流程,而不是建议,因为观察到的失败模式并不是无知——而是模型把整份文档读完、表示认同,然后照样从第一性原理重新推理一遍。
所以正文里有四样东西是用来执行的,不是用来读的:
- 四条覆盖规则(R1–R4)。 当它们与当前计划冲突时,在证据推翻它们之前,以它们为准。
- 一份症状索引。 每一行都是已经付过代价的失败。命中一行就是停止信号:在你跑下一条命令之前加载那个文件,而不是在又试了几次之后。绕过已经记录在案的已知症状继续推理,就是同一批小时被花掉两次的方式。
- 四个 gate(G1–G4),每个都是一个动作加一条通过标准。「我理解这个思路」并不能通过 gate。它们存在的意义是让分类、环境真相和对照构建发生在第一次打补丁之前,而不是在第三次失败之后。
- 一条两击规则和若干停止条件。 同一形态的失败出现两次,说明错的是模型,不是参数。一个已经失败过两次的假设再出第三个变体,就是回合葬身之处。
另外还有一样在结尾、应当被扣住的东西:**「done」**有定义(六项)。一份干净的日志不在其中。少于六项全部达成,就只是一个检查点,应当作为检查点汇报,并说明还剩什么。
如果你是正在读这段的 agent:成本最低的第一条命令是 python skills/apk-reverse/scripts/doctor.py。它会告诉你这里存在哪些工具、哪些脚本真的能跑,以及环境里是否已经有什么东西在污染你的测量结果。
它擅长什么
- 快速判断一个需求在客户端是否本来就做不到,而不是把几小时烧在一个由服务端强制执行的付费墙(paywall)上。
- 在任何工作开始之前先确定交付物必须是什么形态——一个免 root、自包含的产物与「让它在你这台机器上能跑」是两个不同的问题,混淆这两者是这个领域里最昂贵的漂移。
- 为给定改动选择最安全的补丁层,并避开那些会把 app 弄坏的层。
- 抓住那种「看起来成功」的重打包失败:app 安装、启动、渲染都完美,但每一个签名请求都被拒绝,因为客户端是从自己的签名证书推导请求签名密钥的。
- 把你自己的错误与 app 或服务端的问题区分开——限定在某个功能上的失败(登录、注册、支付)常常是某一条代码路径上的 TLS/证书问题,而不是你刚做出来的补丁的后果。设备状态、失联的 device server 和时钟漂移会以同样的方式伪装成同类问题。
- 确认实际执行的是哪个架构、哪个库,而不是相信 manifest 里带了什么或设备自称什么。
- 处理加壳/加固目标:识别壳、脱壳,并把内存 dump 还原成一个打过补丁、可安装的 APK。
- 处理一个故意终止进程的加固库——包括那种刻意崩溃的形态(
fault addr 0x4),它看起来和普通的空指针解引用 bug 一模一样;以及「把它失效化,但绝不要让它不返回」这条规则,它决定修法是生效,还是以完全看不出与原因有关的方式冻住整个 app。
- 知道该伸手去拿哪些工具,以及每个工具在哪里说谎——包括那些只以 GUI 形式存在的工具,此时应当请求人类介入,而不是悄悄换用一个更弱的方法。
- 让打过补丁的构建保持打过补丁:失效化版本检查、强制升级弹窗和自更新安装器,使这份成果无法被远端一键关掉——同时认出那个能在版本号毫无变化的情况下悄悄把它撤销的热更新/远程配置通道。
- 把客户端侧的登录闸门(可打补丁)与账号维度的资源(为空,因为服务端没有东西可答)区分开;并且知道伪造一个 session 所产生的状态比保持未登录更糟。
- 让长时间任务保持诚实:一份实时记录、分级结论、校准过的超时和有界等待,使进展不会丢失、同一个错误不会被犯两次。
- 避开那些会产出「构建完美、运行即死」的 APK 的具体错误。
- 当 APK 不是可选项时,决定交付物应该是什么——被多个独立检查拒绝的重打包是受阻,不是昂贵;回落阶梯是系统级模块、本地 RPC 服务,或一份明确写出边界的诚实报告。
- 分辨真实内存 dump 与抽取壳骨架,并知道哪条恢复路线适用——包括当
frida 本身被拒绝时走 root 侧 dump。这次测量能看见什么、看不见什么,写在 skills/apk-reverse/references/advanced-unpacking.md。
- 当逆向的成本高于调用时,调用例程而不是逆向它:在宿主上做模拟执行,或把一个活函数通过 Frida RPC 服务化。
- 当一个 native 函数被 OLLVM 碾平成状态机时,去读指令级执行证据——包括在真实设备上实测到的 Stalker 反咬的两种方式。
- 认出用户态 hooking 根本够不到那个检查的情况(裸
svc 系统调用、init_array 早期检测)、上下相邻层实际能做什么,以及什么时候继续升级是错误答案。
- 处理非 REST 的协议——无 schema 的 protobuf、gRPC、QUIC/HTTP3——以及无视系统信任库的 native 侧证书固定(pinning)。
- 直接在手机上工作:MT Manager 的编辑/重打包/签名流程及其 APK MCP 接口、LSPosed Manager、设备上的数据检查,与 PC 工具链并用,而不是用它来替代 PC 工具链。
- 在花几小时去追一个在进程生命周期内任何时刻都不存在的「解密 DEX」之前,先把 Java2C 与抽取壳区分开——代码已经被编译进
.so。
- 处理以 split APK / App Bundle 集合形式到来的构建:从设备上取出该集合、用一个 keystore 为每个成员签名以便
pm install-multiple,或在合法时把 code/native 成员合并成一个独立 APK。
- 用已知明文差分处理一个真实的 Dex VMP——哪些环节可以自动化、哪些不能,一个编译出来的 fixture 能触达什么、不能触达什么,以及如何证明一张推导出的私有 opcode 表,而不是断言它。
- 在发表所学的同时不发表目标——一个带上下文报告目标身份形态的扫描器、一份明确列出不得脱敏内容(工具、库、协议字段、CVE、加固产品、公开 crackme)的清单,因为把这些脱敏会毁掉可复用的那部分;以及能 gate 住一次提交的退出码。
- 在重复本仓库已经收敛过的劳动之前先读先例:记录中正向的那一半,含路线及其死路、对每条断言的分级,以及该案例指明要回写的文件。
结构
SKILL.md、references/ 与 scripts/ 都在 skill 目录 skills/apk-reverse/ 内。仓库根目录下的一切是跨 skill 共享的维护工具,不属于已安装的 skill。