Android 混淆代碼,優(yōu)化

一介褥、為什么進(jìn)行混淆

Java 是一種跨平臺的座掘、解釋型語言,Java 源代碼編譯成中間”字節(jié)碼”存儲于 class 文件中柔滔。由于跨平臺的需要溢陪,Java 字節(jié)碼中包括了很多源代碼信息,如變量名睛廊、方法名形真,并且通過這些名稱來訪問變量和方法,這些符號帶有許多語義信息超全,很容易被反編譯成 Java 源代碼咆霜。為了防止這種現(xiàn)象,我們可以使用 Java 混淆器對 Java 字節(jié)碼進(jìn)行混淆嘶朱。

通過代碼混淆可以將項(xiàng)目中的類蛾坯、方法、變量等信息進(jìn)行重命名疏遏,變成一些無意義的簡短名字偿衰,同時(shí)也可以移除未被使用的類挂疆、方法、變量等下翎。所以直觀的看缤言,通過混淆可以提高程序的安全性,增加逆向工程的難度视事,同時(shí)也有效縮減了apk的體積胆萧。

二、原理

對發(fā)布出去的程序進(jìn)行重新組織和處理俐东,使得處理后的代碼與處理前代碼完成相同的功能跌穗,而混淆后的代碼很難被反編譯,即使反編譯成功也很難得出程序的真正語義虏辫。被混淆過的程序代碼蚌吸,仍然遵照原來的檔案格式和指令集,執(zhí)行結(jié)果也與混淆前一樣砌庄,只是混淆器將代碼中的所有變量羹唠、函數(shù)、類的名稱變?yōu)楹喍痰挠⑽淖帜复柭ィ谌狈ο鄳?yīng)的函數(shù)名和程序注釋的況下佩微,即使被反編譯,也將難以閱讀萌焰。同時(shí)混淆是不可逆的哺眯,在混淆的過程中一些不影響正常運(yùn)行的信息將永久丟失,這些信息的丟失使程序變得更加難以理解扒俯。

三奶卓、如何進(jìn)行混淆

Android SDK 自帶了混淆工具Proguard。它位于<Android SDK目錄>/tools/proguard下面撼玄。

proguard 就是可以把方法夺姑,字段,包和類這些java 元素的名稱改成無意義的名稱互纯,這樣代碼結(jié)構(gòu)沒有變化瑟幕,還可以運(yùn)行磕蒲,但是想弄懂代碼的架構(gòu)卻很難的混淆工具留潦。它可以分析一組class 的結(jié)構(gòu),根據(jù)用戶的配置辣往,然后把這些class 文件的可以混淆java 元素名混淆掉兔院。在分析class 的同時(shí),他還有其他兩個(gè)功能站削,刪除無效代碼(Shrinking 收縮)坊萝,和代碼進(jìn)行優(yōu)化 (Optimization Options)。

如果開啟了混淆,Proguard默認(rèn)情況下會(huì)對所有代碼十偶,包括第三方包都進(jìn)行混淆菩鲜,可是有些代碼或者第三方包是不能混淆的,這就需要我們手動(dòng)編寫混淆規(guī)則來保持不能被混淆的部分惦积。

直接在android項(xiàng)目的build.gradle 文件中配置就可以混淆代碼了:

