怎么在proguard配置文件 文件中加 keep

Android ProGuard实例教程_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Android ProGuard实例教程
来源:Linux社区&
作者:Linux
ProGuard工具通过移除不用的代码,用语义上混淆的名字来重命名类、字段和方法等手段来压缩、优化和混淆你的代码。结果是更小的.apk文件,并且更难于被反编译。由于ProGuard能够让你的程序难于被反编译,因此,当你的程序使用了一些机密的信息的时,使用它就显得更加重要。 ProGuard已经集成到的编译环境中,因此,用不着手动来触发它。ProGuard只在release模式下编译应用程序才会运行,所以,在debug模式下编译,你就不必处理混淆的代码。是否运行ProGuard是完全可选的,但强烈推荐使用。 启用ProGuard 当你创建Android工程时,proguard.cfg文件会在工程的根目录自动创建。这个文件定义了ProGuard如何优化和混淆代码,因此,理解如何定制它是非常重要的。默认的配置文件只是覆盖了一些通用的情况,所以,基本上你需要编辑它来满足你的需求。参考后面的&配置ProGuard&章节来了解如何定制ProGuard的相关信息。 启用ProGuard让它跟随Ant或Eclipse编译时一起运行,你需要在&project_root&/default.properties文件中设置proguard.config属性。路径可以是绝对路径或是工程根目录的相对路径。 如果你把proguard.cfg文件放在默认的位置(工程的根目录),你可以像这样来指定它的位置: proguard.config=proguard.cfg 你还可以把该文件移到任何你想放的位置,然后指定绝对路径:proguard.config=/path/to/proguard.cfg 当你在release模式下编译你的程序,不管是用ant release还是用Eclipse的导出向导,编译系统都会自动检查proguard.config属性是否设置。如果设置了,ProGuard就会在打包成.apk文件之前,自动处理应用程序的字节码。Debug模式编译,不会触发ProGuard,因为它会使得调试更加复杂累赘。 ProGuard运行结束后,输出以下文件: dump.txt 描述.apk文件中所有类文件间的内部结构 mapping.txt 列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。 seeds.txt 列出了未被混淆的类和成员 usage.txt 列出了从.apk中删除的代码这些文件放在以下文件夹中: Ant:&project_root&/bin/proguard Eclipse: &project_root&/proguard 注意:每当你在release模式下编译时,这些文件都会被覆盖重写,当然,是被ProGuard工具生成的最新的文件所覆盖。每次你发布你的程序时,都应该保存一份,为了将来能够解码bug报告。配置 ProGuard 一些情况下,proguard.cfg文件中的默认配置就足够了。然而,有些情况ProGuard也很难正确分析,它可能会删除它认为不用的代码,但实际上正是你的程序所需要的。例如: 只在AndroidManifest.xml文件中引用的类 由JNI调用的方法 动态引用的字段和方法 默认的proguard.cfg文件努力去覆盖通用的情况,但有可能你会遇到如ClassNotFoundException这样的异常,而这正好是由于ProGuard移除了整个类造成的。 你可以修正由于ProGuard移除代码造成的错误,只需要在proguard.cfg文件中添加一行&-keep&。例如: -keep public class &MyClass& 使用-keep选项时,有一些选项和建议,因此,强烈建议你阅读ProGuard手册来了解更多关于定制配置文件的信息。&Overview of Keep options&和&Examples section&将非常有用。
ProGuard 的详细介绍:ProGuard 的下载地址:
更多Android相关信息见 专题页面
相关资讯 & & &
& (08/01/:22)
& (08/01/:17)
& (03/20/:38)
& (08/01/:40)
& (08/01/:03)
& (05/29/:31)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款安卓开发(5)
前言注意事项
在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是project.properties和proguard-project.txt。
如果需要对项目进行全局混码,只需要进行一步操作:
将project.properties的中
“# &proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt”的“#”去掉就可以了。
如果有一些代码不能被混淆,比如需要加入了so文件,需要调用里面的方法,那么调用JNI访问so文件的方法就不能被混码。在导出的时候,可能不会报错。但是在手机上运行的时候,需要调用so文件的时候,就会报某某方法无法找到。这个时候就需要用到proguard-project.txt。
在老版本中,创建项目的时候,会给出proguard.cfg,但是在的新版中创建项目则不会有任何提示。这个时候需要只要将proguard.cfg的内容加入到proguard-project.txt中,再根据自己的需要进行编辑即可。
proguard.cfg详细的信息可以参看:
本章内容为开发者指南(Dev Guide)/Developing/Tools/ProGuard,本章内容为&混淆器&,版本为Android3.0 r1,翻译来自:&Jim&,欢迎与他交流:&&,再次感谢&Jim& !。
混淆器(ProGuard)
  在本文中(In this document)
