Android Studio 代码混淆 与 发布release正式签名版本

来源:互联网 发布:2017淘宝改销量技术 编辑:程序博客网 时间:2024/05/17 00:56


一.android App 打包签名

个人建议:如果是公司开发,建议可以到网上买一些付费的混淆服务,国外有多提供混淆代码工具服务的公司,他们做的非常专业,
我们下面使用到的的混淆工具是google内部提供的,个人玩玩还可以,但是混淆代码的区域比较有限
在我们完成一个项目之后,其实工程还未真正的完结,在项目开发阶段,在手机运行的程序是使用Debug版本发布的,并没有真正的使用
release发布版本,个人建议,在进行完项目测试之后,先不着急进行打包签名,可以使用发布版本再进行测试,因为,App有些时候在debug版本测试是没有问题,但是移到release发布版本就不能运行了

  1. 如果以上步骤,你没出现任何问题,那么,接下来,我们可以进行签名打包了,但是,在一些公司开发中,为了保证代码安全
(一般的程序app都可以将apk文件中的代码进行还原,所有,我们首要做的一点就是保证个人或公司的代码资产安全)
在这里,我介绍一下怎么使用android studio 进行代码的混淆和打包release发布版本(注意:我使用的是androidstudio 1.3版本,较早之前的版本可能操作有点不一样,不过混淆规则都是一样的)

  1. 首先,我们打开项目的build.gradle文件,这个文件在android视图下能很快找到
这里值得注意的是,在minifyEnabled系统默认为false,表示不进行代码混淆(android studio 1.2版本之前使用的是runProguard true)
我们需要将其设置为true,红色框的第二行表示android个我们生成的混淆代码文件,主要使用到proguard-rules.pro规则文件
默认的proguard-android.txt文件在\SDK\tools\proguard\proguard-android.txt下,直接拷贝过来,在添加上自己自定义的规则,就能使用




    2.我们需要认真研究一下混淆的代码的一些规则和优化(重点),下面如图,打开proguard-rules.pro文件,添加需要的规则(后面部分有介绍)
是我自定义的几条常用的规则,前面的部分内容是通过sdk文件夹下的proguard-android.txt拷贝,
然后添加上自己的规则,(粘贴部分的代码,省略。。。。。)
根据自己项目的需要,判断对那一部分代码混淆过滤


    3.最后就是我们的签名
        步骤:点击Build--->Generate Signed APK---->


4.填写签名相关的信息(注意:如果是公司开发,一定不能不签名的key搞丢了,否则后果是非常严重的


5.接下来:选择release发布版本,


6,最后你就能看到成功签名的提示:如图,


7,点击进入就能看打打包签名好的APK文件


二,检验代码是否已经混淆

  1. 使用逆向编译工具对我们打包好的APK文件进行反编译(我这里使用的是Android逆向助手_v2.0
首先,我们先将APK文件中的.dex文件提取出来


其次,将*.dex文件转成jar文件


然后Android逆向助手_v2.0会自动的打开.jar文件,并显示目录结构




##让我么先来了解一下代码progurad混淆代码的原理

下面内容来自于网上,并且自己添加了一些内容,有什么不对的请各位看官更正
proguard 原理
Java代码编译成二进制class 文件,这个class 文件也可以反编译成源代码 ,除了注释外,原来的code 基本都可以看到。为了防止重要code 被泄露,我们往往需要混淆(Obfuscation code , 也就是把方法,字段,包和类这些java 元素的名称改成无意义的名称,这样代码结构没有变化,还可以运行,但是想弄懂代码的架构却很难。 proguard 就是这样的混淆工具,它可以分析一组class 的结构,根据用户的配置,然后把这些class 文件的可以混淆java 元素名混淆掉。在分析class 的同时,他还有其他两个功能,删除无效代码(Shrinking 收缩),和代码进行优化 (Optimization Options)。
缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。
一, 我们用到反射的地方。
二, 我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。
三, 是我们的java 元素名称是在配置文件中配置好的。
所以使用proguard时,我们需要有个配置文件告诉proguard 那些java 元素是不能混淆的。

来源: <http://www.cnblogs.com/royi123/archive/2013/02/28/2937657.html>
 proguard的配置
最常用的配置选项
-dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
-keep 指定的类和类成员被保留作为 入口 。
-keepclassmembers 指定的类成员被保留。
-keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。

 proguard 问题和风险
代码混淆后虽然有混淆优化的好处,但是它往往也会带来如下的几点问题
1,混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,否则proguard 会报错。
2,运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。
3,调试苦难,出错了,错误堆栈是混淆后的代码 ,自己也看不懂。

 proguard 问题解决办法
为了防止混淆出问题,你需要熟悉你所有的code ,系统的架构 ,以及系统和你code的集成的接口,并细心分析。 同时你必须需要一轮全面的测试。 所以混淆也还是有一定风险的。 为了避免风险,你可以只是混淆部分关键的代码,但是这样你的混淆的效果也会有所降低。
 常见不能混淆的Code代码
Android 程序 ,下面这样代码混淆的时候要注意保留:
(自己总结的部分)
四大组建不能进行混淆,否则android手机系统不会识别你写的代码
反射的地方
aidl文件不能混淆
建议应用开源框架,或者一些其他框架,在不知道内部代码结构的同时,建议不要对框架代码进行混淆

(网上总结的部分)
Android系统组件,系统组件有固定的方法被系统调用。
被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。
Android Parcelable ,需要使用android 序列化的。
其他Anroid 官方建议 不混淆的,如
android.app.backup.BackupAgentHelper
android.preference.Preference
com.android.vending.licensing.ILicensingService
Java序列化方法,系统序列化需要固定的方法。
枚举 ,系统需要处理枚举的固定方法。
本地方法,不能修改本地方法名
annotations 注释
数据库驱动
有些resource 文件

 系统检查第三方库
这里指的是项目中使用的的第三方架包会被检测到
-dontwarn android.support.**   (这是项目使用到的依赖库)

 分析proguard中的参数含义:
-include {filename}    从给定的文件中读取配置参数
-basedirectory {directoryname}    指定基础目录为以后相对的档案名称
-injars {class_path}    指定要处理的应用程序jar,war,ear和目录
-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。
  • 选项
-keep {Modifier} {class_specification}    保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件
  • 压缩
-dontshrink    不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}  

  • 优化
-dontoptimize    不优化输入的类文件
-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用
-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员
  • 混淆
-dontobfuscate    不混淆输入的类文件
-printmapping {filename}
-applymapping {filename}    重用映射增加混淆
-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively    混淆时应用侵入式重载
-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string}    设置源文件中给定的字符串常量






2 0
原创粉丝点击