android {
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

1> 代碼混淆:
配置如 minifyEnabled true接校。

代碼混淆包括4個(gè)步驟:壓縮, 優(yōu)化狮崩, 混淆蛛勉, 預(yù)校驗(yàn)。

①壓縮(shrink):移除無用的類睦柴,類的成員诽凌,方法,屬性等坦敌;

②優(yōu)化(optimize):分析和優(yōu)化二進(jìn)制代碼侣诵,根據(jù)Proguard-android-optimize.txt 中的描述,優(yōu)化可能會(huì)造成一定的風(fēng)險(xiǎn)恬试,不能保證在所有版本上的Dalvik正常運(yùn)行窝趣。因此android項(xiàng)目建議關(guān)閉該項(xiàng)。

③混淆(obfuscate):把類名训柴,屬性名哑舒,方法名替換為簡短且無意義的名稱:使用a、b幻馁、c洗鸵、d這樣簡短而無意義的名稱,對類仗嗦、字段和方法進(jìn)行重命名膘滨。

④預(yù)校驗(yàn)(previrfy):添加預(yù)校驗(yàn)信息。這個(gè)預(yù)校驗(yàn)是作用在java平臺的稀拐,android平臺不需要這個(gè)功能火邓,去掉之后還可以加快混淆速度。因此android項(xiàng)目關(guān)閉該功能德撬。

這4個(gè)流程默認(rèn)是開啟的铲咨,我們需要在android的混淆配置文件中關(guān)閉代碼優(yōu)化和預(yù)校驗(yàn)功能,即 -dontoptimize蜓洪, -dontpreverify纤勒。(在 proguard-android.txt中默認(rèn)已經(jīng)關(guān)閉了這2項(xiàng))

2> 資源混淆(刪除沒有引用資源):

配置如 shrinkResources true÷√矗可以減少apk的大小摇天,一般建議開啟粹湃。

在應(yīng)用構(gòu)建打包的過程中自動(dòng)刪除沒有引用的資源,對依賴的庫同樣有效泉坐。shrinkResources必須和minifyEnabled配合使用達(dá)到減少包體積的作用为鳄,只有刪除了無用的代碼之后,才能知道哪些資源是無用的腕让。

資源處理包括2個(gè)流程:合并資源济赎,移除資源;

android studio打包時(shí)會(huì)自動(dòng)merge資源记某,不受參數(shù)控制司训。

移除資源,需要配置參數(shù)液南。(建議可以先用lint自行過一遍)

四壳猜、默認(rèn)基本混淆配置

  • proguard-android.txt代表系統(tǒng)默認(rèn)的混淆規(guī)則配置文件,該文件在<Android SDK目錄>/tools/proguard下滑凉,這里面是一些比較常規(guī)的不能被混淆的代碼規(guī)則统扳。一般不要更改該配置文件,因?yàn)橐矔?huì)作用于其它項(xiàng)目畅姊,除非你能確保所做的更改不影響其它項(xiàng)目的混淆咒钟。
  • proguard-rules.pro代碼表當(dāng)前project的混淆配置文件,是針對我們自己的項(xiàng)目需要特別定義混淆規(guī)則若未。它在app module下朱嘴,可以通過修改該文件來添加適用當(dāng)前項(xiàng)目的混淆規(guī)則。

