Android代码混淆方法,Android 代码混淆零基础入门

内容提要

本篇文章主要有三个部分,让读者读完后能自己写规则混淆项目

对Android代码怎么开启混淆做一个简单的介绍。

对混淆规则做一个简单介绍;

在混淆过后Crash日志反推代码工具retrace.bat、可视化反推工具GUI说明。

对混淆的一个简单介绍:

Android SDK 自带了混淆工具Proguard。它位于SDK根目录\tools\proguard下面。如果开启了混淆,Proguard默认情况下会对所有代码,包括第三方包都进行混淆,可是有些代码或者第三方包是不能混淆的,这就需要我们手动编写混淆规则来保持不能被混淆的部分。

混淆有几个作用:

【优化】它能优化java的字节码,使程序运行更快;

【压缩】最直观的就是减少App大小,在混淆过程中它会找出未被使用过的类和类成员并删除他们;

【混淆】这个功能使我们的java代码中的类、函数、变量名随机变成无意义的代号形如:a,b,c...之类的,即使我们的APP即使被反编译,也不容易理解了。

上面这几个功能都是默认打开的,要关闭他们只需配置规则:

-dontshrink :关闭压缩;

-dontoptimize:关闭优化;

-dontobfuscate:关闭混淆。

写在开始之前:

本编使用Android Studio工具作为开发环境,Eclipse类似;

Android Studio新建项目时会在项目根目录下自动生成一个混淆配置文件:

proguard-rules.pro;【Eclipse 下面的文件名为:proguard.cfg或者proguard.txt】里面的内容规则都是一样的;

1.现在开始混淆:

第一步:开启混淆,编辑项目配置文件build.gradle(Module: app)

*** minifyEnabled true;这个选项的意思为开启混淆;

*** proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro';//配置文件**

'proguard-android.txt' 是AndroidStudio默认自动导入的规则,这个文件位于Android SDK根目录\tools\proguard\proguard-android.txt。这里面是一些比较常规的不能被混淆的代码规则。'proguard-rules.pro'是针对我们自己的项目需要特别定义混淆规则,它位于项目根目录下面,里面的内容需要我们自己编写

zipAlignEnabled true 这个在打包时需要设置为true,能优化我们的java字节码,提高运行效率;

build.gradle编辑完成后如下图所示:(表示发布的release包,会按照指定规则来进行混淆)

android {

compileSdkVersion 23

buildToolsVersion "24.0.1"

defaultConfig {

}

buildTypes {

release { //主要看这部分:

zipAlignEnabled true

minifyEnabled true

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

}

}

....

}

第二步:现在就可以开始编辑自己的规则了

下面是一个比较简单的proguard-rules.pro文件内容,做完这些就可以打包发布版本了

86ee6ef970ef

1.png

将混淆过的APK反编译,你会发现里面的代码变成了a、b、c之类的没有意义的代号了,而且APK也变小了。

2.重点来了【规则介绍】

现在对混淆规则做一个介绍:

先来看一看Android studio 默认包含的规则文件(proguard-android.txt 文件)里面的类容,我们选出几个重点说明:

#混淆时不生成大小写混合的类名

-dontusemixedcaseclassnames

#不忽略非公共的类库

-dontskipnonpubliclibraryclasses

#混淆过程中打印详细信息

-verbose

#关闭优化

-dontoptimize

#不预校验

-dontpreverify

# Annotation注释不能混淆

-keepattributes *Annotation*

#对于NDK开发 本地的native方法不能被混淆

-keepclasseswithmembernames class * {

native ;

}

#保持View的子类里面的set、get方法不被混淆(*代替任意字符)

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

void set*(***);

*** get*();

}

#保持Activity子类里面的参数类型为View的方法不被混淆,如被XML里面应用的onClick方法

# We want to keep methods in Activity that could be used in the XML attribute onClick

-keepclassmembers class * extends android.app.Activity {

public void *(android.view.View);

}

#保持枚举类型values()、以及valueOf(java.lang.String)成员不被混淆

-keepclassmembers enum * {

public static **[] values();

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

}

#保持实现Parcelable接口的类里面的Creator成员不被混淆

-keepclassmembers class * implements android.os.Parcelable {

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

}

#保持R类静态成员不被混淆

-keepclassmembers class **.R$* {

public static ;

}

#不警告support包中不使用的引用

-dontwarn android.support.**

-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

#保持使用了Keep注解的方法以及类不被混淆

-keepclasseswithmembers class * {

@android.support.annotation.Keep ;

}

#保持使用了Keep注解的成员域以及类不被混淆

-keepclasseswithmembers class * {

@android.support.annotation.Keep ;

}

-keepclasseswithmembers class * {

@android.support.annotation.Keep (...);

}

