第十四节_Android_代码混淆与解混淆

第十四节 Android 代码混淆与解混淆

(第2章 安卓逆向基础)

学习目标

学完本节,希望你能够:

  1. 说出 Android 代码混淆 在干啥:把类名、方法名、变量名等替换成短无意义名(如 a、b、c),减小体积、增加逆向难度。
  2. 知道常见混淆工具:ProGuardR8 (默认启用)、DexGuard 、以及国内加固(如 360)等;混淆和加壳不是一回事。
  3. 能判断 APK 是否被混淆:反编译后看类名/方法名是否大量为 a、b、c 等;若有 mapping.txt 可用来还原符号。
  4. 了解解混淆思路:用 mapping.txt 还原(ProGuard retrace)、用 jadx/Bytecode Viewer 看逻辑、手动根据字符串/调用关系推测原名(仅限授权环境)。

阅读提示 :解混淆、脱壳等仅限授权环境、学习与安全研究;不得对他人应用做未授权逆向或传播脱壳包。

常见疑问:混淆和加壳有啥区别?混淆是「改名字、删未用代码」;加壳是「把 DEX/so 加密或隐藏,运行时再解密」,两者可同时存在。


一、Android 代码混淆是啥?

代码混淆 (Obfuscation)说白了就是:在编译时把类名、方法名、变量名 换成短且无意义的符号 (如 a、b、c),并可能删除未使用代码 ,达到减小 APK 体积提高逆向难度的目的。不会改逻辑,只是名字难读。

为啥要混淆?

  • 防逆向:名字没语义,读代码费劲。
  • 减体积:删未用代码、短名字。
  • 护核心:算法、校验逻辑不易一眼看出。

常见混淆工具一句话

工具 在干啥 是否默认
ProGuard 缩减、重命名、优化 早期默认,现多被 R8 替代
R8 替代 ProGuard,支持 D8 当前默认
DexGuard 商用,加密、动态混淆等 需单独购买
360 加固等 加固 + 混淆,DEX 可能被加密 需单独配置

记一句:混淆 = 改名字 + 删未用代码;和加壳(加密 DEX/so)是两回事。


二、怎么判断 APK 是否被混淆?

在干啥:反编译后看类名、方法名是否大量为 a、b、c 等

jadx 反编译 APK,看 com/xxx/a.javab.java ,方法名 a()b(),若大量这种短名,基本可认为被混淆。

bash 复制代码
jadx -d output/ app.apk
ls output/sources/com/example/

若目录里多是 a.javab.java,且方法名也是 a、b、c,说明已混淆。


三、解混淆一般怎么干?

在干啥:把混淆后的名字还原成可读的类名/方法名,或至少理清逻辑

有 mapping.txt 时 :ProGuard/R8 会生成 mapping.txt ,记录「原名 → 混淆名」的映射,用 proguard-retrace 或 jadx 的 mapping 功能可还原堆栈或符号。

bash 复制代码
# 还原堆栈示例
proguard-retrace mapping.txt stacktrace.txt

没有 mapping.txt 时 :只能靠逻辑推断 ------看字符串、看调用关系、看参数类型,手动给类/方法起「推测名」;或用 Bytecode Viewerjadx 多换几种反编译器看,逻辑不变,名字可读性会不同。

手动还原示例(Smali)

混淆后可能是:

smali 复制代码
.method public b()V
    .locals 1
    const-string v0, "Login Success"
    invoke-static {v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)V
    return-void
.end method

根据字符串 "Login Success" 可推测该方法可能是 checkLoginonLoginSuccess ,在注释或重命名时写成 checkLogin()V 方便后续分析。工具上可用 jadx 的「重命名」功能做标注。


四、加固(如 360)和混淆的区别

在干啥:加固会加密/隐藏 DEX 或 so,运行时再解密;混淆只改名字

混淆 :不加密,只是名字变短、未用代码删除;反编译后仍能看到字节码,只是难读。
加固(加壳) :DEX 或 so 被加密或抽走,直接反编译可能失败或只有壳代码;需要脱壳才能拿到真实 DEX(脱壳见后续「加固与脱壳」相关节)。

若遇到无法直接反编译、或反编译后只有壳类,多半是加固;若反编译正常但满屏 a、b、c,多半是混淆。

记一句:混淆 = 名字难读;加固 = 代码被藏/加密,要脱壳。


本节小结

你只要记住这几条就行:

  1. 混淆 = 类/方法/变量名替换成短符号(a、b、c),减体积、增逆向难度;ProGuard/R8 常用,会生成 mapping.txt
  2. 判断是否混淆:反编译后看类名、方法名是否大量为单字母或短名。
  3. 解混淆 :有 mapping 用 retrace 或 jadx mapping;没有就靠字符串、调用关系手动推断 ;混淆和加壳别混。
  4. 仅限授权、合规环境下分析与解混淆。

本节术语速查

术语 一句话解释
混淆(Obfuscation) 编译时把类/方法/变量名换成短无意义名,减体积、增逆向难度。
ProGuard / R8 常用混淆与缩减工具,R8 为当前默认。
mapping.txt 记录原名与混淆名映射,用于还原堆栈或符号。
加壳/加固 对 DEX/so 加密或隐藏,与混淆不同,需脱壳才能拿到真实代码。

本节思考与练习

  1. 概念:混淆和加壳有啥区别?分别会对反编译结果造成什么影响?
  2. 应用 :若反编译后看到大量 a()b() ,但有一个方法里调用了 Log.d("Login", ...),你会怎么推测这个方法的作用?
  3. 动手 :找一个已混淆的 APK(或自己打一个带 ProGuard 的 release 包),用 jadx 反编译,看类名和方法名,再尝试用 mapping.txt(若有)做一次 retrace 或导入 jadx。
  4. 动手:在同一 APK 里选一个混淆后的类,根据字符串和调用关系,在笔记里给它和主要方法起「推测原名」,体会手动解混淆的过程。

下一节预告 :下一节讲逆向加密算法(MD5、AES、RSA),会介绍这些算法在应用里的用途、如何用 jadx 找加解密逻辑、以及如何用 Frida Hook 拿密钥和明文(仅限授权环境)。

相关推荐
长沙火山1 天前
第二节_如何反编译_APK
逆向·安卓逆向
长沙火山1 天前
第七节_动态调试入门
逆向·安卓逆向
长沙火山1 天前
第十九节_Android_APP_安全机制
逆向·安卓逆向
长沙火山2 天前
第十七节_ELF_文件解析
逆向·安卓逆向
长沙火山2 天前
第十三节_Android_APP_目录结构
逆向·安卓逆向
长沙火山2 天前
第十二节_Android_权限机制
逆向·安卓逆向
长沙火山2 天前
第十六节_反汇编工具介绍
逆向·安卓逆向
长沙火山2 天前
第十一节_Android_进程管理
逆向·安卓逆向
长沙火山2 天前
第九节_Android_CPU_架构解析
逆向·安卓逆向