在<Android SDK目錄>/tools/proguard/proguard-android.txt這個(gè)文件在Android Gradle插件2.2+以上不再不再維護(hù)和使用了粗合。相反萍嬉,Android Gradle插件在構(gòu)建時(shí)生成默認(rèn)規(guī)則,并將它們存儲在build目錄中隙疚。所以說現(xiàn)在混淆的默認(rèn)規(guī)則是由Gradle自動(dòng)生成的壤追。(例如:...\build\intermediates\proguard-files\proguard-android.txt-4.2.2這個(gè)文件就是gradle版本生成的,在新版本中供屉,通過 proguardFiles getDefaultProguardFile('proguard-android.txt')獲取到的就是這個(gè)文件中的混淆規(guī)則

系統(tǒng)的proguard-android.txt 中內(nèi)容:

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

# 混淆時(shí)不使用大小寫混合類名
-dontusemixedcaseclassnames
# 不跳過library中的非public的類
-dontskipnonpubliclibraryclasses
# 打印混淆的詳細(xì)信息
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
# 關(guān)閉優(yōu)化(原因見上邊的原英文注釋)
-dontoptimize
# 不進(jìn)行預(yù)校驗(yàn)行冰,可加快混淆速度
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

# 保留注解中的參數(shù)
-keepattributes *Annotation*
# 不混淆如下兩個(gè)谷歌服務(wù)類
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
# 不混淆包含native方法的類的類名以及native方法名
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
# 不混淆View中的setXxx()和getXxx()方法,以保證屬性動(dòng)畫正常工作
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
# 不混淆Activity中參數(shù)是View的方法伶丐,例如悼做,一個(gè)控件通過android:onClick="clickMethodName"綁定點(diǎn)擊事件,混淆后會(huì)導(dǎo)致點(diǎn)擊事件失效
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
# 不混淆枚舉類中的values()和valueOf()方法
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 不混淆Parcelable實(shí)現(xiàn)類中的CREATOR字段撵割,以保證Parcelable機(jī)制正常工作
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

# 不混淆R文件中的所有靜態(tài)字段贿堰,以保證正確找到每個(gè)資源的id
-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
# 不對android.support包下的代碼警告(如果我們打包的版本低于support包下某些類的使用版本辙芍,會(huì)出現(xiàn)警告的問題)
-dontwarn android.support.**

# Understand the @Keep support annotation.
# 不混淆Keep類
-keep class android.support.annotation.Keep

# 不混淆使用了注解的類及類成員
-keep @android.support.annotation.Keep class * {*;}

# 如果類中有使用了注解的方法啡彬,則不混淆類和類成員
-keepclasseswithmembers class * {
    @android.support.annotation.Keep <methods>;
}

# 如果類中有使用了注解的字段羹与,則不混淆類和類成員
-keepclasseswithmembers class * {
    @android.support.annotation.Keep <fields>;
}

# 如果類中有使用了注解的構(gòu)造函數(shù),則不混淆類和類成員
-keepclasseswithmembers class * {
    @android.support.annotation.Keep <init>(...);
}

五庶灿、混淆配置的語法

可以從上面的代碼中看出proguard-android.txt主要作用是防止指定內(nèi)容被混淆纵搁,其中使用了以-開頭,結(jié)合keep類關(guān)鍵字往踢,*腾誉、<>等通配符的語法。

下面我們來看看混淆相關(guān)項(xiàng):

1> 混淆常見關(guān)鍵字:

關(guān)鍵字 含義
keep 保留 類和類成員峻呕,防止混淆或移除
keepnames 保留 類和類和類成員利职,防止被混淆,但是沒有引用的類成員會(huì)被移除
keepclassmembers 只保留 類成員瘦癌,防止混淆或移除
keepclassmembernames 只保留 類成員猪贪,防止混淆,但沒有引用的類成員會(huì)被移除
keepclasseswithmembers 保留 類和類成員 讯私,防止被混淆或移除热押,如果指定的類成員不存還是會(huì)被混淆
keppclasseswithmembernames 保留 類和類成員,防止被混淆斤寇,如果指定類成員不存在還是會(huì)被混淆桶癣,沒有被引用的類成員會(huì)被移除
dontwarn dontwarn 基本和keep同時(shí)出現(xiàn),尤其是在引入 library時(shí)娘锁,為了忽略library的警告牙寞,保證build的正常進(jìn)行

-dontwarn 主要是避免警告,-keep 主要是保留不被混淆</pre>

2> 相關(guān)通配符:

通配符 含義
* 匹配任意長度字符莫秆,但不包含分隔符 . 捞稿。例如一個(gè)類全路徑是com.heytap.test.demo瓶堕,使用com.heytap.test .* 就可以匹配,但是com.heytap.* 就不能匹配
** 匹配任意長度字符,并包含分隔符 . 滔岳。例如: com.heytap.test.**可以匹配包下的所有內(nèi)容
*** 匹配任意參數(shù)類型。例如: *** getName(***)可以匹配String getName (String)
... 匹配任意長度的任意參數(shù)類型澡绩。 例如: void setName(...) 可以匹配 void setName(String name0,String name1,String name2)
<fileds> 匹配類豹爹、接口中所有字段
<methods> 匹配類、接口中所有方法
<init> 匹配所有的構(gòu)造函數(shù)

六党巾、混淆注意問題

混淆配置官方文檔:gradle example

下面是關(guān)于混淆配置時(shí)要注意的問題:

1萎庭、運(yùn)用了反射的類也不進(jìn)行混淆。因?yàn)榇a混淆齿拂,類名驳规、方法名、屬性名都改變了署海,而反射它還是按照原來的名字去反射吗购,結(jié)果程序崩潰医男。

2、注解不能混淆捻勉。因?yàn)樽⒔庖灿玫搅薺ava反射镀梭,所以不能混淆。

3踱启、Activity不能混淆报账。因?yàn)锳ndroidManifest.xml文件中是完整的名字

4、自定義View不能混淆埠偿。因?yàn)楸籄ndroid Resource 文件引用到的透罢,名字已經(jīng)固定,也不能混淆冠蒋。自定義view是帶了包名寫在xml布局中的琐凭。

