學習Android的代碼混淆


學習路線:

1.看developer對於代碼混淆的介紹:http://developer.android.com/tools/help/proguard.html. 很短,大概20分鍾看完(我只看了ant編譯的部分)。核心點:

a, 背景。原來proguard不僅是代碼混淆,還能通過去掉無用代碼減少代碼體積,對代碼做優化

b, 一定要記得,為每個release版本保存mapping.txt! 非常重要,否則可能無法還原之前版本的trace!

c,具體的proguard使用,參見http://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.html

 

2. 去看proguard手冊:http://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.html。 導讀:

a,"Input/output options” 這一節要看完。估計花費15分鍾

b,重點看-keep Options.花點時間把class specification這部分看完。其他部分可以暫時不看。看到這里,對於基本的規則已經比較清楚了,那么問題來了,對於android,有沒有一套一般性的規則呢?哪些class要keep住?

看到這里不得不罵一下谷歌,文檔居然沒提這茬。 再看看proguard的example:https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/examples.html

這里面重要的幾句話:

Most importantly, we're keeping all fundamental classes that may be referenced by the AndroidManifest.xml file of the application. If your manifest file contains other classes and methods, you may have to specify those as well. ------在manifest中提到的class要keep。例如activity,broadcastreceiver, service, contentprovider等等。

We're keeping annotations, since they might be used by custom RemoteViews --------remoteview沒用過,不知道有何影響

We're keeping any custom View extensions and other classes with typical constructors, since they might be referenced from XML layout files.  -------在layout中可能引用的類要keep

We're also keeping the required static fields in Parcelable implementations, since they are accessed by introspection. --------實現parceble的要keep住. 因為傳遞參數后要還原parceble對象的一些內部成員

If applicable, you should add options for processing native methodscallback methodsenumerations, and resource files. --------native,回調等要keep住。估計這些類並沒有明顯的被調用,怕被優化時誤殺。

View的幾種構造函數也要保護,因為他們在代碼中並沒有顯式地被調用。

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

 可以總結出需要被keep的類/方法/字段的原則:

1, 在XML等外部配置文件中引用名字的。原因:如果是類之間相互引用,proguard是知道的,被混淆后也可以找到類,但是外部引用proguard是不知道的。如果被proguard混淆了,外部引用就找不到對應類了

2,在代碼中沒有顯式調用的函數(就是你用“open call hierarchy"結果為空的),比如native方法,系統回調,反射的函數,改了名字后就找不到類了。

接下來,實際動手執行混淆。可以在網上找個模板上,然后以此為基礎稍加改動。模板例子:http://blog.csdn.net/lovexjyong/article/details/24652085

實際調試過程中遇到的問題:

1,自帶的ADT工具中,proguard是4.7版本的,其中支持JDK 8有問題,自己在sourceforge上下載了proguard 5.x,將bin和lib拷貝到ADT proguard對應目錄下,搞定。

2,不知道哪個類庫引用了com.jboss和org.joda下的類,proguard報告警,用-dontwarn org.jboss.** -dontwarn org.joda.** 搞定。

3. 遇到報錯 [java.lang.IllegalArgumentException] (Value is not a reference value。。。。 google之,是proguard的一個bug,增加這句搞定:-optimizations !class/unboxing/enum

4. 遇到報錯

[dx] Uncaught translation error: com.android.dx.cf.code.SimException: local variable type mismatch: attempt to set or access a value of type java.lang.Object using a local variable of type int. This i
s symptomatic of .class transformation tools that ignore local variable information

google了一下,沒有找到明確答案,但是確認是由優化引起的。先把-dontoptimize加上,發現OK,然后再去掉,發現通過了。。。不知道解決的原因。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM