1. android代碼混淆以及怎麼判斷一個apk代碼是否被混淆過
1、proguard原理
java代碼編譯成二進制class文件,這個class文件也可以反編譯成源代碼,除了注釋外,其他的code基本都可以看到。為了防止重要code被泄露,我們往往需要混淆,即把方法名,變數名,類名,包名等這些java元素的名稱改成讓人意想不到的名稱,這樣代碼結構就沒有變化,還可以運行,但是想弄懂代碼的架構卻很難。proguard就起到了這樣的作用:
一、它可以分析一組class的結構,根據用戶的配置,然後把這些class文件中可以混淆的java元素進行混淆
二、刪除無效的代碼
三、對代碼進行優化(使用adt插件導出的apk,還進行zipalign優化)
預設情況下,proguard會混淆所有代碼,但是下面幾種情況是不能改變java元素的名稱,否則就會導致程序出錯。
一、用到反射的地方(android中的api常用@hide注釋掉,開發者在調用相應的方法時,需要用到反射)
二、當app的代碼要依賴於系統的介面時,如被系統代碼調用的回調方法,這種方法比較復雜
三、java元素名稱是配置文件中配置好的
所以在使用proguard時,我們需要有個配置文件告訴proguard,哪些java元素是不能混淆的。
2、proguard配置
-dontwarn預設proguard會檢查每一個引用是否正確,但是第三方庫里往往有些不會用到的類,沒有正確引用,如果不配置的話,系統就會報錯。
-keep指定的類和類成員被保留作為入口
-keepclassmembes指定的類成員被保留。
-keepclasswithmembers指定的類和類成員被保留,假如指定的類成員存在的話。
2. android項目對apk進行混淆
混淆apk是一個很基礎的工作,博客上也有一堆介紹,本文提供一下這類工作的解決思路。在安卓源碼下面和android studio裡面的做法差異不大,本文以android源碼舉例。
首先在對應mk文件裡面添加proguard enabled的語句,系統有一個自帶的build/core/proguard.flags,默認是使用這個文件,而且一般項目默認是關閉的,這也是有原因的。因為這里的proguard.flags是沒有針對app的配置的,使用默認的混淆,app很有可能就不工作了。
添加了mk文件修改之後,在Android.mk同級根目錄創建本app自有的proguard.flags。新增內容如下,這里需要注意,網上很多demo,基本分為三部分,一部是保留app基礎功能部分的內容不混淆;2是保持app對外介面,例如get、set、isxx、AIDL、public、native層的介面或者類;3.是第三方jar包或介面。混淆的基本原理就是將上訴類或介面進行統一簡單字母的替換,如果改變了這些對外介面的名字,很有可能被別人使用的時候就找不到對應哦介面
一些第三方的庫如何不進行混淆,這個根據項目特點,可以自行搜索,比如網路的地圖包什麼的。
然後是如何驗證和解決混淆過程遇到的問題,因為是對介面名進行替換,如果出現混淆問題的話,log裡面一定會有類似
這個時候只需要對相關介面進行例外(-keep)即可,然後用android-studio,直接打開或者dex2jar進行反解可以看到相關的介面是否被簡單替換。
3. android 混淆 什麼意思
Android代碼混淆,是為了你的apk被他人反編譯之後拿到源碼,如果你混淆了,那反編譯後的apk所有的java類都被改成了a.java/c.java之類的文件名,類裡面的屬性也變成abc之類的了,想拿到你的源碼就不可能了,直接在gradle(app)文件的android節點下加上下邊代碼。
buildTypes{
release{
minifyEnabledfalse
('proguard-android.txt'),'proguard-rules.pro'
}
}
4. Android項目里如何混淆自己打的jar包或者防止被反編譯
Android之防止反編譯技巧:
1. 判斷程序是否運行在模擬器上
boolean isRunningInEmualtor() {
boolean qemuKernel = false;
Process process = null;
DataOutputStream os = null;
try{
process = Runtime.getRuntime().exec("getprop ro.kernel.qemu");
os = new DataOutputStream(process.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
os.writeBytes("exit\n");
os.flush();
process.waitFor();
// getprop ro.kernel.qemu == 1 在模擬器
// getprop ro.proct.model == "sdk" 在模擬器
// getprop ro.build.tags == "test-keys" 在模擬器
qemuKernel = (Integer.valueOf(in.readLine()) == 1);
Log.d("com.droider.checkqemu", "檢測到模擬器:" + qemuKernel);
} catch (Exception e){
qemuKernel = false;
Log.d("com.droider.checkqemu", "run failed" + e.getMessage());
} finally {
try{
if (os != null) {
os.close();
}
process.destroy();
} catch (Exception e) {
}
Log.d("com.droider.checkqemu", "run finally");
}
return qemuKernel;
}
2. 檢測keystore簽名,再與之前得做比較
public int getSignature(String packageName) {
PackageManager pm = this.getPackageManager();
PackageInfo pi = null;
int sig = 0;
try {
pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
Signature[] s = pi.signatures;
sig = s[0].hashCode();
} catch (Exception e1) {
sig = 0;
e1.printStackTrace();
}
return sig;
}
3. 檢測包名,版本名和版本號,然後做判斷:
private String getAppInfo() {
try {
String pkName = this.getPackageName();
String versionName = this.getPackageManager().getPackageInfo(
pkName, 0).versionName;
int versionCode = this.getPackageManager()
.getPackageInfo(pkName, 0).versionCode;
return pkName + " " + versionName + " " + versionCode;
} catch (Exception e) {
}
return null;
}
4. 把jpg圖片寫成是png格式得圖片 但是最新版本的apktool已經修復了
5. 花指令,影響jd-gui 但是最新版本的jd-gui已經修復
private static final char[] wJ = "0123456789abcdef".toCharArray();
public static String imsi = "204046330839890";
public static String p = "0";
public static String keyword = "電話";
public static String tranlateKeyword = "%E7%94%B5%E8%AF%9D";
在每個類裡面加入 如上欄位。。。。
https://***/ 一個第三方得」愛加密「網站 1.需要使用官方的打包key工具打包後上傳到"愛加密"網站進行處理,然後到網站上面下載,下載後還要用"愛加密"的打包工具再次進行打包即可。
5. Android濡備綍浠g爜娣鋒穯錛岄槻姝apk紼嬪簭琚鍙嶇紪璇
涓嬮潰鍏蜂綋璇翠竴璇存庝箞鏍瘋㏒DK2.3涓嬬殑proguard.cfg鏂囦歡璧蜂綔鐢錛屽厛鏉ョ湅鐪媋ndroid-sdk-windows\tools\lib\proguard.cfg鐨勫唴瀹癸細view plain 1. -optimizationpasses 5 2. -dontusemixedcaseclassnames 3. - 4. -dontpreverify 5. -verbose 6. -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 7. 8. -keep public class * extends android.app.Activity 9. -keep public class * extends android.app.Application 10. -keep public class * extends android.app.Service 11. -keep public class * extends android.content.BroadcastReceiver 12. -keep public class * extends android.content.ContentProvider 13. -keep public class * extends android.app.backup.BackupAgentHelper 14. -keep public class * extends android.preference.Preference 15. -keep public class com.android.vending.licensing.ILicensingService 16. 17. -keepclasseswithmembernames class * { 18. native <methods>; 19. } 20. 21. -keepclasseswithmembernames class * { 22. public <init>(android.content.Context, android.util.AttributeSet); 23. } 24. 25. -keepclasseswithmembernames class * { 26. public <init>(android.content.Context, android.util.AttributeSet, int); 27. } 28. 29. -keepclassmembers enum * { 30. public static **[] values(); 31. public static ** valueOf(java.lang.String); 32. } 33. 34. -keep class * implements android.os.Parcelable { 35. public static final android.os.Parcelable$Creator *; 36. } 浠庤剼鏈涓鍙浠ョ湅鍒幫紝娣鋒穯涓淇濈暀浜嗙戶鎵胯嚜Activity銆丼ervice銆丄pplication銆丅roadcastReceiver銆丆ontentProvider絳夊熀鏈緇勪歡浠ュ強com.android.vending.licensing.ILicensingService錛 騫朵繚鐣欎簡鎵鏈夌殑Native鍙橀噺鍚嶅強綾誨悕錛屾墍鏈夌被涓閮ㄥ垎浠ヨ懼畾浜嗗滻瀹氬弬鏁版牸寮忕殑鏋勯犲嚱鏁幫紝鏋氫婦絳夌瓑銆) 璁﹑roguard.cfg璧蜂綔鐢ㄧ殑鍋氭硶寰堢畝鍗曪紝灝辨槸鍦╡clipse鑷鍔ㄧ敓鎴愮殑default.properties鏂囦歡涓鍔犱笂涓鍙モ減roguard.config=proguard.cfg鈥濆氨鍙浠ヤ簡 瀹屾暣鐨刣efault.properties鏂囦歡搴旇ュ備笅錛歷iew plain 1. # This file is automatically generated by Android Tools. 2. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3. # 4. # This file must be checked in Version Control Systems. 5. # 6. # To customize properties used by the Ant build system use, 7. # "build.properties", and override values to adapt the script to your 8. # project structure. 9. 10. # Project target. 11. target=android-9 12. proguardproguard.config=proguard.cfg 澶у姛鍛婃垚錛屾e父鐨勭紪璇戠懼悕鍚庡氨鍙浠ラ槻姝浠g爜琚鍙嶇紪璇戜簡銆
6. android混淆打包 功能不能用
ProGuard來進行混淆打包,大大的優化Apk包的大小。但是注意ProGuard對文件路徑的名名很有講究,不支持括弧,也不支持空格。在混淆過後,可以在工程目錄的proguard中的mapping.txt看到混淆後的類名,方法名,變數名和混淆前的類名,方法名,變數名。
在使用Eclipse新建一個工程,都會在工程目錄下生產配置project.properties和proguard-project.tx。
#
To
enable
ProGuard
to
shrink
and
obfuscate
your
code,
uncomment
this
(available
properties:
sdk.dir,
user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
#
Project
target.
target=android-10
project.properties用於配置Android工程的一些屬性,#號的話表示當前行是注釋,這里的proguard.config就用於指定ProGuard的混淆配置文件,並對使用release方式打包應用程序時開啟代碼混淆功能。對於是否是使用release方式打包,和AndroidManifest.xml中application的android:debuggable屬性有很多關系。如果該值為android:debuggable="true",那麼最終就是debug方式打包。最明智的方式就是在AndroidManifest.xml並不顯示的指定它,而是是打包工具在打包時來決定它最終的值。對於ant就是ant
release或ant
debug。而對於直接在Eclipse中使用run
或debgu來打包的話就是debug,使用export的話就是release.
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
這里的話指定了混淆的基本配置文件proguard-android.txt,和混淆的個性化配置文件proguard-project.txt。