安卓项目混淆详解

官网的介绍是:

ProGuard是一个免费的Java类文件缩小,优化,混淆和预验证的工具。

它检测和删除未使用的类,字段,方法和属性;

优化字节码并删除未使用的指令;

它使用短的无意义的名称重命名剩余的类,字段和方法。所得到的应用程序和库更小,更快,并且更好地针对逆向工程进行优化。

而且Proguard已经集成在Android studio构建系统里了,可以通过简单的代码来实现构建apk的时候进行混淆打包。

Android SDK 本身就提供混淆的功能,将混淆开关进行开启后,开发者需要做的是对Android Studio工程项目中的proguard-rules.pro文件进行混淆白名单的配置。即我们要保留哪些不被混淆,不能被混淆。

官网地址:https://developer.android.google.cn/studio/build/shrink-code.html

使用介绍


Proguard使用,我们需要在项目里的build.gradle文件里配置Proguard。

buildTypes {

release {

shrinkResources true

minifyEnabled true

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’

}

}

getDefaultProguardFile(‘proguard-android.txt’) 方法可从 Android SDK tools/proguard/ 文件夹获取默认 ProGuard 设置。

提示:要想做进一步的代码压缩,可尝试使用位于同一位置的 proguard-android-optimize.txt 文件。它包括相同的 ProGuard 规则,但还包括其他在字节码一级(方法内和方法间)执行分析的优化,以进一步减小 APK 大小和帮助提高其运行速度。

shrinkResources 是去除无效的资源文件,压缩资源。

minifyEnabled 是开启混淆。

这是默认的Proguard配置,proguard-rules.pro是需要在你的项目里创建的文件,层级跟build.gradle文件一样的,当然你可以随意改他的文件名,只不过需要在配置代码里面跟着修改,其实这个文件就是Proguard的自定义配置文件,没有这个文件你构建是会报错的。

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’

如果你希望在不通的渠道版本里使用不同的ProGuard 规则,那就在相应的 productFlavor 代码块中再添加一个 proguardFiles 属性。例如,以下 Gradle 文件会向 flavor2 产品风味添加 flavor2-rules.pro。现在 flavor2 使用所有三个 ProGuard 规则,因为还应用了来自 release 代码块的规则。

android {

buildTypes {

release {

shrinkResources true

minifyEnabled true

proguardFiles getDefaultProguardFile(‘proguard-android.txt’),‘proguard-rules.pro’

}

}

productFlavors {

flavor1 {

}

flavor2 {

proguardFile ‘flavor2-rules.pro’

}

}

}

每次构建时 ProGuard 都会输出下列文件:

dump.txt //说明 APK 中所有类文件的内部结构。

mapping.txt //提供原始与混淆过的类、方法和字段名称之间的转换。

seeds.txt //列出未进行混淆的类和成员。

usage.txt //列出从 APK 移除的代码。

这些文件保存在 /build/outputs/mapping/release/。

Proguard基本语法


-dontwarn dontwarn是一个和keep可以说是形影不离,尤其是处理引入的library时

-keep 不混淆类和成员或者被重命名

-keepnames 保留类和类中的成员,防止被混淆或移除

-keepclassmembers 只保留类中的成员,防止被混淆,成员没有引用会被移除

–keepclassmembernames 只保留类中的成员,防止被混淆,成员没有引用会被移除

-keepclasseswithmembers 保留类和类中的成员,防止被混淆或移除,保留指明的成员

-keepclasseswithmembernames 保留类和类中的成员,防止被混淆,保留指明的成员,成员没有引用会被移除

而且还支持通配符*

例如

不混淆某个类

-keep public class com.xx.xx.xx { *; }

不混淆某个包

-keep public class com.xx.xx.** { *; }

不混淆某个类的子类

-keep public class * extends com.xx.xx { *; }

基本规则


//不混淆某个类

-keep public class com.xx.xx.mi{ *; }

//不混淆某个类的子类

-keep public class * extends com.xx.xx.mi { *; }

//不混淆所有类名中包含了“model”的类及其成员

-keep public class .model. {*;}

//不混淆某个接口的实现

-keep class * implements com.xx.xx.TestInterface { *; }

//不混淆某个类的构造方法

-keepclassmembers com.xx.xx.example.Test {

public ();

}

//不混淆某个类的特定的方法(不混淆mi这个类下的test方法)

-keepclassmembers class com.xx.xx.mi{

public void test(java.lang.String);

}

//不混淆某个类的内部类

-keep class class com.xx.xx.mi$* {

*;

}

//两个常用的混淆命令,注意:

//一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;

//两颗星表示把本包和所含子包下的类名都保持;

-keep class com.suchengkeji.android.ui.**

-keep class com.suchengkeji.android.ui.*

//用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,

//如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了

//不混淆某个包所有的类

-keep class com.xx.xx.bean.** { *; }

//在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下

保留我们使用的四大组件,自定义的Application等等这些类不被混淆

因为这些子类都有可能被外部调用

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Appliction

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class * extends android.app.backup.BackupAgentHelper

-keep public class * extends android.preference.Preference

-keep public class * extends android.view.View

-keep public class com.android.vending.licensing.ILicensingService

libs下的第三方Jar包的混淆方式

保留libs下的jar包的方式也很简单,同样是使用-keep关键字:找到libs目录,打开相对于的jar文件,找到对应的包名,然后添加如下代码:

-keep class 包名.** { *; }

complie的第三方Jar包的混淆方式complie的第三方Jar包的混淆方式和libs下的相同,只需要打开:打开对应的引用jar文件,然后同样使用

-keep class 包名.** { *; }

保留代码