混淆器通过删除从未用过的代码和使用晦涩名字重命名类、字段和方法,对代码进行压缩,优化和混淆。结果是一个比较小的.apk文件,该文件比较难进行逆向工程。因此,当你的应用程序对安全敏感(要求高),例如当你的时候,混淆器是一种重要的保护手段。
混淆器被集成在android&构建系统中,所以你不必手动调用它。同时混淆器仅在发布模式下进行构建应用程序的时候才会运行起来,所以在调试模式下构建程序时,你不必处理混淆代码。让混淆器运行起来是可选择的,但是推荐选上。
这个文档描述了怎样启用并配置混淆器,以及使用跟踪(retrace)工具对混淆的堆栈跟踪信息(stack traces)进行解码。
启用混淆器Enabling ProGuard
当你新建了一个Android工程之后,一个proguard.cfg文件会在工程的根目录下自动创建。这个文件定义了混淆器是怎样优化和混淆你的代码的,所以懂得怎样根据你的需要来定制是非常重要的。缺省的配置文件仅覆盖到了通常情况,所以根据你的需求,很可能需要编辑它。接下来的内容是关于通过定制混淆器配置文件来对。
为了让启用混淆器作为Ant或者Eclipse构建过程中一部分,可以在&project_root&/default.properties文件中,设置proguard.config属性。路径可以是绝对路径或者工程根目录的相对路径。
如果你让proguard.cfg文件在缺省位置(工程的根目录),你可以像这样指定位置:
proguard.config=proguard.cfg
& & &同样,你可以把该文件放到任意的位置,并指定它的绝对路径。
proguard.config=/path/to/proguard.cfg
当你在发布模式下,或者通过运行ant release,或者通过使用Eclipse中的Export Wizard构建你的应用程序的时候,构建系统都会自动地去检查proguard.config属性是否被设置了。如果被设置了,混淆器在把所有东西打包成.apk文件之前,自动地对应用程序字节码进行混淆处理。而在调试模式中构建则不会调用混淆器,因为那样调试会更加繁重。
& & & 运行混淆器之后输出的文件有:
&&&&&&dump.txt
&&&&&&&&&&&&&&&&&&&描述.apk包中所有class文件的内部结构。
& & &&mapping.txt
列出了源代码与混淆后的类,方法和属性名字之间的映射。这个文件对于在构建之后得到的bug报告是有用的,因为它把混淆的堆栈跟踪信息反翻译为源代码中的类,方法和成员名字。更多信息,查看。
& & &&seeds.txt
&&&&&&&&&&&&&&&&&&&列出那些未混淆的类和成员。
& & &&usage.txt
&&&&&&&&&&&&&&&&&&&列出从.apk中剥离的代码。
这些文件放在以下目录中:
&project_root&/bin/proguard&当你使用Ant时&project_root&/proguard&当你使用Eclipse时
注意:&每次在发布模式下构建时,这些文件都会被最新的文件覆盖。所以每次发布程序时候,为了反混淆来自构建时产生的bug报告,请保存这些文件的一个拷贝。对于为什么要保存这些文件的重要性的更多信息,请查看
混淆器配置(proguard config)
某些情况下,proguard.cfg文件的缺省配置可以满足需求了。但是,对于混淆器来说,大多数情况做出正确的分析是困难的,并且它或许会删除在它看来是无用的,但对于程序来说却确实需要的代码。一些例子如下:
&一个仅引用于AndroidManifest.xml文件的类。一个通过JNI调用的方法。动态引用的属性和方法。
缺省的proguard.cfg文件试图覆盖普通的情况,但是你可能碰到类似ClassNotFoundException的异常,这个异常出现在当你的程序去访问一个被混淆器移除了的类的时候。
你可以在proguard.cfg文件中添加-keep这一行来修复这些错误。例如:
-keep&public&class&&MyClass&
-Keep设置有很多可选项和注意地方,所以为了获得更多关于配置信息,强烈推荐你阅读。特别有用的有和。在混淆器手册部分,介绍了代码在混淆过程中你可能碰到的其他常见问题。
解码混淆过的堆栈跟踪信息(Decoding Obfuscated Stack Traces)
当混淆代码并输出了一个堆栈调试信息时,这些方法名字是混淆过的,虽然可以进行调试,但是调试变得困难。幸运的是,每当混淆器运行时候,它都会输出到文件&project_root&/bin/proguard/mapping.txt中,该文件包含了从原始类,方法和属性名字到混淆后名字的映射。
&Windows系统中retrace.bat脚本命令或者Linux和Mac OS X系统中retrace.sh脚本命令能把混淆后的堆栈调试信息转换为可以理解的文件。它被放在&sdk_root&/tools/proguard/目录下。运行retrace工具的命令语法是:
retrace.bat|retrace.sh&[-verbose]&mapping.txt&[&stacktrace_file&]
retrace.bat&-verbose
mapping.txt obfuscated_trace.txt
如果你没有为&stracktrace_file&指定值,那么retrace工具从标准输入读取。
已发布应用程序的调试注意事项(Debugging considerations for published applications)
保存好每一个已发布给用户的程序的mapping.txt文件。通过保存发布构建版本的mapping.txt文件拷贝,确保当用户碰到bug,并把混淆后的堆栈调试跟踪信息提交给你时,你可以进行调试从而修复问题。程序的mapping.txt文件在每次发布构建时都会被覆盖,所以你一定要注意保存正确的版本。
例如,假设你已经发布了一个应用程序并在继续在新的版本中开发添加新的功能。接着你马上启动混淆器并创建一个新的发布版本。该操作把mapping.txt文件覆盖了。一个用户提交了来自当前发布版本的bug报告,该报告包含了堆栈调试信息。你再也不能对用户的堆栈信息进行调试了,因为这个对应用户本机上版本的mapping.txt文件不存在了。其他覆盖mapping.txt文件的情况还有很多,所以对于每一个可能需要调试的版本,你都要确保有一份拷贝。
如何保存mapping.txt文件由你决定。例如,你可以根据版本和构建号来重命名它们,或者连同你的源代码进行版本控制。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7526次
排名:千里之外
原创:11篇
(1)(1)(1)(3)(6)2109人阅读
一、什么是ProGuard
为了保证代码的可读性,编写的函数或者变量一般都使用有意义的名字,一看到函数名就知道这个函数是干什么的,一看到变量名就知道这个变量存放的值代表什么含义。这样,对于以后代码的维护会有很多的好处,将代码交接给别人维护也会非常的方便。
但是Android应用是用Java代码写的,最后这些代码会被编译成一个包含Dalvik指令的dex文件,并且所有的函数名、变量名都会原封不动的保留在dex文件中。对于某些居心叵测的人,可以使用dex2jar和jd-gui试着反推出原始的Java代码或者程序的大致逻辑,然后用apktool修改代码并重新打包。这时候,清晰的函数名和变量名将会给这些黑客以很大的帮助。
拿我写的一个应用来说,在没有经过任何处理的情况下,用dex2jar将apk文件转换成jar文件后,再用jd-gui将其打开:
可以看到,其实现的逻辑几乎一览无疑,想要了解背后的实现原理,根本没有任何难度。
那么有没有什么办法既能保证原始代码的可读性,又可以防止这些有用的信息被包含在编译后的代码中,从而泄露给其他的人呢?Google为此提供了一个ProGuard的工具。
ProGuard是在Android
SDK中提供的一个免费的开源工具,它能够使用语义上隐晦的名称来重命名代码中的类、变量和函数等,达到混淆代码的功能。
二、如何使用ProGuard
当在Eclipse中创建一个新的Android工程时,在工程目录的根路径下,会有一个project.properties文件,将其打开,可以看到下面的两行:
#To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt所以,默认情况下,ProGuard是被关闭的,如果想打开的话,将proguard.config前面的井号(“#”)去掉就行了。
可以看到,在这个配置项中指定了两个文件。第一个位于Android
SDK中,它是Android为所有项目定义的一个通用的配置文件;而第二个位于本工程的根目录下(项目创建时,会在根目录下自动创建一个proguard-project.txt配置文件),其里面的内容是空的,如果第一个通用配置文件无法满足你的需要,还需要专门为你自己的项目添加配置项的话,可以加在这个文件中。一般情况下,通用配置文件已经够用了,并不需要对项目进行特殊的定制。
到此,我们已经通过简单的配置,在Eclipse工程中打开了ProGuard工具混淆Android代码的功能。当你下次在Eclipse中导出你的Android应用时,ProGuard会自动混淆你的代码:
ProGuard只在release模式下编译应用程序才会起作用。而如果在debug模式下编译的话,并不会触发ProGuard对代码进行混淆。
下面我们来看看混淆的效果,还是同样的工程,当开启ProGuard混淆功能后,经过dex2jar处理,在jd-gui中看到的结果如下:
可以看出来,相对于前面来说,混淆过后的代码,其函数和变量名都被替换成了没有任何含义的a、b、c、d等字母,单纯看函数名和变量名已经没法猜出其具体作用了。
当你通过Eclipse导出了一个通过ProGuard混淆过的apk后,会在项目的根目录下创建一个叫做proguard的目录,自动生成四个文件:
<span style="color:#)dump.txt:描述apk内所有类文件的内部结构。
<span style="color:#)mapping.txt:列出了原始的类、方法和变量名与混淆后代码间的映射关系。这个文件非常重要,如果你的代码产生bug的话,那么在log中显示的是混淆后的代码。如果希望定位到原始的源代码的话,可以根据记录在mapping.txt文件中的映射关系进行反推。
<span style="color:#)seeds.txt:列出了没有被混淆的类和成员函数及变量。
4)usage.txt:列出了被删除的无用代码。
注意,对于下列几种情况,ProGuard不会对代码进行混淆:
<span style="color:#) 反射用到的类;
<span style="color:#) 在AndroidManifest.xml文件中引用到的类;
<span style="color:#) 需要使用JNI调用的类。
三、如何配置ProGuard
其实ProGuard的配置文件主要用来告诉ProGuard,项目中的哪些代码是不能被混淆的。要想保证代码的某些部分不被ProGuard混淆,必须要在配置文件中添加一些以-keep打头的配置项,一共有<span style="color:#种关键字,它们的区别和含义如下:
ProGuard在对代码混淆的同时,还会剔除一些无用的代码,也就是从任何调用路径都无法被执行的代码,这样做的好处是可以有效减小应用程序的大小。第一列的关键词可以保证指定的代码不被改名也不会被剔除,即使没有用;第二列的关键词只保证指定代码不会被改名,但如果ProGuard判断这些代码没有用的话,任然会将其删除掉。
这<span style="color:#个关键字后面都要包含一个类规&#26684;(Class
Specification),说明作用的范围,如:
-keep class_specification这个所谓的类规&#26684;是一个非常复杂的概念,其大致定义如下:
[[!]public|final|abstract ...] [!]interface|class|enum classname
[extends|implements classname]
[[!]public|private|protected|static|volatile|transient ...] &fields& |
(fieldtype fieldname);
[[!]public|private|protected|static|synchronized|native|abstract ...] &methods& |
&init&(argumenttype,...) |
(returntype methodname(argumenttype,...));
[[!]public|private|protected|static ... ] *;
}]是不是觉得非常复杂?下面我们来解释一下。表达式中的方括号(“[ ]”)表示里面的内容是可选的,可以有也可以没有;省略号(“…”)表示前面的内容均可以以任何次序和组合同时使用;竖线(“|”)表示这些选项只能出现一个。
表达式中的class关键字表示任何接口类、抽象类和普通类;interface关键字表示只能是接口类;enum关键字表示只能是枚举类。如果在interface和enum关键字前面加上感叹号(“!”)分别表示不是接口类的类和不是枚举类的类。class关键字前面是不能加感叹号的。
对于类名(classname)来说,可以是类全名,或者可以包含以下一些特殊字符的正则表达式:
<span style="color:#)?:问好代表一个任意字符,但不能是句号(“.”,因为句号是包名分隔符);
<span style="color:#)*:单个星号代表任意个任意字符,但不能代表句号;
<span style="color:#)**:两个星号代表任意个任意字符,且能代表句号。
对于单个星号来说,如果类名部分只有一个星号,不包含其它任何字符,为了保证兼容性,其代表任何类,就跟两个星号的作用一样了。
extends和implements表示限定类一定要扩展自一个指定类或者实现了一个指定接口类,这时候通常类名部分是一个星号。
对于类中的成员变量(Fields)来说,可以通过变量类型fieldtype和变量名fieldname来精确指定,也可以通过&fields&表示类中的任何成员变量。
对于类中的成员函数(Methods)来说,可以通过返回类型returntype、方法名methodname和参数类型argumenttype来唯一限定,也可以通过&methods&来表示类中的任何成员函数。
对于类的构造函数来说,可以用&init&加上构造函数的参数来指定。
星号(“*”)可以匹配类中的任何成员变量和函数。
对于类中的成员函数名methodname和成员变量名fieldname来说也可以使用通配符来匹配,同样问号(“?”)可以匹配一个任意字符,而星号(“*”)可以匹配任意多个任意字符。
对于类中的成员变量的类型、成员函数的返回类型和参数类型,以及构造函数的参数类型来说,可以使用下面这些通配符来匹配:
<span style="color:#)
%:匹配任何原始类型,如boolean、int等,但不包括void;
<span style="color:#)
?:匹配一个任意字符,不包括句号;
<span style="color:#)
*:匹配任意个任意字符,不包括句号;
<span style="color:#)
**:匹配任意个任意字符,包括句号;
<span style="color:#)
***:匹配任意类型,包括原始类型和非原始类型,数组类型和非数组类型;
6)…:匹配任何数目个任何类型的参数。
在类名前、类中成员变量和成员函数名前,可以加上访问限定符(如public、private、protected等,修饰类、成员变量和成员函数的访问限定符各不相同)。如果加上了访问限定符后,就表示要匹配的类、成员变量或成员函数的定义中必须包含这些限定符。如果在限定符前面加上感叹号“!”,则刚好相反,定义中必须不包含这些限定符。
事实上还可以加上对特定类型注释(Annotation)的限定条件,但一般用不到,这里就不再多说了。
作为例子,我们可以看看Android SDK中已经为我们预定义的一些ProGuard规则。这些规则保证一般的Android应用不需要任何配置就可以使用ProGuard进行混淆,并且混淆后的代码还可以无错误的运行,具体解释请看注释:
#两个特定的类不能被混淆和删除
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
#所有包含JNI调用的类以及其内部的成员都不能被混淆
-keepclasseswithmembernames class * {
native &methods&;
#扩展自android.view.View类的任何public类的setter和getter方法都不能被混淆和删除
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
#扩展自android.app.Activity类的任何类中访问属性是public,返回值是void,参数是android.view.View类型的所有函数都不能被混淆或删除
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
#任何枚举类中的values和valueOf静态方法都不能被混淆和删除
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
#实现了android.os.Parcelable接口类的任何类,以及其内部定义的Creator内部类类型的public final静态成员变量,都不能被混淆和删除
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
#所有自动生成的R类中的public静态成员变量
-keepclassmembers class **.R$* {
public static &fields&;
}最后总结一下,ProGuard是一个非常方便的代码混淆工具。只需要在你的项目开发过程中,花一点点时间将其集成进去,并稍微多做一下测试,就可以起到很好的效果,可以极大的增加破解的难度,建议大家多多使用。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:234099次
积分:2896
积分:2896
排名:第11165名
原创:63篇
评论:153条
(2)(1)(2)(2)(2)(4)(4)(4)(2)(4)(4)(4)(4)(4)(2)(1)(1)(3)(8)(6)}

我要回帖

更多关于 proguard配置文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信