Metadata.d2全解读android-reverse-engineering-skill从JVM类型描述符恢复类名【免费下载链接】android-reverse-engineering-skillClaude Code skill to support Android apps reverse engineering项目地址: https://gitcode.com/GitHub_Trending/an/android-reverse-engineering-skillandroid-reverse-engineering-skill 是一款面向 Claude Code 的 Android APK 逆向工程技能它能反编译 APK/XAPK/JAR/AAR、提取 HTTP 接口还能借助 Kotlin 的Metadata.d2注解从 R8 混淆后的应用中恢复出开发者原本写的类名——这是整篇文章的核心。一句话总结R8 会把AccountRepositoryImpl重命名成a.b.c但它删不掉Kotlin 元数据里的原始全限定名。这个技能就是把这些藏在注释里的名字挖出来。一、为什么反编译后类名全变成 a.b.c现代 Android 应用几乎都用 Kotlin 编写并经过 R8/ProGuard 混淆后上架。反编译之后你看到的是这样的源码public final class a implements ... { ... }--deobf之类的重命名参数只是生成p001a、C0123Foo这样的合成名字并不是开发者原来写的名字。对于逆向分析来说真正的价值在于读*Repository、*ViewModel、*UseCase这些业务类——而它们恰恰是混淆的重灾区。关键洞察在于R8 重命名的是 JVM 符号但 Kotlin 元数据字符串删不掉。因为 Kotlin 运行时在反射、协程、data class 等场景下运行期仍然依赖这些原始全限定名。二、Metadata.d2 是什么藏在注解里的逃生通道每个 Kotlin 类在反编译后都带有一个顶层Metadata注解其中的d2数组列出了文件内引用的类名格式是JVM 类型描述符L包名/类名;Metadata(d1 {...}, d2 {..., Lcom/example/feature/account/AccountRepositoryImpl;, ...}) public final class b implements ... { ... }解读Lcom/example/feature/account/AccountRepositoryImpl;只需三步步骤操作结果1去掉首尾的L和;com/example/feature/account/AccountRepositoryImpl2把/换成.com.example.feature.account.AccountRepositoryImpl3丢弃kotlin.、java.等标准库前缀✅ 原始类名到手技能里 recover-kotlin-names.sh 正是用一行正则完成这件事RE_LCLASS re.compile(rL([A-Za-z][\w/$]);)另一个辅助来源DebugMetadata几乎每个suspend函数协程都会生成带DebugMetadata注解的 SuspendLambda它的c字段直接携带原始类名DebugMetadata( c com.example.feature.account.AccountRepositoryImpl$fetch$1, f AccountRepositoryImpl.kt, m invokeSuspend) public final class a extends SuspendLambda implements Function2... { ... }脚本的挖掘优先级是DebugMetadata→Metadata.d2→ jadx 的renamed from注释三者互为补充。三、一键恢复类名recover-kotlin-names.sh 怎么用反编译完成后只需一条命令即可构建混淆名 → 真实名映射表bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/recover-kotlin-names.sh output/sources/ output/names/脚本会遍历所有*.java文件自动跳过kotlin.、androidx.、okhttp3.等第三方目录产出三份成果输出文件内容用途mapping.tsv混淆名 / 真实名 / 文件路径人工阅读、导入表格mapping.json同一数据的 JSON 格式供 lookup-name.sh 查询by_package/按真实包名分组的索引快速浏览某个功能包运行结束会打印统计例如从 d2 恢复了 N 个类名让你立刻知道收益。四、lookup-name.sh三种查询姿势映射建好之后日常查名全靠 lookup-name.sh# ① 按真实名关键字搜索比如找所有 Repository bash .../lookup-name.sh output/names/ Repository # ② 反查遇到混淆名 nq.e 时一键解析出真实类名和它的兄弟类 bash .../lookup-name.sh output/names/ -o nq.e # ③ 最实用grep 源码每条命中自动追加注释 // 真实类名 bash .../lookup-name.sh output/names/ --grep /api/ output/sources/第三种模式是杀手锏你不必再盯着nq.e这种天书猜它属于哪个类每条 grep 命中后面都会跟着真实的归属类名读混淆代码的效率直接翻倍。五、恢复效果能找回多少类名在真实世界的混淆 Kotlin 应用上脚本通常能恢复 30%–50% 的类——但重点在于你真正想读的类恢复率接近 100%。类的类型典型恢复率*Repository/*Impl~100%*ViewModel~100%*UseCase/*Interactor~100%普通 data classDTO~80%纯 Java 工具类低没有 Kotlin 元数据匿名内部类有时能恢复为父类全限定名六、常见误区与注意事项误区jadx 的--deobf就够了。不够。--deobf只是用内部启发式重命名标识符产出的是合成名恢复不了原始类名。正确姿势是组合拳--deobf处理字段和方法名元数据恢复脚本处理类名两者互补。已知局限详见 kotlin-name-recovery.md⚠️方法名和字段名不在恢复范围内——Kotlin 元数据只保留类级全限定名方法名仍需手动推断或交互式重命名⚠️纯 Java 类没有Metadata会保持混淆状态⚠️ 被重度内联的类JvmInlinevalue class、顶层函数编译出的合成*Kt.class偶尔会张冠李戴把结果当强提示而非绝对真理。七、快速上手4 条命令跑通完整流程# 1. 反编译前先给 APK 做体检框架、混淆程度、HTTP 技术栈 bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/fingerprint.sh app.apk # 2. 反编译混淆应用记得加 --deobf bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/decompile.sh --deobf app.apk # 3. 挖掘 Kotlin 元数据生成类名映射 bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/recover-kotlin-names.sh output/sources/ output/names/ # 4. 带着真实类名注释去 grep 源码 bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/lookup-name.sh output/names/ --grep /api/ output/sources/这套流程在技能的工作流中对应 Phase 3.5见 SKILL.md建议只在混淆程度中等/高 确认是 Kotlin 应用时执行。也可以在 Claude Code 中直接输入/decompile app.apk触发完整工作流定义见 decompile.md。写在最后Metadata.d2就像开发者无意间留在废墟里的门牌号。android-reverse-engineering-skill 把读注解 → 解析 JVM 类型描述符 → 建映射 → 查询标注这一整套动作封装成了两个轻量脚本几乎零成本地把反编译代码从天书变回人话。想深入了解原理和边界情况推荐阅读项目内的完整技术文档 kotlin-name-recovery.md 与总体说明 README.md。【免费下载链接】android-reverse-engineering-skillClaude Code skill to support Android apps reverse engineering项目地址: https://gitcode.com/GitHub_Trending/an/android-reverse-engineering-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考