Android Apk的反編譯與代碼混淆


一、反編譯

1.獲取工具:
  既然是反編譯,肯定要用到一些相關的工具,工具可以到這里下載,里面包含三個文件夾,用於反編譯,查看反編譯之后的代碼;
  其實這兩工具都是google官方出的,也可在google code上下載 dex2jarapktool

2-1.反編譯獲取Java源代碼:
  將要反編譯的apk文件后綴改為zip並解壓,得到classes.dex,它就是java文件編譯再通過dx工具打包而成的,將classes.dex復制到apk2java目錄下的dex2jar-0.0.9.9文件夾;在命令行下進入dex2jar-0.0.9.9文件夾,輸入命令:dex2jar.bat classes.dex,會生成一個jar文件classes_dex2jar.jar,用工具包中jdgui工具即可查看代碼;

2-2.反編譯獲取程序的源代碼和圖片、XML配置、語言資源等文件:
  打開apk2java文件夾,進入apktool1.4.1,里面有三個文件aapt.exeapktool.batapktool.jar;
  在命令行下定位到apktool1.4.1文件夾,輸入命令:apktool.bat  d  abc123.apk  abc123;后兩個參數分別是apk所在位置,反編譯后代碼存放位置;下面是我反編譯QQ得到的AndroidManifest.xml文件的內容,輸入命令為:apktool.bat d c:\qq.apk c:\qq;

 

2-3.將反編譯出來的文件重新打包:同樣,在apktool1.4.1文件夾下,輸入命令:apktool.bat b c:\qq c:\\qq表示需要重新打包的文件所在的位置;

  等待生成,生成的文件在qq/dist文件夾下,當然,這個程序是不能使用的,因為沒有簽名;關於簽名后面會有講述;

3.圖形化反編譯:
  在工具包中,還有一個文件夾Androidfby,里面包含兩個圖形化反編譯工具,其本質上就是對dex2jar和apktool兩個工具進行了一層包裝,使之有一個圖形化的操作界面;

  
  

二、代碼混淆

  前面說了反編譯,我們當然不希望我們的應用被別人反編譯,所以就得在打包的時候進行代碼混淆,這樣的包也可反編譯出代碼,但是代碼的可讀性很低,從而達到保護代碼的目的;
  在我們新建的項目中,都有一個proguard-project.txt文件,默認里面是沒有任何配置的,只有一些說明性的注釋文字;我們就是能過它,來進行代碼混淆的,首先需要為該文件添加需要混淆的代碼說明;

 -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>;
 }

 -keepclasseswithmembernames class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }

 -keepclasseswithmembernames 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 *;
 }
  在上面的腳本文件混淆中,保留了繼承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本組件以及com.android.vending.licensing.ILicensingService,並保留了所有的Native變量名及類名,所有類中部分以設定了固定參數格式的構造函數,枚舉等等。(詳細信息請參考android-sdk\tools\proguard\examples中的例子及注釋。)
  最后,在project.properties文件中,添加對proguard-project.txt文件的引用: proguard.config=proguard-project.txt
  下面是一個代碼混淆過后的apk反編譯之后得到的代碼,可以看出,如果給你一個這樣的jar文件,你如何去讀取整理它的代碼?
  
 
>>延伸擴展:
1。當程序中有使用第三方jar包時,常常需要過濾掉反射的R文件及jar包,以及防止讀取jar包是出現讀取錯誤、防止因為警告導致打包不成功等等問題;
  -keep class **.R$* {   *;  }   過濾R文件
  -keep class packagename.** {*;}   過濾第三方包(packagename為第三方包的包名)
  -libraryjars libs/mmbilling.jar   防止讀取第三方jar包時讀取內容錯誤
  -dontwarn android.net.http.**   不提示讀取某個包的警告
2。當混淆打包的apk文件上有bug時,我們一般所用的統計平台所收集到的錯誤信息也是混淆之后的代碼信息,我們自身也看不明白了,這種情況下可以單獨把某個類提取出來,不進行混淆;參考上面對繼承了Activity的類的保留方法,對單個個別的類進行保留;
  
三、程序打包簽名
  生成keystore,生成keystore有兩種方式,一是在eclipse中生成,還有一種是在命令行中生成,在這里我只說在命令行中生成;
  • 打開命令行窗口,進入jdk文件夾下面的bin目錄,輸入命令:keytool -genkey -v -keystore android.keystore -alias android.keystore -keyalg RSA -validity 20000
  • 接下來會讓輸入一個keystore文件的屬性配置,輸入合法的屬性就行,最后會讓確認信息是否正確,輸入y,創建keystore完成;
  • 對未簽名的程序進行簽名:jarsigner -verbose -keystore appkey.keystore -signedjar c:\test_signed.apk c:\test_unsign.apk your_alias
  • 進入apk所在文件目錄:jarsigner -verbose -keystore appkey.keystore -storepass xoxopassword -signedjar test_signed.apk -digestalg SHA1 -sigalg MD5withRSA test_unsign.apk your_alias
可能遇到的問題:找不到xx的證書鏈。xx必須引用包含專用密鑰和相應的公共密鑰證書鏈的有效密鑰庫密鑰條目。
這個問題一般是簽名的別名寫錯了,可以通過如下的命令查看keystore文件的別名(前提是要在jdk所在文件夾下面的bin目錄);
keytool -list  -v -keystore xxxx.keystore -storepass (password密碼)
 
 
 
 
 


免責聲明!

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



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