5、使用了 Gson 之類的工具要使 JavaBean 類即實(shí)體類不能混淆浊服。因?yàn)閖son轉(zhuǎn)換用到了java反射统屈。

6、泛型不能混淆牙躺。

7愁憔、自定義控件類的get/set方法和構(gòu)造函數(shù)不能混淆。

8孽拷、內(nèi)部類吨掌,如果會(huì)被外部調(diào)用到,那么也不能混淆脓恕。

9膜宋、使用了枚舉要保證枚舉不被混淆

10、對第三方庫中的類不進(jìn)行混淆

11炼幔、不混淆任何包含native方法的秋茫,否則找不到本地方法。

12乃秀、屬性動(dòng)畫兼容庫不能混淆肛著。

13、在引用第三方庫的時(shí)候跺讯,一般會(huì)標(biāo)明庫的混淆規(guī)則的枢贿,建議在使用的時(shí)候就把混淆規(guī)則添加上去,免得到最后才去找

14刀脏、有用到 WebView 的 JS 調(diào)用也需要保證寫的接口方法不混淆局荚,原因和第一條一樣

15、Parcelable 的子類和 Creator 靜態(tài)成員變量不混淆,否則會(huì)產(chǎn)生 Android.os.BadParcelableException 異常

16耀态、不混淆Rxjava/RxAndroid

17轮傍、對于Android APP來說四大組件和Application不能混淆。現(xiàn)在的系統(tǒng)已經(jīng)配置為混淆時(shí)候會(huì)保留Android系統(tǒng)組件

18茫陆、數(shù)據(jù)庫驅(qū)動(dòng)

19、其他Anroid 官方建議 不混淆的擎析,如
android.app.backup.BackupAgentHelper
android.preference.Preference
com.android.vending.licensing.ILicensingService

注意:如果你的Android SDK Tools版本足夠高(>24)簿盅,那么在proguard-rules.pro文件其實(shí)不用做任何改動(dòng),因?yàn)镚oogle已經(jīng)幫我們在proguard-android.txt文件配置好了(如果較低就把下面代碼拷貝到proguard-android.txt中)揍魂。

混淆代碼配置參考:

1.>不混淆桨醋,需要保留的東西:

#保留了繼承自Activity、Application這些類的子類
#因?yàn)檫@些子類有可能被外部調(diào)用
#比如第一行就保證了所有Activity的子類不要被混淆
-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 * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService

#如果有引用android-support-v4.jar包现斋,可以添加下面這行
-keep public class com.null.test.ui.fragment.** {*;}

#保留Activity中的方法參數(shù)是view的方法喜最,
#從而我們在layout里面編寫onClick就不會(huì)影響
-keepclassmembers class * extends android.app.Activity {
public void * (android.view.View);
}

# 保留自定義控件(繼承自View)不能被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set(*);
*** get
();
}

# 保留Serializable 序列化的類不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

對于帶有回調(diào)函數(shù)onXXEvent的,不能混淆

-keepclassmembers class * {
void *(**On*Event);
}

2.>第三方和自己的bean文件是不需要混淆:
-keep public class com.heytap.test.yourBeanPackageName.** {
//全部忽略
*;
}
-keep public class com.heytap.test.yourBeanPackageName.** {
//忽略get和set方法
public void set*(***);
public ***get*();
public *** is*();
}
//以上兩種任意一種都行

3.>內(nèi)部類混淆處理:
-keep class com.heytap.test.MainActivity$* {
*;
}

4.>避免泛型混淆:
-keepattribute Signature

5.>帶有throws的混淆:

-keepattribute Exceptions

七庄蹋、代碼混淆方案

1.組件化混淆

在創(chuàng)建一個(gè)Android Module的時(shí)候瞬内,在Module的build.gradle,會(huì)生成 proguard-android-optimize.txt 和 proguard-rules.pro限书。

