代碼混淆與反射的沖突


from://http://blog.csdn.net/musicvs/article/details/7948627

代碼混淆與反射的沖突



編譯Android的代碼,大部分人都知道了,防反編譯的方法也大部分都知道了(盡管它不一定一直有效,但起碼像我這種水平的人,沒辦法看到混淆之后的Java代碼, 最可惡的是沒有注釋= =)。

最近才發現,我的代碼在很久之后設置了混淆,也在很久之前不知道什么時候不小心把代碼混淆給弄沒了(好吧,你可以去反編譯我的項目了,我不介意,因為代碼很爛,實在是爛)。

於是,這兩個又在搞混淆代碼了,混淆代碼的方法很簡單:
1.在項目下新建一個文件,命名為“proguard.cfg”,正常情況下包括以下內容:

-optimizationpasses 5

-dontusemixedcaseclassnames

-dontskipnonpubliclibraryclasses

-dontpreverify

-verbose

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Application

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class * extends android.app.backup.BackupAgentHelper

-keep public class * extends android.preference.Preference

-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {

    native <methods>;

}

-keepclasseswithmembers class * {

    public <init>(android.content.Context, android.util.AttributeSet);

}

-keepclasseswithmembers class * {

    public <init>(android.content.Context, android.util.AttributeSet, int);

}

-keepclassmembers enum * {

    public static **[] values();

    public static ** valueOf(java.lang.String);

}

-keep class * implements android.os.Parcelable {

  public static final android.os.Parcelable$Creator *;

}



2.后編輯項目下的“project.properties”文件,在最后加上一句:proguard.config=proguard.cfg

OK,大功告成,記住了,只有打包的時候代碼才會混淆,直接運行項目然后去bin目錄下找的那個apk包是不會混淆的。


么簡單的事情,當然就不會特意來這分享了~
我想說說我遇到的問題,那就是,當代碼混淆遇上Java反射時,一堆麻煩來了。


==============別睡着了啊,真正的問題來了============

是的,我們會發現,Java的反射再也找不到它想找的類,或者方法,或者屬性了。
是的,因為代碼混淆的原因,原本的類名、方法名、屬性名都改變了,而反射它還是按照原來的名字去反射,結果只能射出一個程序崩潰。

決的方法當然有~
那就是,讓和反射有關的那些代碼或者類,不進行混淆,那就不會有上述的問題了~!

看看proguard.cfg文件,里面那么多代碼,不可能沒有用的,來,先隨便整一句看看:

-keep public class * extends android.app.Activity



簡單的,這句話的意思是,保留所有繼承Activity的類,不進行混淆。來,馬上舉一反三:

-keep public class com.mutou.test.HelloWorld


句更加簡單了,保留HelloWorld,不進行混淆。

注意了,所有的類必須指出完整的包路徑(廢話了,這個文件里又沒有import語句,當然要完整路徑了,不然它哪知道那個類在哪兒~)。

不進行混淆的意思就是,當我們的android項目的代碼被反編譯工具反編譯出來之后,代碼看起來不會像天書一樣,不會所有變量名、方法名都變成a、b、c、d什么的。

注意了,有一個比較糾結的地方,一定要小心,通過上面兩種方式防止混淆的代碼,並不代表,反編譯之后和源碼一模一樣,它的類名什么的都和源碼一樣,但是變量名、方法名就不一定了,它也有可能是abcd什么的。這個我也不知道為嘛。總之,小心就是了。

也正因為如此,在有反射的代碼里(吶,別問我什么叫做反射啊,我只是要用的時候百度了一下,現在已經忘了具體用法了),不能通過以上兩種方式來防止代碼混淆。



==============真正的主題在不華麗的分割線下面============
,沒有辦法了嗎?
有啊~木了個頭的,沒有辦法我就不來發帖了~~

嘻嘻,看看:

-keepclasseswithmembernames class com.kogame.god.thing.creature.**
{
*;
}


糕~這個有點復雜,別着急~
先看看這個名字:keepclasseswithmembernames 顧名思義,就是保留類以及它的成員的名字。
那花括號里面那個”*;”又是什么東西呢?它代表類里的所有成員(包括變量、方法)的名字都不會被混淆,都保留原汁原味的樣子。

於是,整段代碼的意思就是,保留所有繼承creature類的代碼以及它的變量和方法,不進行混淆。

好喇~~
謝謝觀賞。

如果沒有聽懂的,請移步(更簡單明了詳細而不復雜的文章):
http://www.apkbus.com/android-57338-1-1.html


免責聲明!

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



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