Android開發實踐:利用ProGuard進行代碼混淆

來源:互聯網
上載者:User

標籤:proguard   android   反編譯   

由於Android的代碼大都是Java代碼,所以挺容易被反編譯的,好在Android ADT為我們整合了混淆代碼的工具,一來可以混淆我們的代碼,讓程式被反編譯後基本看不懂,另外還能起到代碼最佳化的作用。發布項目前,建議開啟Android的代碼混淆功能。


Android ADT主要通過ProGuard工具來提供代碼混淆,網上也有挺多部落格文章講這個的,但感覺很多都介紹得太過於複雜,這裡我就以問答的方式來更加簡潔地介紹下ProGuard吧。


1. ProGuard是什麼


ProGuard是一個工具,用來混淆和最佳化Java代碼。


工作方式:移除無效的代碼,將代碼中的類名、函數名替換為晦澀難懂的名字。


注意,它只能混淆Java代碼,Android工程中Native代碼,資源檔(圖片、xml),它是無法混淆的。


2. 如何開啟ProGuard


修改Android工程根目錄下的project.properties檔案,把proguard.config=....這一行前面的注釋“#”去掉。


這一行指定了系統預設的proguard設定檔,位於Android SDK/tools/proguard目錄下。


當然,你也可以自己編寫設定檔,但不建議這樣做,因此系統預設的配置已經涵蓋了許多通用的細節,如果你還有額外的配置,可以添加在 proguard-project.txt 檔案中。


注意: 只有在產生release版本的apk時,混淆配置才會起作用,debug版本的apk不會進行混淆。


3. 哪些內容需要手動設定


系統預設的配置已經涵蓋了大部分的內容,但是如果你的工程中有如下內容,則需要手動添加配置到proguard-project.txt檔案中。


(1) 只在 AndroidManifest.xml 引用的類

(2) 通過JNI回調方式被調用的函數

(3) 運行時動態調用的函數或者成員變數

(4) 當然,如果你不確定哪些需要手動設定,可以以預設的配置產生程式,當運行中發現ClassNotFoundException異常時,即可找到哪個類不該被混淆。


4. 手動設定的規則


手動添加的配置,一般以“-keep”開頭,常用的配置命令分別樣本如下:


假設Android工程中有一個介面和一個類:


package com.ticktick.example;                                                                                                                                                                                                                                                                                                                                                       public interface TestInterface {    public void test();}                                                                                                                                                                                                                                                                                                                                        public class Test {                                                                                                                                                                                                                                                                                                                                                private String mTestString;    private final int mMinValue;    private final int mMaxValue;                                                                                                                                                                                                                                                                                                                                                  public Test( int min, int max){        mMinValue = min;        mMaxValue = max;    }                                                                                                                                                                                                                                                                                                                                                            public int getMinValue() {        return mMinValue;    }                                                                                                                                                                                                                                                                                                                                                       public int getMaxValue() {        return mMaxValue;    }                                                                                                                                                                                                                                                                                                                                                       public void setTestString(String testStr ) {        mTestString = testStr;    }}


(1) 不混淆某個類的建構函式


例如:不混淆Test類的建構函式:


-keepclassmembers classcom.ticktick.example.Test {    public <init>(int,int);}


(2) 不混淆某個包所有的類或指定的類


例如,不混淆package com.ticktick.example下的所有類/介面

-keep class com.ticktick.example.** { * ; }

例如,不混淆com.ticktick.example.Test類:

-keep class com.ticktick.example.Test { * ; }

如果希望不混淆某個介面,則把上述命令中的class替換為interface即可。


(3) 不混淆某個類的特定的函數


例如:不混淆com.ticktick.example.Test類的setTestString函數:

-keepclassmembers classcom.ticktick.example.Test {    public void setTestString(java.lang.String);}


(4) 不混淆某個類的子類,某個介面的實現


例如:不混淆com.ticktick.example.Test類的子類

-keep public class * extends com.ticktick.example.Test

例如:不混淆com.ticktick.example.TestInterface的實現

-keep class * implementscom.ticktick.example.TestInterface {    public static final com.ticktick.example.TestInterface$Creator *;}


(5) 添加第三方依賴包


例如:添加android-support-v4.jar依賴包

-libraryjarslibs/android-support-v4.jar-dontwarnandroid.support.v4.**{*;}-keep class android.support.v4.**{*;}-keep interface android.support.v4.**{*;}


注意: 需要添加dontwarn,因為預設情況下proguard會檢查每一個引用是否正確,但是第三方庫裡往往有些不會用到的類,沒有正確引用,所以如果不配置的話,系統會報錯。


5. 混淆後的調試資訊解析


當代碼混淆之後,輸出的Log資訊也會帶有混淆內容,比如函數名和類名會被替換為晦澀難懂的名字,而與代碼中的不一致。


因此,ProGuard工具還提供了恢複混淆內容的工具和檔案。


當你開啟了ProGuard混淆後,每次產生release版的apk時,Andriod工程的根目錄下會對應產生一個proguard檔案夾,該檔案夾下的mapping.txt檔案記錄了混淆後的名字與混淆前的名字的對應關係,通過該檔案,我們反向得到恢複後的Log資訊。


假設Log檔案名稱為log.txt,則恢複混淆的命令為:

$retrace.sh -verbose mapping.txt log.txt

注1:retrace.sh命令位於 <sdk_root>/tools/proguard/目錄下

注2:你需要儲存每一個release版本的mapping.txt,因為每一次release的混淆結果和映射關係都不一樣。


關於Android的代碼混淆我就總結到這兒了,你也可以去ProGuard的官方網頁上擷取關於ProGuard更加詳細的介紹,有任何疑問歡迎留言或者來信[email protected]交流。

   

本文出自 “對影成三人” 部落格,請務必保留此出處http://ticktick.blog.51cto.com/823160/1413066

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.