Android混淆——了解這些就夠了

Csdn

混淆介紹

Proguard是一個Java類文件壓縮器、優化器、混淆器、預校驗器。壓縮環節會檢測以及移除沒有用到的類、字段、方法以及屬性。優化環節會分析以及優化方法的字節碼。混淆環節會用無意義的短變量去重命名類、變量、方法。這些步驟讓代碼更精簡,更高效,也更難被逆向(破解)。

混淆后默認會在工程目錄app/build/outputs/mapping/release(debug)下生成一個mapping.txt文件,這就是混淆規則,我們可以根據這個文件把混淆后的代碼反推回源本的代碼,所以這個文件很重要,注意保護好。原則上,代碼混淆后越亂越無規律越好,但有些地方我們是要避免混淆的,否則程序運行就會出錯。

ProGuard常用操作

  • 后面有備注Proguard官方文檔,其他騷操作自行查看即可

  • 壓縮(Shrinking):默認開啟,用以減小應用體積,移除未被使用的類和成員,并且會在優化動作執行之后再次執行(因為優化后可能會再次暴露一些未被使用的類和成員)。

      -dontshrink #關閉壓縮
    
  • 優化(Optimization):默認開啟,在字節碼級別執行優化,讓應用運行的更快。

      -dontoptimize  #關閉優化
      -optimizationpasses n  #表示proguard對代碼進行迭代優化的次數,Android一般為5
    
  • 混淆(Obfuscation):默認開啟,增大反編譯難度,類和類成員會被隨機命名,除非用keep保護。

      -dontobfuscate  #關閉混淆
    
  • 一顆星表示只是保持該包下的類名,而子包下的類名還是會被混淆;

      -keep class com.thc.test.*
    
  • 兩顆星表示把本包和所含子包下的類名都保持;

      -keep class com.thc.test.**
    

(上面兩種方式保持類后,會發現類名雖然未混淆,但里面的具體方法和變量命名還是變了)

  • 既可以保持該包下的類名,又可以保持類里面的內容不被混淆;

      -keep class com.thc.test.*{*;}
    
  • 既可以保持該包及子包下的類名,又可以保持類里面的內容不被混淆;

      -keep class com.thc.test.**{*;}
    
  • 保持某個類名不被混淆(但是內部內容會被混淆)

      -keep class com.xlpay.sqlite.cache.BaseDaoImpl
    
  • 保持某個類的 類名及內部的所有內容不會混淆

      -keep class com.xlpay.sqlite.cache.BaseDaoImpl{*;}
    
  • 保持類中特定內容,而不是所有的內容可以使用如下:

      -keep class com.thc.gradlestudy.MyProguardBean{
          <init>; #匹配所有構造器
          <fields>;#匹配所有域
          <methods>;#匹配所有方法
      }
    

    上面就保持住了MyProguardBean這個類中的所有的構造方法、變量、和方法

  • 可以在<fields>或<methods>前面加上private 、public、native等來進一步指定不被混淆的內容

      -keep class com.xlpay.sqlite.cache.BaseDaoImpl{
          public <methods>;#保持該類下所有的共有方法不被混淆
          public *;#保持該類下所有的共有內容不被混淆
          private <methods>;#保持該類下所有的私有方法不被混淆
          private *;#保持該類下所有的私有內容不被混淆
          public <init>(java.lang.String);#保持該類的String類型的構造方法
      }
    
  • 在方法后加入參數,限制特定的方法(經測試:僅限于構造方法可以混淆)

      -keep class com.thc.gradlestudy.MyProguardBean{
          public <init>(String);
      }
    
  • 要保留一個類中的內部類不被混淆需要用 $ 符號

      #保持ProguardTest中的MyClass不被混淆
      -keep class com.xlpay.sqlite.cache.ProguardTest$MyClass{*;}
    
  • 使用Java的基本規則來保護特定類不被混淆,比如用extends,implement等這些Java規則,如下:保持Android底層組件和類不要混淆

      -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.view.View
    
  • 如果不需要保持類名,只需要保持該類下的特定方法保持不被混淆,需要使用keepclassmembers,而不是keep,因為keep方法會保持類名。

      #保持ProguardTest類下test(String)方法不被混淆
      -keepclassmembernames class com.xlpay.sqlite.cache.ProguardTest{
          public void test(java.lang.String);
      }
    
  • 如果擁有某成員,保留類和類成員

      -keepclasseswithmembernames class com.xlpay.sqlite.cache.ProguardTest
    

注意事項

  • jni方法不可混淆,因為native方法是要完整的包名類名方法名來定義的,不能修改,否則找不到;

      #保持native方法不被混淆
      -keepclasseswithmembernames class * {    
          native <methods>; 
      }
    
  • 反射用到的類混淆時需要注意:只要保持反射用到的類名和方法即可,并不需要將整個被反射到的類都進行保持

  • AndroidMainfest中的類不混淆,所以四大組件和Application的子類和Framework層下所有的類默認不要進行混淆。自定義的View默認也不會被混淆

  • 與服務端交互時,使用GSON、fastjson等框架解析服務端數據時,所寫的JSON對象類不混淆,否則無法將JSON解析成對應的對象;

  • 使用第三方開源庫或者引用其他第三方的SDK包時,如果有特別要求,也需要在混淆文件中加入對應的混淆規則;

  • 有用到WebView的JS調用也需要保證寫的接口方法不混淆,原因和第一條一樣;

  • Parcelable的子類和Creator靜態成員變量不混淆,否則會產生Android.os.BadParcelableException異常;

      -keep class * implements Android.os.Parcelable { 
          # 保持Parcelable不被混淆            
          public static final Android.os.Parcelable$Creator *;
      }
    
  • 使用enum類型時需要注意避免以下兩個方法混淆,因為enum類的特殊性,以下兩個方法會被反射調用,見第二條規則。

      -keepclassmembers enum * {  
          public static **[] values();  
          public static ** valueOf(java.lang.String);  
      }
    
  • 建議:

    發布一款應用除了設minifyEnabled為ture,你也應該設置zipAlignEnabled為true,像Google Play強制要求開發者上傳的應用必須是經過zipAlign的,zipAlign可以讓安裝包中的資源按4字節對齊,這樣可以減少應用在運行時的內存消耗。

混淆情況記錄:

例子中使用:classA和classB,在加混淆的情況下多種結果:

  1. 如果classA沒有被keep,則不會看到classA的class文件

  2. 如果classA沒有被keep,classB被保持,同時classB引用到了classA,這個時候能夠看到被混淆的classA的class文件,如顯示為a

  3. 如果classA中通過反射,獲取到classB,那么classB的類名及反射用到的方法必須keep住

  4. jar包混淆,暴露出的類、方法、方法的參數需要keep住

  5. 情況說明:工程Demo依賴了 小米渠道的依賴,小米依賴又依賴了Common,對Common進行混淆但是不對小米渠道混淆,那么小米的依賴中使用到的Common中的類都需要keep住

參考內容

Proguard官方文檔

參考

可能還參考了別的,但是沒有注明,不好意思了,給忘記了,google吧

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容