標籤:android 混淆
混淆器(ProGuard)
---
混淆器通過刪除從未用過的代碼和使用晦澀名字重新命名類、欄位和方法,對代碼進行壓縮,最佳化和混淆。結果是一個比較小的.apk檔案,該檔案比較難進行逆向工程。因此,當你的應用程式對安全敏感(要求高),例如當你授權應用程式的時候,混淆器是一種重要的保護手段。
混淆器被整合在android 構建系統中,所以你不必手動調用它。同時混淆器僅在發布模式下進行構建應用程式的時候才會運行起來,所以在偵錯模式下構建程式時,你不必處理混淆代碼。讓混淆器運行起來是可選擇的,但是推薦選上。
Android項目中的混淆非常簡單,之所以寫這篇總結是因為最近發現公司的代碼竟然沒有混淆,反編譯後代碼隨手可得。非常震驚。
1. 修改project.properties
```xml
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# 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-19
```
將proguard.config前面的注釋去掉
2. 修改proguard-project.txt
```xml
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
```
如果在程式中使用了第三方的`jar`包,在混淆後導致出錯,這時我們需要在proguard-project.txt中去進行相應的配置,來讓其在混淆時不要混淆相應的jar包。對改設定檔中的相關配置解釋如下:
```java
-keep public class * extends android.app.Activity 【不進行混淆類名的類,保持其原類名和包名】
-keep public abstract interface com.asqw.android.Listener{
public protected <methods>; 【所有public protected的方法名不進行混淆】
}
-keep public class com.asqw.android{
public void Start(java.lang.String); 【對該方法不進行混淆】
}
-keepclasseswithmembernames class * { 【對所有類的native方法名不進行混淆】
native <methods>;
}
-keepclasseswithmembers class * { 【對所有類的指定方法的方法名不進行混淆】
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclassmembers class * extends android.app.Activity {【對所有類的指定方法的方法名不進行混淆】
public void *(android.view.View);
}
-keepclassmembers enum * {【對枚舉類型enum的所有類的以下指定方法的方法名不進行混淆】
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {【對實現了Parcelable介面的所有類的類名不進行混淆,對其成員變數為Parcelable$Creator類型的成員變數的變數名不進行混淆】
public static final android.os.Parcelable$Creator *;
}
-keepclasseswithmembers class org.jboss.netty.util.internal.LinkedTransferQueue {【對指定類的指定變數的變數名不進行混淆】
volatile transient org.jboss.netty.util.internal.LinkedTransferQueue$Node head;
volatile transient org.jboss.netty.util.internal.LinkedTransferQueue$Node tail;
volatile transient int sweepVotes;
}
-keep public class com.unionpay.** {*; }【對com.unionpay包下所有的類都不進行混淆,即不混淆類名,也不混淆方法名和變數名】
```
經過上面這兩部之後反編譯後就能混淆了,但是四大組件還在,為什麼四大組件還在呢,因為四大組件是在資訊清單檔中進行配置的,如果混淆後就不能根據資訊清單檔的配置去尋找了。
如果對於一些自己的代碼中要想提供出來讓別人通過反射調用的方法時,我們不想讓部分代碼被混淆,或者是我們使用別人提供的第三方jar包,因為第三方的jar包一般都是已經混淆過的,我們要是再混淆就會報錯了,所以我們要保證這些內容不用混淆,這裡我們只需修改這個檔案,然後加上後面的一句話,他就不會混淆我們給出的內容
```xml
-keepattributes *Annotation*
-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.BackupAgent
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService
-keep class com.itheima.mobilesafe.engine.AppInfoProvider
-keep class net.youmi.android.** {
*;
}
Android代碼混淆