Android APP代码混淆proguard和加固

2024-02-24 05:32

本文主要是介绍Android APP代码混淆proguard和加固,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android APP代码混淆proguard和加固

    proguard官方网址:http://proguard.sourceforge.net/index.html#/manual/examples.html


 一、在gradle中开启:

Gradle项目(以及Android Studio)

在build.gradle中进行配置

android {
    buildTypes {
        release {  

           minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
            //proguardFile 'some-other-rules.txt'  配置单个文件这样
        }
    }
}

如上面代码所示,我们可以使用rminifyEnabled true开启,并且对其配置混淆配置,可以配置多个文件或单个文件。

android的sdk中已经为我们提供了两个默认的配置文件,我们可以拿过来进行使用,proguard-android.txt和proguard-android-optimize.txt。

二、proguard主要三部分功能

   缩减代码、优化代码、混淆代码。三部分功能都可以在配置文件里配置不启用此功能(其实还有预校验的功能不过android官方不建议开启)。

#Shrink Options

#不缩减代码
-dontshrink

#Optimization Options

#不优化代码
-dontoptimize

 

#Obfuscate Options 
#-不混淆输入的类文件 
-dontobfuscate 

 

 

三、用法

1.保留选项(配置不进行处理的内容)

-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员(类的属性),如果此类名受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们没在压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

-keep用法区别

1)保留某个类名不被混淆

-keep public classcom.ebt.app.common.bean.Customer

2)保留类及其所有成员不被混淆

-keep public classcom.ebt.app.common.bean.Customer { *;}

或者
-keepclasseswithmembers class com.ebt.app.common.bean.Customer {

    <init>;#匹配所有构造函数

    <fields>;#匹配所有成员
    <methods>;#匹配所有方法
}

3)只保留类名及其部分成员不被混淆

-keep public classcom.ebt.app.common.bean.Customer { 

    static final<fields>;

    private void get*();

}

4)#保留包路径下所有的类及其属性和方法
-keep class com.ebt.app.sync.** { *;}

2.压缩

-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}

3.优化

-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

4.混淆

-dontobfuscate 不混淆输入的类文件
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable,LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, andInnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量

后面的文件名,类名,或者包名等可以使用占位符代替
?表示一个字符
可以匹配多个字符,但是如果是一个类,不会匹配其前面的包名
* 可以匹配多个字符,会匹配前面的包名。

在android中在android Manifest文件中的activity,service,provider, receviter,等都不能进行混淆。一些在xml中配置的view也不能进行混淆,android提供的默认配置中都有。

5..缺省情况下,proguard 会混淆所有代码,但是下面几种情况不能改变类名和方法名。
a.我们用到反射的地方。

b.我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。
c.在配置文件manifest中配置的。

6.对出现问题的类的处理。遇见一个及添加。

7.常见*的用法区别(一般情况下用不到,非必须了解)

修饰类、接口、枚举等时

*       matchesany part of a class name not containing the package separator. For example,"mypackage.*Test*" matches "mypackage.Test" and"mypackage.YourTestApplication", but not"mypackage.mysubpackage.MyTest". Or, more generally, "mypackage.*"matches all classes in "mypackage", but not in its subpackages.

**     matchesany part of a class name, possibly containing any number of package separators.For example, "**.Test" matches all Test classes in all packagesexcept the root package. Or, "mypackage.**" matches all classes in"mypackage" and in its subpackages.

   修饰构造函数、成员变量、方法

Fields and methods are specified much likein Java, except that method argument lists don't contain argument names (justlike in other tools like javadoc and javap). The specifications can alsocontain the following catch-all wildcards:

<init>        matches any constructor.

<fields>    matches any field.

<methods>       matches any method.

*       matchesany field or method.

Note that the above wildcards don't havereturn types. Only the <init> wildcard has an argument list.

Fields and methods may also be specifiedusing regular expressions. Names can contain the following wildcards:

?       matchesany single character in a method name.

*       matchesany part of a method name.

Types in descriptors can contain thefollowing wildcards:

%      matchesany primitive type ("boolean", "int", etc, but not"void").

