Jean同学的Proguard私房物语

醉酒当歌 提交于 2019-12-01 06:44:53
      由于项目中自主研发的一个Android平台工具库需要提供给外部人员使用,我们决定使用android sdk自带的proguard tool混淆源码。在动用了google之后得到的大量资源文中,拨云见雾、去糟存精,融会贯通理论于实践,自我成长之余制作以下proguard源码混淆独家宝典。
      无耻的分割线----------------------------------------------------------------------------------------------------------------------

      本文是以项目中进行混淆的步骤以及其间遇到的问题为主线,行文略乱,洁癖er轻拍。

      1. proguard工具身藏Android sdk何处: android-sdks/tools/proguard/
      推荐使用lib文件夹下的proguard.jar,从命令行启动该工具“java -jar .../lib/proguard.jar @混淆配置文件” 对代码进行混淆;图形界面proguardgui.jar在win下启动正常,ubuntu11.10启动失败( 没空追踪失败原因,放弃之, 读者若有兴趣可自行研究)

      2. 上一条中的“混淆配置文件”是个神奇的好东东,在混淆的道路上起着举足轻重综合协调承前启后的作用,不好意思,我墨迹了,我只是想强调它的重要性。proguard这玩意虽然开源,但工作起来丝毫不含糊,高效霸气,不过如果配置不得当,人家会陡然傲娇,您的代码混淆完之后生成的混淆包里可能空然无物。

       下面将结合项目案例具体说明制作过程:
       菜料 :在本人项目中需要被混淆的是一个在Android平台源码中编译得到的jar包
       烹具:proguard工具一枚
       辅助工具:jdgui、dex2jar

       首先来加工在android ICS源码下编译得到的jar包,此jar并非为标准java平台下生成的jar包,Android编译系统将所有的class字节码转化为dex文件,第一个辅助工具登场:dex2jar,顾名思义,这是一个将Android 的 Dalvik Executable (.dex) format 文件转成 Java 类文件的工具,若想详细了解此open source project,请猛击http://code.google.com/p/dex2jar/。

       command:dex2jar abc.jar,会自动在abc.jar所在目录下生成一个abc_dex2jar.jar,即为转换后的标准jar包,当然你可以任意rename此包。

 

      好啦,下面我们就要用本文的主角proguard对这个abc_dex2jar.jar进行混淆,开始写混淆配置文件,准备好了嘛?
      开门见山,请先写下面俩配置参数,告诉proguard我们准备混淆哪个jar包,并且打算把混淆出来的jar包搁在哪
       -injars abc_dex2jar.jar

       -outjars '/home/jean/adbc_pro.jar'

 

      我们的工具库之所以在Android平台源码环境下编译,是因为依赖了源码中的若干jar包,而这些是Android sdk所不能提供的,所以这些依赖包我们要一一添置到libraryjars这个参数。一定要添加全部,不然在混淆编译的过程中会报“找不到叉叉类文件”的错。
       -libraryjars lib/android.test.runner.jar
       -libraryjars lib/core.jar
       -libraryjars lib/framework.jar
       -libraryjars lib/junit.jar
       -libraryjars lib/emma.jar   
       proguard这个小王子其实还是蛮难伺候的,在你自认为配置好所有编译依赖的包之后,编译过程中会出一些始料未及的warnings,如果你确定一定以及肯定这跟你编译所依赖的包无关,请加上-ignorewarnings,因为warnings在proguard这个洁癖er看来还是挺严重的,会导致build fail.  
       以下配置选项请酌情添加
       -dontoptimize #proguard在做混淆的时候,会对一些代码进行优化,若遇到一些相对复杂的方法时,可能会抛出errors。对付的办法是增加配置参数-dontoptimize
       -dontusemixedcaseclassname #混淆时不会产生形形色色的类名,没试出来有什么用,备选
       -dontshrink #proguard在做混淆之前最开始会默认对代码进行压缩,为了增加反编译的难度可以选择不压缩
       -overloadaggressively #混淆时应用侵入式重载 ,混淆后名字变的很长
       -useuniqueclassmembernames #把混淆类中的方法名也混淆了,keep类中一些不需要keep的类的方法名也混淆了
       -include {filename}    #从给定的文件中读取配置参数
       -dontskipnonpubliclibraryclasses  #指定不去忽略非公共的库类 

   

      身为一个码工,当你辛辛苦苦的劳动成果指不定在哪天被别人恣意挪用篡改,是不是会有一股莫名的占有欲油然而升,是不是想把自己的code全部混淆让那些反编译工具都玩儿蛋去?不过......如果你的code混淆成这幅模样,估计连他的好盆友编译器都要不认识它了,而由你的code所提供出来的api接口能被谁拿去调用呢,只能在风中孤自飘零了。所以,得饶人处且饶人,proguard为您提供了保留选项参数(也就是配置代码中哪些部分不需要混淆),可以使你的code看起来犹抱琵琶半遮面,又能为人民服务。

      proguard是个很霸道的家伙,如果你在方法声明时throws Exception,它在混淆优化过程中会默认把你throws的exception吃抹干净,比如public void method() throws Exception直接就给变成了public void method(),这个带来的后果还是满严重的,可添加以下配置参数防止这种情况发生: -keepattributes Exceptions  

      code中依赖的第三方包可以选择不混淆,你都用了别人的包,还给别人的包混淆上,你这私有欲也忒重了吧,所以请选择配置参数,以第三方包junit举例-keep class junit.**{*;}
    
      当你的工具包被外部程序调用时,被调用的接口方法名必然是不能混淆的,不然编译器无法找到对应的接口方法,我们可以不混淆该方法名,而混淆该方法内部的code实现,例如CLAZZA中的methoda方法需要保留方法名:-keepclasseswithmembernames class CLAZZA{*** methoda(...);}

      至此为止,通过以上教程写出一个主流的混淆配置文件应该不成问题了,如您想了解更多更详细的配置参数内容,请移步官网http://proguard.sourceforge.net/index.html#/manual/usage.html

      最后,给咱写好的混淆配置文件起个名myconfig.pro,调用java -jar proguard.jar @myconfig.pro执行混淆,由于配置混淆后的文件输出文件路径为-outjars '/home/jean/adbc_pro.jar',那么,混淆后的jar包就生成在该路径。

      用jdgui展现一下劳动成果吧,曾经书写美妙的代码转眼变得抽象写意,满城尽是“a,b,c,d”。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!