【Android】Android 代码混淆Obfuscation实践与总结

Android代码混淆与优化:ProGuard/R8实战指南 代码混淆是移动应用安全加固的核心技术,通过语义保留的变换(如命名混淆、控制流混淆)有效提升反编译难度。在Android开发中,ProGuard/R8作为官方工具链,兼具代码压缩与混淆双重功能,能减少20%-50%的APK体积。其工作原理包括Shrinking移除未使用代码、Optimization字节码优化、Obfuscation标识符随机化等关键步骤。典型应用场景涉及保护核心算法、防止二次打包、满足金融类应用安全审计等需求。配置时需特别注意保留反射调用类、Android组件及第三方SDK的特定规则,避免引 阅读详情

对于Android Obfuscation,一直困扰我很久了,很多混淆规则不好记并且容易混淆(概念混淆),有些混淆规则并不能按照字面上去理解。今天在这里手撸每一条规则实践一下,彻底做个总结。

举个例子,比如以下这条规则的含义:

-keep class com.devnn.*

这个规则看上去是保留com.devnn包里的类不被混淆。如果这么简单的理解就说明你对混淆还没有足够的了解。

如果你能肯定地回答以下几个疑问,这篇文章你就不用看了。

  1. com.devnn.model包下的类会被混淆吗?
  2. com.devnn这个包名会被混淆吗?
  3. com.devnn下的类的父类会被混淆吗?
  4. com.devnn下的类的成员变量和方法会被混淆吗?
  5. -keep class com.devnn.*、-keep class com.devnn.**、
    -keep class com.devnn.**{ *;}三者区别是什么?
  6. 如何只混淆包下的类不混淆包的路径?
  7. 如何只混淆包的路径不混淆包下的类?
  8. 如何保留类下的部分方法不被混淆?
  9. -keepclasseswithmembers xxx{xxx;}会保留"members"吗?

带着以上疑问,我们来做一个Demo试一试就知道了。实践才能出真知,凭空想象是站不住脚的。

先建一个名为ObfuscationDemo的工程,随便建两个简单的类:Engineer和Student,它们共同的接口是Person。

目录结构如下:
在这里插入图片描述
Student类:

package com.devnn.model;

import com.devnn.interfaces.Person;

/**
 * create by devnn on 2019-10-14
 */
public class Student implements Person {

    @Override
    public String say() {
        return "I am a student!";
    }

    @Override
    public String work() {
        return "I can wash dishes!";
    }

    @Override
    public String study() {
        return "That's what I am doing!";
    }

}

Engineer类:

package com.devnn.model;

import com.devnn.interfaces.Person;

/**
 * create by devnn on 2019-10-14
 */
public class Engineer implements Person {

    @Override
    public String say() {
        return "I am en engineer!";
    }

    @Override
    public String work() {
        return "I work very hard!";
    }

    @Override
    public String study() {
        return "I do study sometimes!";
    }

}

在Activity里调用一下自定义类,否则会被视为无效代码在打包时被删除:

package com.devnn.obfuscationdemo;

import android.app.Activity;
import android.os.Bundle;

import com.devnn.model.Engineer;
import com.devnn.model.Student;
import com.devnn.test.Test;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        test();
    }

    public void test(){
        System.out.println("test");

        Engineer engineer=new Engineer();
        engineer.say();
        engineer.study();
        engineer.work();

        Student student=new Student();
        student.say();
        student.study();
        student.work();
    }
}