配置如下:

    buildTypes {
        release { minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
       defaultConfig {         ...       
            consumerProguardFiles 'consumer-rules.pro'  
  }
  • proguardFiles配置的proguard文件不會(huì)被打進(jìn)aar中虫蝶,只作用于庫文件代碼,只在編譯發(fā)布aar的時(shí)候有效倦西。
  • consumerProguardFiles配置的proguard會(huì)被打進(jìn)aar包中能真,在你將庫文件作為一個(gè)模塊添加到app模塊中后,庫文件中consumerProguardFiles配置的proguard文件則會(huì)追加到app模塊的Proguard配置文件中扰柠,作用于整個(gè)app代碼粉铐。

1> 混淆方案1:在app模塊中管理所有的混淆規(guī)則

優(yōu)點(diǎn):所有混淆規(guī)則在app模塊的proguard-rule.pro文件中統(tǒng)一管理

缺點(diǎn):移除某些模塊后,需手動(dòng)移除app模塊中的混淆規(guī)則卤档。理論上混淆規(guī)則添加多了不會(huì)造成崩潰或者編譯不通過蝙泼,但是會(huì)影響編譯效率

2> 混淆方案2:各個(gè)組件模塊各自管理混淆規(guī)則

優(yōu)點(diǎn):將混淆文件解耦到每個(gè)模塊中,并且不會(huì)影響編譯效率

組件化混淆解耦:

我們可以將固定的第三方混淆放到common模塊的consumer-rules.pro文件中劝枣,每個(gè)模塊獨(dú)有的第三方引用庫混淆放到各自的consumer-rules.pro文件中踱承,在app模塊的proguard-rule.pro文件中放入Android通用的混淆聲明,如四大組件和全局的混淆等配置哨免。這樣可以最大限度的完成混淆解耦操作茎活。

2.SDK代碼混淆

SDK代碼的混淆方案和組件化混淆方案大致相同,sdk代碼一般會(huì)經(jīng)過兩次混淆過程:

1> 內(nèi)部混淆

主要是將相關(guān)核心代碼混淆琢唾,將對外暴露的類keep住载荔,混淆配置文件寫proguardFiles配置文件中。

2>外部混淆

當(dāng)外部依賴我們的SDK時(shí)采桃,開啟混淆后懒熙,也會(huì)使得SDK內(nèi)部的類被混淆丘损,可能會(huì)導(dǎo)致反射調(diào)用報(bào)ClassNotFoundException異常,所以我們需要將這些需要反射的類keep住工扎,這些混淆配置需要寫在SDK內(nèi)部的consumerProguardFiles配置文件中徘钥,這樣我們在外部業(yè)務(wù)方就不需要再次配置混淆文件了。

特別注意:

①我們在開發(fā)SDK的時(shí)候經(jīng)常會(huì)用到compileOnly這樣的依賴方式肢娘,通過這種依賴方式引用SDK呈础,SDK內(nèi)部consumerProguardFiles配置的proguard也會(huì)被引入

② 在打包aar的過程中,consumerProguardFiles中的混淆配置規(guī)則不對aar混淆起作用橱健。

八而钞、混淆后奔潰調(diào)試

當(dāng)項(xiàng)目混淆代碼后,安裝release版本的apk到手機(jī)有時(shí)根本運(yùn)行不起來拘荡,有時(shí)啟動(dòng)了瞬間崩潰臼节,其實(shí)原因很簡單我們應(yīng)用的庫或者第三方j(luò)ar被混淆了導(dǎo)致無法正常調(diào)用,那怎么查找是哪些不該混淆了的被混淆了珊皿?

在Android studio 中生成release包的同時(shí) build\outputs\mapping\release文件夾下也生成了4個(gè)文件:

① configuration.txt :總的混淆規(guī)則网缝。這個(gè)文件包含了打包過程中所有混淆規(guī)則的匯總。

② mapping.txt :列出了原始的類蟋定,方法途凫,和字段名與混淆后代碼之間的映射。

③ seeds.txt :列出了未被混淆的類和成員溢吻。

④ usage.txt : 列出了從apk中刪除的代碼维费。

一般情況下,我們直接看mapping 和seeds這2個(gè)文件夾就可以了促王,在調(diào)試過程中犀盟,使用notedpad打開mapping文件,有時(shí)日志比較多蝇狼,可能將近幾萬行阅畴。

mapping文件記錄了所有的混淆前后的映射關(guān)系。比如:你安裝運(yùn)行apk迅耘,根本跑步起來贱枣。你檢查mapping會(huì)有可能發(fā)現(xiàn) 是你把不應(yīng)該混淆的第三方包給混淆了,在mapping文件的映射中第三方包 也變成abc了颤专,這里就是出錯(cuò)的根本纽哥,一一找出,在proguard-rules.pro中-dontwarn 包名栖秕,-keep class 包名 就可以順利解決春塌。幾萬行并不是讓你一行一行去看的,點(diǎn)擊對應(yīng)包的關(guān)鍵字滾動(dòng)查看。一一過濾只壳。

seeds文件夾是幫你查看是否需要混淆的類沒有被混淆俏拱,當(dāng)然都是可以修改的,查看過程中會(huì)有errormessage,搜索一下吼句,看看是否有不應(yīng)該混淆的被你混淆掉锅必。

也可以使用工具查看報(bào)錯(cuò)問題:

<SDK目錄>\tools\proguard\bin下的proguardgui.bat腳本將Crash堆棧信息還原到混淆前的狀態(tài)。步驟如下

①雙擊打開腳本惕艳,選擇左邊的ReTrace選項(xiàng)

②選擇Mapping file文件搞隐,也就是混淆后打包后在app module/build/outputs/mapping/release下生成的mapping.txt

③拷貝混淆后的堆棧信息

④點(diǎn)擊右下角的ReTrace!按鈕,完成Crash堆棧信息的追溯

如下圖中間部分就是追溯到的原Crash堆棧信息:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尔艇,一起剝皮案震驚了整個(gè)濱河市尔许,隨后出現(xiàn)的幾起案子么鹤,更是在濱河造成了極大的恐慌终娃,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒸甜,死亡現(xiàn)場離奇詭異棠耕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)柠新,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門窍荧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恨憎,你說我怎么就攤上這事蕊退。” “怎么了憔恳?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵瓤荔,是天一觀的道長。 經(jīng)常有香客問我钥组,道長输硝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任程梦,我火速辦了婚禮点把,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屿附。我一直安慰自己郎逃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布挺份。 她就那樣靜靜地躺著衣厘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上影暴,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天错邦,我揣著相機(jī)與錄音,去河邊找鬼型宙。 笑死撬呢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妆兑。 我是一名探鬼主播魂拦,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搁嗓!你這毒婦竟也來了芯勘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤腺逛,失蹤者是張志新(化名)和其女友劉穎荷愕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棍矛,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡安疗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了够委。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荐类。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茁帽,靈堂內(nèi)的尸體忽然破棺而出玉罐,到底是詐尸還是另有隱情,我是刑警寧澤潘拨,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布吊输,位于F島的核電站,受9級特大地震影響战秋,放射性物質(zhì)發(fā)生泄漏璧亚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一脂信、第九天 我趴在偏房一處隱蔽的房頂上張望癣蟋。 院中可真熱鬧,春花似錦狰闪、人聲如沸疯搅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幔欧。三九已至罪治,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間礁蔗,已是汗流浹背觉义。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浴井,地道東北人晒骇。 一個(gè)月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像磺浙,于是被迫代替她去往敵國和親洪囤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容

  • APK的混淆分為資源混淆與代碼混淆.一般大部分都使用兩者結(jié)合.尤其是目前主流的應(yīng)用. 其中的優(yōu)點(diǎn): 防止被惡意破解...
    會(huì)剝皮的貓閱讀 1,349評論 2 1
  • 什么是代碼混淆 代碼混淆就是將代碼中的各種元素撕氧,如變量瘤缩,方法,類和包的名字改寫成無意義的名字伦泥,增加項(xiàng)目反編譯后被讀...
    蝸牛家族史閱讀 5,160評論 1 4
  • 混淆規(guī)則 因?yàn)锳ndroid是使用Java開發(fā)的剥啤,所以開發(fā)者可以使用ProGuard對代碼進(jìn)行混淆。SDK已經(jīng)集成...
    CarlosLynn閱讀 1,543評論 0 0
  • 本篇文章:自己在混淆的時(shí)候整理出比較全面的混淆方法奄喂,比較實(shí)用铐殃,自己走過的坑海洼,淌出來的路跨新。請大家不要再走回頭路,可能...
    Zane_Samuel閱讀 55,378評論 8 93
  • 什么是混淆 代碼壓縮通過 ProGuard 提供坏逢,ProGuard 會(huì)檢測和移除封裝應(yīng)用中未使用的類域帐、字段、方法和...
    6He閱讀 2,911評論 0 0