Jean同窗的Proguard私房物語

      因爲項目中自主研發的一個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此包。html

 

      好啦,下面咱們就要用本文的主角proguard對這個abc_dex2jar.jar進行混淆,開始寫混淆配置文件,準備好了嘛?
      開門見山,請先寫下面倆配置參數,告訴proguard咱們準備混淆哪一個jar包,而且打算把混淆出來的jar包擱在哪
       -injars abc_dex2jar.jar

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

 

      咱們的工具庫之因此在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看起來猶抱琵琶半遮面,又能爲人民服務。android

      proguard是個很霸道的傢伙,若是你在方法聲明時throws Exception,它在混淆優化過程當中會默認把你throws的exception吃抹乾淨,好比public void method() throws Exception直接就給變成了public void method(),這個帶來的後果仍是滿嚴重的,可添加如下配置參數防止這種狀況發生: -keepattributes Exceptions   ubuntu

      code中依賴的第三方包能夠選擇不混淆,你都用了別人的包,還給別人的包混淆上,你這私有欲也忒重了吧,因此請選擇配置參數,以第三方包junit舉例-keep class junit.**{*;}
    
      當你的工具包被外部程序調用時,被調用的接口方法名必然是不能混淆的,否則編譯器沒法找到對應的接口方法,咱們能夠不混淆該方法名,而混淆該方法內部的code實現,例如CLAZZA中的methoda方法須要保留方法名:-keepclasseswithmembernames class CLAZZA{*** methoda(...);}

      至此爲止,經過以上教程寫出一個主流的混淆配置文件應該不成問題了,如您想了解更多更詳細的配置參數內容,請移步官網http://proguard.sourceforge.net/index.html#/manual/usage.htmlapi

      最後,給咱寫好的混淆配置文件起個名myconfig.pro,調用java -jar proguard.jar @myconfig.pro執行混淆,因爲配置混淆後的文件輸出文件路徑爲-outjars '/home/jean/adbc_pro.jar',那麼,混淆後的jar包就生成在該路徑。工具

      用jdgui展示一下勞動成果吧,曾經書寫美妙的代碼轉眼變得抽象寫意,滿城滿是「a,b,c,d」。
相關文章
相關標籤/搜索