开启混淆:

    buildTypes {
        debug{
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

跑一下assembleDebug命令,生成debug包。

反编译看一下源码:
在这里插入图片描述
发现混淆生效了,使用的是默认的混淆规则。我们发现默认的混淆规则就是按照小写字母表的顺序给包、类、成员重新命名。Activity类名及路径默认不被混淆,Actiivty自定义的成员默认是会被混淆的。

一、混淆规则:-keep class xxx.xxx.*

现在加上第一条混淆规则:-keep class com.devnn.*
在这里插入图片描述
重新assembleDebug一下。反编译后:
在这里插入图片描述
发现跟之前是一样的。

似乎不起作用?

将混淆规则改成-keep class com.devnn.model.*试试。

这次的结果如下:
在这里插入图片描述
这下子就一目了然了。

-keep class com.devnn.model.*的作用是保留com.devnn.mode包下的类名(包括路径)不被混淆,类成员和子包还是会被混淆的

-keep class com.devnn.*因为com.devnn下没有类所以这条规则没有作用。

二、混淆规则:-keep class xxx.xxx.**

下面将混淆代码改成-keep class com.devnn.**看看是什么效果。

结果如下:
在这里插入图片描述
可以看到两颗**表示对com.devnn下的子包的类都保留不被混淆,同时也仅仅是针对类名。

那么我们可以这样理解:

混淆规则的关键字-keep class xxx表示保留xxx这个类(包括路径)不被混淆,类成员和子路径的的类都不影响。

三、混淆规则:-keep class xxx.xxx.**{xxx;}

下面将混淆规则改成:-keep class com.devnn.**{*;}

结果如下:在这里插入图片描述
我们发现,加上{*;}后表示类成员也保留不被混淆。

有时候我们会看到这样的规则:

-keep class com.xxx.xxx.*{
    public <fields>;
    public <methods>;
    *** set*(***);
    *** get*();
 }

那么这个规则也自然很好理解了,就是保留com.xxx.xxx下的类及其public成员和set、get方法不被混淆。

那么如何只保留包名不被混淆,包下的类被混淆呢?

四、混淆规则:-keeppackagenames xxx.xxx.xxx

我们试试:-keeppackagenames com.devnn.model 这条规则。

结果如下:
在这里插入图片描述
我们发现com.devnn.model这个包名确实是被保留了,其它都不受影响。

弄懂了上面的规则,-keeppackagenames com.devnn.* 也就很好理解了,它表示保留com.devnn下的一级包名不被混淆,-keeppackagenames com.devnn.**表示保留com.devnn下的所有包名不被混淆。

验证一下-keeppackagenames com.* 的结果:
在这里插入图片描述
因为没有com.*这样的包,所以以上规则无效。

试一试-keeppackagenames com.**:
在这里插入图片描述
我们发现com开头的包都保留了。

再试试一下-keeppackagenames com.devnn.*:
在这里插入图片描述
我们发现,com.devnn下的两个包都保留了。

五、混淆规则:-keepclasseswithmembers class xxx.xxx.xxx{xxx;}

像-keepclasseswithmembers这样的规则使用得比较少,字面意思是保留持有某种成员的类不被混淆,比如:

-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

它表示main方法所在的类不被混淆,那么main方法会被混淆吗?不知道,试试。

我们在新建一个包名com.devnn.test并在里面建一个MainTest.java的类,完整内容如下:
在这里插入图片描述
我们在混淆文件中只设置一条规则:

-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

打包并查看源码:
在这里插入图片描述
发现main方法以及所在类路径保留了。

为什么main方法保留了呢?难道是因为main方法被特殊处理了?

我们不用mina方法,换成其它名字:
在这里插入图片描述
在MainActivity里面调一下Test.test1方法:

   Test.test1("aaa");

修改一下混淆规则:

-keepclasseswithmembers public class * {
    public static void test1(java.lang.String);
}

打包并查看源码:
在这里插入图片描述
我们发现-keepclasseswithmembers 确实是保留了"classes"和"members"。

是不是似乎有某种相似?那其实以下两种规则的作用是一样的?

-keepclasseswithmembers public class * {
    public static void test1(java.lang.String);
}
-keep class com.** {
    public static void test1(java.lang.String);
}

实践一下,我们试试将混淆规则改成上面第二种,查看结果:
在这里插入图片描述
我们发现这两种规则的作用并不是一样的。

-keepclasseswithmembers public class * {
    public static void test1(java.lang.String);
}

上面这条规则是必须匹配到包含有 public static void test1(java.lang.String);这个方法的类,保留保含此方法的类和此方法不被混淆。

-keep class com.** {
    public static void test1(java.lang.String);
}

这条规则是即使没有找到 public static void test1(java.lang.String);这个方法,也照样保留类不被混淆(类成员还是会被混淆)。

六、混淆规则:-keepclassmembers class xxx.xxx.xxx{xxx;}

下面将混淆规则改成:

-keepclassmembers class com.** {
    public java.lang.String say();
}

打包并查看源码:
在这里插入图片描述
发现除了say()方法保留了,其它内容都被混淆了。-keepclassmembers xxx.xxx.xxx(xxx)作用就是保留某些成员不被混淆,其它都被混淆。

经过以上实践,我们应该对
-keep class com.xxx.*、
-keep class com.xxx.**、
-keep class com.xxx.**{xxx;}、
-keeppackagenames xxx.*、
-keeppackagenames xxx.**、
-keepclasseswithmembers public class * {xxx;}、
-keepclassmembers xxx.xxx.xxx{xxx;}
这些混淆规则有深刻的认识了。

安卓逆向工程实战:从混淆代码中定位与修改手游内购逻辑 在安卓应用开发中,代码混淆是保护应用逻辑和知识产权的重要手段,它通过重命名类、方法和变量名来增加逆向分析的难度。其原理在于将可读的代码标识符替换为无意义的短字符,同时可能结合优化和压缩技术。这项技术的核心价值在于提升应用安全性,防止核心算法和业务逻辑被轻易窃取或篡改。在移动安全、软件保护等应用场景下,混淆是开发者必备的防御措施。然而,对于安全研究人员或学习逆向技术的开发者而言,分析混淆后的代码是一项关键技能。本文聚焦于如何利用AndroidKiller和JADX等工具,通过静态分析定位混淆代码中的关键逻辑, 阅读详情

相关推荐

Unity代码混淆实战:Obfuscator Pro配置与避坑指南

代码混淆是一种通过改变代码结构和形式,使其难以被逆向工程分析的技术手段。其核心原理在于保持程序原有功能不变的前提下,对标识符重命名、打乱控制流、加密字符串等,从而增加代码的理解难度。这项技术在保护知识产权、防止算法泄露方面具有重要价值,尤其适用于游戏开发、商业软件等需要分发客户端的场景。在Unity移动游戏开发中,代码混淆常与IL2CPP编译后端结合使用,以应对反编译工具对C# DLL的静态分析。本文基于Obfuscator Pro这一深度集成Unity的工具,详细解析如何配置序列化字段排除、控制流混淆等关

weixin_30457551的博客 509

Android混淆之ProGuard

文章目录初识ProGuardProGuard详解什么在压缩?什么是混淆?反射混淆选项非keep选项keep选项class_specificationProGuard其他需要注意的事项一份通用的ProGuard混淆文件 初识ProGuard Android开发的小伙伴们都或多或少的接触过混淆,很多人都对混淆很困惑。需要发版的时候,从网上load一份混淆文件,或从其他项目中拷贝一份过来,修改一下,管用...

milanac007的专栏 1650

MacOS蓝牙连接疑难杂症:从基础排查到高级修复全攻略

本文提供了一份全面的MacOS蓝牙故障排查与修复指南。从基础的菜单栏检查、终端命令诊断,到软/硬重启蓝牙服务、删除配置文件,再到使用blueutil工具、重置NVRAM等高级方法,系统性地解决了蓝牙无法连接、连接不稳定等常见问题。最后还分享了环境干扰排查、预防措施及硬件故障自检方法,帮助用户彻底解决Mac蓝牙连接难题。

weixin_29271263的博客 450

Android Proguard 如何混淆package name

一、在Android 的proguard-project.txt 文件里我们可以看到如下选项: http://proguard.sourceforge.net/manual/usage.html#keeppackagenames   -keeppackagenames [package_filter] Specifies not to obfuscate the given pac

我的专栏 7115

施耐德 Modicon M580 ePAC 项目实战:从硬件选型到 Control Expert V15 组态

本文详细解析了施耐德 Modicon M580 ePAC 在工业自动化项目中的实战应用,从硬件选型到 Control Expert V15 组态的全流程。重点介绍了水处理站控制系统的硬件配置、网络架构设计、软件安装授权及程序框架开发,帮助工程师高效实施中大型控制系统项目。

weixin_33701617的博客 326

S4 HANA 1809+折旧过账(AFAB/AFABN)凭证行数据存储逻辑变迁:从BSEG到ACDOCA的深度解析

本文深度解析了S4 HANA 1809+版本中折旧过账(AFAB/AFABN)凭证行数据存储逻辑的变迁,从传统的BSEG表迁移到ACDOCA表。文章详细探讨了这一变更的技术背景、官方设计意图及实际影响,包括数据存储量减小和系统性能提升等优势。同时提供了升级项目的应对策略和最佳实践建议,帮助用户顺利过渡到新的数据存储模型。

weixin_28731223的博客 293

Proguard的Keep使用方法

java代码存在互相引用的关系,构成一个网状关系.(个人理解)引用又分为两种:普通引用和字符串引用(例如反射,native方法等).而java代码的执行入口点必然是采用的字符串引用(例如main等方法),因为外部想要执行此代码必须知道一个明确的入口点名字..Proguard流程

wyzzgo的技术博客 1万+

UE5游戏逆向实战:用FModel提取.pak文件中的3D模型(附Dumper-7避坑指南)

本文详细介绍了如何使用FModel工具从UE5游戏的.pak文件中提取3D模型,并提供了Dumper-7的避坑指南。内容涵盖FModel工具链配置、UE5特有的unversioned properties问题解决方案、Dumper-7实战流程以及模型后处理技巧,帮助开发者高效获取游戏资产。

weixin_30872499的博客 422

深入 Android 混淆实践:ProGuard 通关秘籍

使用 Java 编写的源代码在编译时会生成 CLASS 文件,而 CLASS 字节码的规则非常的标准,按照对应的格式能够很好的反编译出原代码。市面上也存在很多很好用的工具,来帮助我们进行反编译并阅读 CLASS 中的代码逻辑。为了更好的保护代码安全,混淆是最容易做的一件事情。针对 Java 的混淆,有一个开源项目 ProGuard 就是常用的混淆工具。它可以对代码进行 压缩、优化 、混淆。本文将基...

大罗说事 3353

BF8815A

了解ADBMS1818芯片的人会发现,这款BF8815B和1818有着很多相似的东西,当你了解其中一款AFE之后,另一款你的上手也会特别快,下面文章是我针对1818梳理的一些重要知识点,此篇文章主要讲解BF8815B的一些差异点。

m0_61973119的博客 561

lammps 案例in文件汇总

进阶案例: 聚乙烯和石墨烯界面pull out模拟代码 反应力场reax/c设置方法及案例解析 石墨烯热导率模拟代码(NEMD方法) 圆锥形SiC纳米磨削单晶硅源代码 高熵合金FeNiCrCoCu纳米压痕模拟代码 fix indent命令实现纳米摩擦及摩擦力计算 Fe原子辐照轰击多层石墨烯模拟代码 铝基石墨烯复合物压缩变形in文件源代码 石墨烯自动卷曲到Fe纳米线模拟源代码 铝/石墨烯复合物结晶过程lammps模

lammps_jiayou的博客 9444

Android 代码混淆问题

一般Android项目,如果不想被反编译查看源码的话,这就需要我们去做一些安全措施;最基础的便是代码混淆。然而代码混淆并不能使程序绝对的安全,但是用来防止一些非专业的人足够了。  混淆处理的命令      1) 保持不混淆 -keep class 或 -keep public class xx.xx.类名,如             -keep public cl

shenzhongaboluo的博客 796

作物生长模型Oryza V3实战10:运行文件参数详解

运行文件(.rer)用于批量模拟农业场景,包含多组参数集(Rerunset),每组设定独立的时间范围、灌溉施肥方案等,支持测试不同农艺措施效果。该文件可实现参数自动校准,通过多组参数组合迭代寻找最优值。模拟结果文件(res.dat)会记录全部测试时间段的数据,便于用户对比产量、水分利用率等指标,筛选最优方案或分析气候适应性策略。

209

Paranoid核心组件揭秘:Deobfuscator与Obfuscation Seed深度解析

Paranoid作为一款专为Android应用打造的字符串混淆工具,其核心组件Deobfuscator与Obfuscation Seed在保障应用安全方面发挥着关键作用。本文将带您深入了解这两大组件的工作原理与实现细节,助您轻松掌握Android字符串混淆的核心技术。 ## Deobfuscator:字符串还原的幕后功臣 Deobfuscator是Paranoid实现字符串动态还原的核心类,它

gitblog_00557的博客 1073

Open3D 读取、保存、显示点云【2025最新版】

paint_uniform_color给所有的点上一个统一的颜色。博客长期更新,本文最近更新时间为:2025年1月1日。

点云侠的博客 37万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Android 混淆其实很简单

简介 在 Android 打出正式的 APK 安装包时,通常为了增加别人反编译后阅读源代码的难度,需要做一些混淆工作。在 Android Studio 中配合 Gradle 很容易完成这个操作。 Proguard 作用 压缩 Shrinking : 默认是开启的,移除未被使用的类和成员,并且在 优化Optimization **工作执行后还会再次执行。 优化 Optimization ...

Star的博客 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

使用 obfuscation 代码混淆保护你的 Flutter 应用程序

本文将会和大家说下保护代码的重要性,和如何给程序加上混淆编译功能。 尽可能的不要在你的程序中写死各种服务秘钥,比如 oss 容易被盗用。

会煮咖啡的猫咪 1371

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Android系统源码代码混淆

前言 刚好有个项目需要提供apk给客户,所以需要对该apk进行代码混淆。在此将遇到的坑记录下来,避免后续再踩。 代码混淆 代码混淆主要是增加“不法分子“对apk进行反编译后,阅读代码的难度。代码混淆并不是所有的代码都可以混淆,有些代码则是不能混淆的,如一些反射应用。 开启混淆 这里记录遇到的第一个坑,在apk的Android.mk文件中,增加如下语句: LOCAL_PROGUARD_ENABLED...

u010456460的博客 1913

Flutter应用安全保护:代码混淆的重要性与Android/iOS混淆步骤详解

通过讲解Flutter代码混淆的重要性、逆向工程演示以及具体在Android和iOS项目中的混淆配置,本文提供了全面的混淆指南。此外,还介绍了专业工具IpaGuard,用于进一步保护iOS IPA文件,增强应用安全。

2501_91592143的博客 457

android 怎么混淆代码,Android如何混淆代码

我们不得不面临一个问题,写出来的代码,被别人反编译过来 直接可以使用,那么我们如何有效的防止这种局面呢?android 引入了Proguard,Proguard 是Android tools包中提供用来对代码进行压缩,优化和进行混淆的工具,它能够移除无用的代码,对类名,方法名,字段名进行重命名,但不改变代码的结构,从而达到对代码混淆的作用。而这样做的好处是我们可以得到一个更小的apk文件和一份更难...

weixin_29356575的博客 416

【代码安全】浅谈安卓开发代码混淆技术

随着移动互联网的快速发展,应用的安全问题不断涌现出来,于是越来越多的应用开发者将核心代码由java层转到native层,以对抗成熟的java逆向分析工具,然而如果native层的代码如果没有进行任何保护,还是比较容易被逆向分析工作者获取其运行逻辑,进而完成应用破解或者进行其他的操作。今天我们就来介绍一种有效对抗native层代码分析的方法——代码混淆技术。

YAQSecurity的博客 1220

Android代码混淆实战:ProGuard配置与优化技巧

代码混淆是Android应用安全加固的核心技术,通过重命名类名、方法名等标识符,有效防止反编译和逆向工程。ProGuard作为官方推荐工具,集成了代码压缩、优化和混淆功能,能显著减小APK体积并提升安全性。在工程实践中,合理的ProGuard配置可解决第三方库兼容性、资源ID冲突等典型问题,特别适用于金融、电商等对安全性要求较高的应用场景。通过结合mapping文件管理和CI/CD集成,可以构建持续可靠的混淆体系。本文以电商App优化案例为基础,详解如何通过-keep规则保留关键类,使用增量混淆提升大型项目

weixin_33747129的博客 407

Android代码混淆终极指南:ProGuard与R8使用详解

在Android应用开发中,代码混淆是保护应用安全、优化应用性能的关键步骤。ProGuard和R8作为Android平台上最主流的代码混淆工具,能够有效防止反编译、缩减应用体积、提升运行效率。本文将为初学者详细解析如何使用ProGuard和R8进行Android代码混淆。🎯 ## 什么是代码混淆?为什么需要它? 代码混淆是一种通过重命名类、方法、变量等标识符,使代码难以被反编译和理解的技术。

gitblog_00995的博客 495

Obfuscapk技术深度解析:Android应用黑盒混淆架构设计与企业级安全防护实践

Obfuscapk是一款基于Python的Android应用黑盒混淆工具,采用模块化插件架构,无需源代码即可对APK文件实施多层次代码混淆与资源保护。该工具通过Yapsy插件系统实现高度可扩展性,支持21种混淆技术分类,涵盖重命名、加密、代码重构等核心防护机制,为移动应用安全提供企业级解决方案。 ## 技术架构设计原理 ### 模块化插件系统架构 Obfuscapk采用基于Yapsy的插件系

gitblog_00677的博客 635

5分钟掌握Obfuscapk:彻底告别Android应用反编译风险的专业级混淆方案

你是否曾经担心自己开发的Android应用被轻易反编译,核心逻辑被竞争对手一览无余?或者你的应用因为缺乏保护措施,在应用商店中面临被破解和盗版的风险?在当前的移动应用安全环境下,APK保护已经成为每个开发者必须面对的重要课题。 Obfuscapk正是为解决这些痛点而生的专业级Android应用混淆工具。作为一个黑盒操作的自动混淆系统,它能够在无需源代码的情况下,为你的APK文件添加多层防护,有效

gitblog_01419的博客 829

ProGuard入门教程:10分钟学会Android应用混淆与优化

ProGuard是Java和Android开发中不可或缺的代码优化与混淆工具,它通过四个核心步骤让您的应用程序变得更小、更快、更安全。无论您是Android开发者还是Java开发者,掌握ProGuard都是提升应用性能和安全性的关键技能。 ## 什么是ProGuard?🤔 ProGuard是一个开源工具,专门用于Java字节码的**压缩**、**优化**、**混淆**和**预验证**。在An

gitblog_00928的博客 1072
上一篇: 【Dart】Dart语言中常量final和const关键字详解(跟Java对比)
下一篇: 【flutter】A RenderFlex overflowed by xxx pixels on the right
devnn
博客等级 码龄12年 2005粉丝 90原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值