Android SDK 本身就提供混淆的功能,将混淆开关进行开启后,开发者需要做的是对Android Studio工程项目中的proguard-rules.pro文件进行混淆白名单的配置.

那么什么是混淆白名单呢?其实就是指定一些包名、类名、变量等不可以被混淆。假设没指定白名单就进行混淆打包,而某某类的类名被混淆了(假设变成了a),那么可能其他引用或使用该类的类就找不到该类,说不定应用就会因此崩溃或是导致相应的功能无法使用.


一般这些都需要保留代码不被混淆:

使用了自定义控件那么要保证它们不参与混淆

使用了枚举要保证枚举不被混淆

对第三方库中的类不进行混淆

运用了反射的类也不进行混淆

使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆

在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找

有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆,原因和第一条一样

Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常

使用的四大组件,自定义的Application* 实体类

JNI中调用的类

Layout布局使用的View构造函数(自定义控件)、android:onClick等。

与js互调的类,工程中没有直接跳过。一般你可以这样写

-keep class 你的类所在的包.** { *; }

如果是内部类的话,你可以这样

-keepclasseswithmembers class 你的类所在的包.父类$子类 { ; }

例如:

-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {

;

}

与反射有关的类,工程中没有直接跳过。类的话直接这样

-keep class 你的类所在的包.** { *; }

通用基础配置


以下是在项目里常使用的配置,再加上你需求混淆的第三方即可。

//— 基础混淆配置区 —

//指定代码的压缩级别

-optimizationpasses 5

//优化时允许访问并修改有修饰符的类和类的成员

-allowaccessmodification

//不使用大小写混合

-dontusemixedcaseclassnames

//指定不去忽略非公共库的类

-dontskipnonpubliclibraryclasses

//混淆时是否记录日志

-verbose

//忽略警告,避免打包时某些警告出现,没有这个的话,构建报错

-ignorewarnings

//不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。

-dontpreverify

//过滤泛型 出现类型转换错误时,启用这个

-keepattributes Signature

//抛出异常时保留代码行号 方便测试

-keepattributes SourceFile,LineNumberTable

//混淆时所采用的算法

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/,!class/merging/

//— Android开发中一些需要保留的公共区 —

//不混淆注解相关

-keepattributes Annotation

#表示不混淆任何包含native方法的类的类名以及native方法名,这个和我们刚才验证的结果是一致

-keepclasseswithmembernames class * {

native ;

}

//保持枚举 enum 类不被混淆

-keepclassmembers enum * {

public static **[] values();

public static ** valueOf(java.lang.String);

}

//不混淆Parcelable

-keep class * implements android.os.Parcelable {

public static final android.os.Parcelable$Creator *;

}

//不混淆Serializable

-keep class * implements java.io.Serializable {*;}

-keepnames class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {*;}

//— 不能被混淆的基类 —

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Fragment

-keep public class * extends android.app.Application

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class * extends android.app.backup.BackupAgentHelper

-keep public class * extends android.preference.Preference

-keep public class * extends android.view.View

-keep class org.xmlpull.v1.** { *; }

//不混淆我们自定义控件(继承自View)

-keep public class * extends android.view.View{

*** get*();

void set*(***);

public (android.content.Context);

public (android.content.Context, android.util.AttributeSet);

public (android.content.Context, android.util.AttributeSet, int);

}

//不混淆R文件

-keepclassmembers class *.R$ {

public static ;

}

//— 不混淆android-support-v4包 —

-dontwarn android.support.v4.**

-keep class android.support.v4.** { *; }

-keep interface android.support.v4.app.** { *; }

-keep class * extends android.support.v4.** { *; }

-keep public class * extends android.support.v4.**

-keep public class * extends android.support.v4.widget

结尾

我还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

image
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

public static ;

}

//— 不混淆android-support-v4包 —

-dontwarn android.support.v4.**

-keep class android.support.v4.** { *; }

-keep interface android.support.v4.app.** { *; }

-keep class * extends android.support.v4.** { *; }

-keep public class * extends android.support.v4.**

-keep public class * extends android.support.v4.widget

结尾

我还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

[外链图片转存中…(img-3r9kZ77G-1715256241660)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
This asset obfuscates your code to make it harder for bad guys to reverse engineer your projects. Specifically designed for Unity, it seamlessly links in with its build process. The top priority of this package is to work straight out of the box with no extra steps required. While other obfuscators can stop a game from working, Beebyte's obfuscator looks for specific Unity related code that must be protected. The contents of your source files are unchanged, the obfuscation targets the compiled assembly. Features: - Supports IL2CPP - Supports Assembly Definition Files (Unity 2017.3+) - Removes Namespaces without any conflicts - Recognises Unity related code that must not be changed - Renames Classes (including MonoBehaviours†) - Renames Methods - Renames Parameters - Renames Fields - Renames Properties - Renames Events - String literal obfuscation - Adds fake methods - Easy and extensive customisation using the Unity inspector window - Consistent name translations are possible across multiple builds and developers - Semantically secure cryptographic naming convention for renamed members The asset works for both Unity Free and Unity Pro version 4.2.0 onwards (including Unity 5 & 2017 & 2018). Build targets include Standalone, Android, iOS, WebGL, UWP. Other platforms are not guaranteed or supported but may become supported at a future date. † There is currently a bug with renaming MonoBehaviour classes on Unity 2018.2. A bug report has been submitted to Unity. IL2CPP builds are much harder to reverse engineer but strings and member information (class, method names etc) are visible in the global-metadata.dat file. Obfuscation will apply to this file adding further security. Why not complement your security with the Anti-Cheat Toolkit - a great third party asset. For more information about the Obfuscator, please see the FAQ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值