欢迎光临
我们一直在努力

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

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

(第2章 安卓逆向基础)

学习目标

学完本节,希望你能够:

  • 说出 Android 代码混淆在干啥:把类名、方法名、变量名等替换成短无意义名(如 a、b、c),减小体积、增加逆向难度。
  • 知道常见混淆工具:ProGuard、R8(默认启用)、DexGuard、以及国内加固(如 360)等;混淆和加壳不是一回事。
  • 能判断 APK 是否被混淆:反编译后看类名/方法名是否大量为 a、b、c 等;若有 mapping.txt 可用来还原符号。
  • 了解解混淆思路:用 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.java、b.java,方法名 a()、b(),若大量这种短名,基本可认为被混淆。

    jadx -d output/ app.apk
    ls output/sources/com/example/

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


    三、解混淆一般怎么干?

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

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

    # 还原堆栈示例
    proguard-retrace mapping.txt stacktrace.txt

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

    手动还原示例(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” 可推测该方法可能是 checkLogin 或 onLoginSuccess,在注释或重命名时写成 checkLogin()V 方便后续分析。工具上可用 jadx 的「重命名」功能做标注。


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

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

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

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

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


    本节小结

    你只要记住这几条就行:

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

  • 本节术语速查

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

    本节思考与练习

  • 概念:混淆和加壳有啥区别?分别会对反编译结果造成什么影响?
  • 应用:若反编译后看到大量 a()、b(),但有一个方法里调用了 Log.d(“Login”, …),你会怎么推测这个方法的作用?
  • 动手:找一个已混淆的 APK(或自己打一个带 ProGuard 的 release 包),用 jadx 反编译,看类名和方法名,再尝试用 mapping.txt(若有)做一次 retrace 或导入 jadx。
  • 动手:在同一 APK 里选一个混淆后的类,根据字符串和调用关系,在笔记里给它和主要方法起「推测原名」,体会手动解混淆的过程。
  • 下一节预告:下一节讲逆向加密算法(MD5、AES、RSA),会介绍这些算法在应用里的用途、如何用 jadx 找加解密逻辑、以及如何用 Frida Hook 拿密钥和明文(仅限授权环境)。

    赞(0)
    未经允许不得转载:171主机测评 » 第十四节_Android_代码混淆与解混淆
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址