上面默认的规则中指示了些需要保持不能别混淆的代码,包括:

继承至Android组件(Activity, Service...)的类。

自定义控件,继承至View的类(被xml文件引用到的,名字已经固定了的)

enum 枚举

实现了 android.os.Parcelable 接口的

Android R文件

数据库驱动...

Android support 包等

Android 的注释不能混淆

-keepattributes *Annotation*

对于NDK开发 本地的native方法不能被混淆

-keepclasseswithmembernames class * { native ; }

对于特定的项目还有很多不能被混淆的,需要我们自己写规则来指示,将在下面来说明:

对一些符号做一些说明

现在来看一下需要我们自己编写的proguard-rules.pro:

#压缩级别0-7,Android一般为5(对代码迭代优化的次数)

-optimizationpasses 5

#不使用大小写混合类名

-dontusemixedcaseclassnames

#混淆时记录日志

-verbose

#不警告org.greenrobot.greendao.database包及其子包里面未应用的应用

-dontwarn org.greenrobot.greendao.database.**

-dontwarn rx.**

-dontwarn org.codehaus.jackson.**

......

#保持jackson包以及其子包的类和类成员不被混淆

-keep class org.codehaus.jackson.** {*;}

#--------重要说明-------

#-keep class 类名 {*;}

#-keepclassmembers class 类名{*;}

#一个*表示保持了该包下的类名不被混淆;

# -keep class org.codehaus.jackson.*

#二个**表示保持该包以及它包含的所有子包下的类名不被混淆

# -keep class org.codehaus.jackson.**

#------------------------

#保持类名、类里面的方法和变量不被混淆

-keep class org.codehaus.jackson.** {*;}

#不混淆类ClassTwoOne的类名以及类里面的public成员和方法

#public 可以换成其他java属性如private、public static 、final等

#还可以使表示构造方法、表示方法、表示成员,

#这些前面也可以加public等java属性限定

-keep class com.dev.demo.two.ClassTwoOne {

public *;

}

#不混淆类名,以及里面的构造函数

-keep class com.dev.demo.ClassOne {

public ();

}

#不混淆类名,以及参数为int 的构造函数

-keep class com.dev.demo.two.ClassTwoTwo {

public (int);

}

#不混淆类的public修饰的方法,和private修饰的变量

-keepclassmembers class com.dev.demo.two.ClassTwoThree {

public ;

private ;

}

#不混淆内部类,需要用$修饰

#不混淆内部类ClassTwoTwoInner以及里面的全部成员

-keep class com.dev.demo.two.ClassTwoTwo$ClassTwoTwoInner{*;}

......

对一些规则的解释:

-keepattributes {name}  保护给定的属性不被混淆,

如:-keepattributes *Annotation*

-dontwarn {name}  不要警告指定库中找不到的引用。混淆在默认情况下会检查每个库的引用是否正确,但是有些第三方库里面会有用不到的类,有些没有正确引用,所以需要对第三方库取消警告 否则会报错,而且有可能混淆时间会很长。

如:-dontwarn org.codehaus.jackson.**

-keep {Modifier} {class_specification}  保留指定的类名、类成员不被混淆

-keepclassmembers {modifier} {class_specification}   保留指定的类成员不被混淆

-keepclasseswithmembers {class_specification}   保留指定的类名、类成员不被混淆

-keepnames {class_specification}   保留指定的类名、类成员的名称不被混淆

-keepclasseswithmembernames {class_specification}   保留指定的类名、类成员名称不被混淆(如果存在的话)

3.混淆后根据Crash崩溃日志反推代码

成功打包后会在目录*** app\build\outputs\mapping\release ***下生成几个文件:

86ee6ef970ef

2.png

说明:

dump.txt 混淆后类的内部结构说明;

mapping.txt 混淆前与混淆后名称对应关系;

seeds.txt 经过了一系列keep语句的保持,没有被混淆的类,成员的名称列表文件。

usage.txt 经过压缩后被删除的没有使用的代码,方法...等的名称的列表文件

retrace工具:

混淆反推工具为retrace.sh(Mac平台)或者retrace.bat(Windows平台)

该工具在sdk根目录\tools\proguard\bin\retrace.sh

(Windows平台类似);

命令格式:

*** ./retrace.sh [mapping.txt目录] [崩溃日历目录]

(Windows平台:retrace.bat [mapping.txt目录] [崩溃日历目录]) ***

第一步:保存Crash日志如下:截取日志保存为txt文件如:bug.txt。

03-21 03:09:32.389: E/AndroidRuntime(3582): FATAL EXCEPTION: main

03-21 03:09:32.389: E/AndroidRuntime(3582): Process: com.dev.demo, PID: 3582

03-21 03:09:32.389: E/AndroidRuntime(3582): java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference

