fwrite

fwrite

twitter
github
email

混淆

混淆#

官網

原理#

Java 是一種跨平台的、解釋型語言,Java 源代碼編譯成中間” 字節碼” 存儲於 class 文件中。由於跨平台的需要,Java 字節碼中包括了很多源代碼信息,如變量名、方法名,並且通過這些名稱來訪問變量和方法,這些符號帶有許多語義信息,很容易被反編譯成 Java 源代碼。為了防止這種現象,我們可以使用 Java 混淆器對 Java 字節碼進行混淆。

混淆就是對發布出去的程序進行重新組織和處理,使得處理後的代碼與處理前代碼完成相同的功能,而混淆後的代碼很難被反編譯,即使反編譯成功也很難得出程序的真正語義。被混淆過的程序代碼,仍然遵照原來的檔案格式和指令集,執行結果也與混淆前一樣,只是混淆器將代碼中的所有變量、函數、類的名稱變為簡短的英文字母代號,在缺乏相應的函數名和程序註釋的況下,即使被反編譯,也將難以閱讀。同時混淆是不可逆的,在混淆的過程中一些不影響正常運行的信息將永久丟失,這些信息的丟失使程序變得更加難以理解。

混淆器的作用不僅僅是保護代碼,它也有精簡編譯後程序大小的作用。由於以上介紹的縮短變量和函數名以及丟失部分信息的原因, 編譯後 jar 文件體積大約能減少 25% ,這對當前費用較貴的無線網絡傳輸是有一定意義的。

語法#


-include {filename}    從給定的文件中讀取配置參數 
-basedirectory {directoryname}    指定基礎目錄為以後相對的檔案名稱 
-injars {class_path}    指定要處理的應用程序jar,war,ear和目錄 
-outjars {class_path}    指定處理完後要輸出的jar,war,ear和目錄的名稱 
-libraryjars {classpath}    指定要處理的應用程序jar,war,ear和目錄所需要的程序庫文件 
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的庫類。 
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可見的庫類的成員。

保留選項 
-keep {Modifier} {class_specification}    保護指定的類文件和類的成員 
-keepclassmembers {modifier} {class_specification}    保護指定類的成員,如果此類受到保護他們會保護的更好
-keepclasseswithmembers {class_specification}    保護指定的類和類的成員,但條件是所有指定的類和類成員是要存在。 
-keepnames {class_specification}    保護指定的類和類的成員的名稱(如果他們不會壓縮步驟中刪除) 
-keepclassmembernames {class_specification}    保護指定的類的成員的名稱(如果他們不會壓縮步驟中刪除) 
-keepclasseswithmembernames {class_specification}    保護指定的類和類的成員的名稱,如果所有指定的類成員出席(在壓縮步驟之後) 
-printseeds {filename}    列出類和類的成員-keep選項的清單,標準輸出到給定的文件 

壓縮 
-dontshrink    不壓縮輸入的類文件 
-printusage {filename} 
-whyareyoukeeping {class_specification}     

優化 
-dontoptimize    不優化輸入的類文件 
-assumenosideeffects {class_specification}    優化時假設指定的方法,沒有任何副作用 
-allowaccessmodification    優化時允許訪問並修改有修飾符的類和類的成員 

混淆 
-dontobfuscate    不混淆輸入的類文件 
-printmapping {filename} 
-applymapping {filename}    重用映射增加混淆 
-obfuscationdictionary {filename}    使用給定文件中的關鍵字作為要混淆方法的名稱 
-overloadaggressively    混淆時應用侵入式重載 
-useuniqueclassmembernames    確定統一的混淆類的成員名稱來增加混淆 
-flattenpackagehierarchy {package_name}    重新包裝所有重命名的包並放在給定的單一包中 
-repackageclass {package_name}    重新包裝所有重命名的類文件中放在給定的單一包中 
-dontusemixedcaseclassnames    混淆時不會產生形形色色的類名 
-keepattributes {attribute_name,...}    保護給定的可選屬性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. 
-renamesourcefileattribute {string}    設置源文件中給定的字符串常量

文件#

mapping.txt

混淆前後的代碼的對照表,使用它進行日記排查,反編譯等。

dump.txt

描述 apk 內所有 class 文件的內部結構

seed.txt

列出沒有被混淆的類和成員

usage.txt

列出源代碼中被刪除,在 apk 中不存在的代碼

常見問題#

1、Proguard returned with error code

  • 更新 proguard 版本

  • android-support-v4 不進行混淆

  • 添加缺少相應的庫

2、使用 gson 包解析數據時,出現 missing type parameter 異常

  • 在 proguard.cfg 中添加

-dontobfuscate
-dontoptimize

  • 在 proguard.cfg 中添加
# removes such information by default, so configure it to keep all of it.         
-keepattributes Signature         
# Gson specific classes        
-keep class sun.misc.Unsafe { *; }                          
#-keep class com.google.gson.stream.** { *; }   
# Application classes that will be serialized/deserialized over Gson                           
-keep class com.google.gson.examples.android.model.** { *; }    

3、類型轉換錯誤

-keepattributes Signature

4、空指針異常

混淆過濾掉相關類與方法

5、java.lang.NoSuchMethodError

沒有相關方法,方法被混淆了,混淆過濾掉相關方法便可

Bug 查找:http://proguard.sourceforge.net/index.html#manual/troubleshooting.html

注意#

  • 反射不能被混淆
  • 系統接口不能被混淆
  • Jni 接口不能被混淆
  • 還有一些特殊的,需要定制的
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。