?       matchesany single character in a class name.

*       matchesany part of a class name not containing the package separator.

**     matchesany part of a class name, possibly containing any number of package separators.

***  matchesany type (primitive or non-primitive, array or non-array).

...     matchesany number of arguments of any type.

Note that the ?, *, and ** wildcards willnever match primitive types. Furthermore, only the *** wildcards will matcharray types of any dimension. For example, "** get*()" matches"java.lang.Object getObject()", but not "float getFloat()",nor "java.lang.Object[] getObjects()".

Constructors can also be specified usingtheir short class names (without package) or using their full class names. Asin the Java language, the constructor specification has an argument list, butno return type.

The class access modifiers and class memberaccess modifiers are typically used to restrict wildcarded classes and classmembers. They specify that the corresponding access flags have to be set forthe member to match. A preceding ! specifies that the corresponding access flagshould be unset.

Combining multiple flags is allowed (e.g.public static). It means that both access flags have to be set (e.g. public andstatic), except when they are conflicting, in which case at least one of themhas to be set (e.g. at least public or protected).

ProGuard supports the additional modifierssynthetic, bridge, and varargs, which may be set by compilers.

四、Proguard的输出文件及reTrace跟踪

 混淆之后,会给我们输出一些文件,在gradle方式下是在<project_dir>/build/proguard/目录下,ant是在<project_dir>/bin/proguard目录,eclipse构建在<project_dir>/proguard目录像。
分别有以下文件:
+ dump.txt 描述apk文件中所有类文件间的内部结构。
+ mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
+ seeds.txt 列出了未被混淆的类和成员
+ usage.txt 列出了从apk中删除的代码

当我们发布的release版本的程序出现bug时,可以通过以上文件(特别时mapping.txt)文件找到错误原始的位置,进行bug修改。同时,可能一开始的proguard配置有错误,也可以通过错误日志,根据这些文件,找到哪些文件不应该混淆,从而修改proguard的配置。

    注意:重新release编译后,这些文件会被覆盖,所以没吃发布程序,最好都保存一份配置文件。

调试Proguard混淆后的程序

上面说了输出的几个文件,我们在改bug时可以使用,通过mapping.txt,通过映射关系找到对应的类,方法,字段等。

ProGuard 提供了命令行和 GUI 工具来还原混淆后的代码,可以将一个被混淆过的堆栈跟踪信息还原成一个可读的信息。
该工具位于  <android-sdk>/tools/proguard/bin/ 目录下。
里面的 proguardgui.bat 为 GUI 工具,

1) 运行 proguardgui.bat
2) 从左边的菜单选择  “ReTrace”
3) 在上面的 mapping 文件中选择你的 mapping 文件 ,在下面输入框输入要还原的代码
4) 点击 “ReTrace!” 按钮

命令行:window下时retrace.bat,linux和mac是retrace.sh,在<sdk_root>/tools/proguard/文件夹下。语法为:

    retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]

例如:

retrace.bat -verbose mapping.txt obfuscated_trace.txt

如果你没有指定<stacktrace_file>,retrace工具会从标准输入读取。


   

五、其他关于Proguard的问题

1.开启optimization导致的问题。有时候为了在release版本中去除log打印,配置
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
此时必须开启优化,但是这样可能会引入更大的问题: http://www.itnose.net/detail/6043297.html而在我的项目中则打包都成功不了,提示说Tencent微博SDK引用的httpclient出问题,找不到父类。结论是:要是你不是proguard高手,就关闭优化吧。
2proguarnd后反编译代码,使用一些工具还能看到真身的影子,如: http://www.tuicool.com/articles/vUB3EnM
-keepattributes SourceFile,LineNumberTable
表示的是java文件的各种文件属性,如果这个被keep了,果断去掉。
3.中文的各个参数的解释,准确性本人不能把握 http://www.2cto.com/kf/201604/497739.html

六、美团Android资源混淆保护实践

 网址:http://tech.meituan.com/mt-android-resource-obfuscation.html

七、第三方加固

大家请百度

这篇关于Android APP代码混淆proguard和加固的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741080

相关文章

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时