03-21 03:09:32.389: E/AndroidRuntime(3582): at com.dev.demo.two.b.b(Unknown Source)

03-21 03:09:32.389: E/AndroidRuntime(3582): at com.dev.demo.a.a.printTest(Unknown Source)

03-21 03:09:32.389: E/AndroidRuntime(3582): at com.dev.demo.MainActivity.i(Unknown Source)

03-21 03:09:32.389: E/AndroidRuntime(3582): at com.dev.demo.MainActivity.a(Unknown Source)

03-21 03:09:32.389: E/AndroidRuntime(3582): at com.dev.demo.MainActivity$1.onClick(Unknown Source)

第二步:删掉Crash日志中03-21 03:09:32.389: E/AndroidRuntime(3582):部分,否则无法反推还原。删除后如下:

FATAL EXCEPTION: main

Process: com.dev.demo, PID: 3582

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference

at com.dev.demo.two.b.b(Unknown Source)

at com.dev.demo.a.a.printTest(Unknown Source)

at com.dev.demo.MainActivity.i(Unknown Source)

at com.dev.demo.MainActivity.a(Unknown Source)

at com.dev.demo.MainActivity$1.onClick(Unknown Source)

第三步:打开命令窗口输入命令:如:*** ./retrace.sh mapping.txt bug.txt ***

如下:

86ee6ef970ef

3.png

按确认后得到结果如下:

FATAL EXCEPTION: main

Process: com.dev.demo, PID: 3582

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference

at com.dev.demo.two.ClassTwoThree.void test()(Unknown Source)

at com.dev.demo.one.ClassOneOne.void printTest()(Unknown Source)

at com.dev.demo.MainActivity.void printWifi()(Unknown Source)

at com.dev.demo.MainActivity.void access$000(com.dev.demo.MainActivity)(Unknown Source)

at com.dev.demo.MainActivity$1.void onClick(android.view.View)(Unknown Source) ```

除了有retrace.sh工具外还有可视化工具,和retrace.sh同目录下proguardgui.sh,这是一块Progurad的可视化工具:

(Windows平台类似)

![4.png](http://upload-images.jianshu.io/upload_images/3589324-f0d492d9da432138.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

>有时为了Crash日志更容易定位可以在规则里面添加:

-keepattributes SourceFile, LineNumberTable

**这样Crash日志里面就能保留类名称 和行号了**

**好了,所有终于完了,希望能帮助到你!谢谢!**

***

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle查询当前用户名下所有表

--SONARQUBE为用户名,用户名必须是大写 SELECT * from all_tables where ownerSONARQUBE;--查看当前登录的用户的表: SELECT table_name from user_tables;

JUC包中的分而治之策略-为提高性能而生

一、前言 本次分享我们来共同探讨JUC包中一些有意思的类,包含AtomicLong & LongAdder,ThreadLocalRandom原理。 二、AtomicLong & LongAdder 2.1 AtomicLong 类 AtomicLong是JUC包提供的原子性操作类,其内部通过CAS保证了对计数的原子性更新…

galaxy s8 android pc,手机秒变PC!三星Galaxy S8桌面模式曝光

据外媒报道,三星旗舰手机Galaxy S8/S8 Plus在外观上以及硬件配置上已经没有了悬念。不过一些小的改进或者是新功能还是让人对Galaxy S8充满期待。日前,传闻中的Galaxy S8桌面模式终于被曝光。三星Galaxy S8桌面模式曝光(图片来自kkj)报道称,G…

2020年进军 AI,想年薪 40 万,没这个能力不行

前几天,《百度沸点:2019年度科技热词》来了!百度沸点:2019年度科技热词 AI排名第一2019年可以说是AI全面落地和商用的一年,产业智能化成为各个行业重点关注的发展方向,交通、工业、农业、医疗等主流行业无一…

重磅公开!阿里语音识别模型端核心技术,让你“听”见未来

语音识别技术作为人工智能技术中的重要组成部分,成为影响人机交互的核心组件之一,从各种智能家用IoT设备的语音交互能力,到公共服务、智慧政务等场合的应用,语音识别技术正在影响着人们生活的方方面面。 本文将全面介绍阿里云语音…

linux搭建SonarQube代码质量平台_Oracle 最新详细版本

文章目录一、最低配置要求1. JDK版本要求2. 数据库版本要求3. 支持浏览器版本二、软件下载安装2.1. 软件列表总览2.2. jdk11下载2.3. sonarqube下载2.4. sonar-scanner-cli2.5. Oracle 驱动三、安装实战3.1. JDK sonar-scanner3.2. sonarqube3.3. oracle驱动3.4. 启动sonar3.4.…

2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势(上)

1、简介: 过去几年一直是人工智能爱好者和机器学习专业人士最幸福的时光。因为这些技术已经发展成为主流,并且正在影响着数百万人的生活。各国现在都有专门的人工智能规划和预算,以确保在这场比赛中保持优势。 数据科学从业人员也是如此&am…

2018最佳GAN论文回顾(下)

继上一篇《2018最佳GAN论文回顾(上)》,我又继续介绍了一个对于GAN的基于样式的生成器体系结构的新论文,提出了一个新的模型来应对这种挑战。 一种用于生成式对抗网络的基于生成器体系结构的方式(A Style-Based Genera…

云+X案例展 | 民生类:浪潮云打卡人间仙境张家界

本案例由浪潮投递并参与评选,CSDN云计算独家全网首发;更多关于【云X 案例征集】的相关信息,点击了解详情丨挖掘展现更多优秀案例,为不同行业领域带来启迪,进而推动整个“云行业”的健康发展。“仙凡共界武陵门&#xf…

云栖专辑 | 阿里开发者们的第19个感悟:Simple is better.

2015年12月20日,云栖社区上线。2018年12月20日,云栖社区3岁。 阿里巴巴常说“晴天修屋顶”。 在我们看来,寒冬中,最值得投资的是学习,是增厚的知识储备。 所以社区特别制作了这个专辑——分享给开发者们20个弥足珍贵的…

使html表格可编辑状态,js+Html实现表格可编辑操作

本文实例为大家分享了jsHtml实现表格可编辑操作的具体代码,供大家参考,具体内容如下功能描述:单击页面使单元格td变成可编辑状态,输入内容后,当单元格失去焦点时,保存输入的内容。点击增加行,在…

深度学习为图片人物换装【python代码教程】

在观看本文之前,请答应我要善良。昨天预告了下,发现很多同学对这个模型都表示出兴趣,甚至有好多同学后台发来照片让我帮他们脱裤子。授人以鱼不如授人以渔,请这些同学好自为之~ 01效果演示 本文案例使用的是开源项目instagan&am…

java通过HTTPS协议POST提交接收JSON格式数据

文章目录一、客户端实现1. HttpsApiUtils 测试方法2. 返回报文监控二、服务端实现2.1. 配置SSL 实现HTTPS2.2. 添加post接口方法2.3. 服务端监控三、进阶测试3.1. 客户端发送对象3.2. 服务端监控3.3. 客户端解析返回报文一、客户端实现 声明:不用引入任何第三方jar…

2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势(下)

4、工具和库 工具和库是数据科学家的基础。我参与了大量关于哪种工具最好的辩论,哪个框架会取代另一个,哪个库是经济计算的缩影等等。 但有一点共识--我们需要掌握该领域的最新工具,否则就有被淘汰的风险。 Python取代其他所有事物并将自己…

Elasticsearch7.15.2 出现 node validation exception 的问题处理

3个异常如下: [1]: max file descriptors [65535] for elasticsearch process is too low, increase to at least [65536][2]: memory locking requested for elasticsearch process but memory is not locked[3]: max virtual memory areas vm.max_map_count [6553…

最强NLP模型BERT可视化学习

2018年是自然语言处理(Natural Language Processing, NLP)领域的转折点,一系列深度学习模型在智能问答及情感分类等NLP任务中均取得了最先进的成果。近期,谷歌提出了BERT模型,在各种任务上表现卓越,有人称其…

一分钟看懂通信铁塔

戳蓝字“CSDN云计算”关注我们哦!作者 | 无线深海责编 | 阿秃说到铁塔,相信大家都很熟悉。我们走在路上,到处都可以看到它们。作为通信工程师来说,我们所说的铁塔,往往是特指那些专门用于通信用途的塔。现实生活中&…

html立体魔方图片制作,ppt怎么制作三维视图的魔方图 ppt制作三维魔方图详细教程...

很多用户在制作PPT展示图的时候,有时候需要制作三维立体的魔方图,制作步骤简单,不过还有很多的用户不清楚如何制作,那么下面小编就为大家分享PPT制作三维魔方图的详细步骤教程,不会制作的朋友可以参照下面的步骤教程多…

PMP考试技巧(必备)

(一) 关键词篇 第 1 章 引论 看到“驱动变革”——选项中找“将来状态” 看到“依赖关系”——选项中找“项目集管理” 看到“价值最大化”——选项中找“项目组合管理” 看到“可行性研究”——选项中找“商业论证” 第 2 章 项目运行环境 看到“…

IDE 插件新版本发布,开发效率 “biu” 起来了

近日,Cloud Toolkit正式推出了面向 IntelliJ 和 Eclipse 两个平台的新款插件,本文挑选了其中三个重大特性进行解读,点击文末官网跳转链接,可查看详细的版本说明。 本地应用一键部署到任何机器上IDE 内置的命令行终端文件上传到服…