放下你的浮躁伸刃,放下你的懶惰谎砾,放下你的三分鐘熱度,放空你禁不住誘惑的大腦捧颅,放開你容易被任何事物吸引的眼睛景图,放淡你什么都想聊兩句八卦的嘴巴,靜下心來做你該做的事碉哑,該好好努力了挚币!有時候真的努力后,你會發(fā)現(xiàn)自己要比想象的優(yōu)秀很多妆毕。記住一句話笛粘,越努力,越幸運
APK你不加固就好比一個妹子全裸在你面前,你可以看到里面的源碼例诀,很危險,哪怕是現(xiàn)在市面上一些APP也有百分之三十左右也沒有加固的扔罪。當然也可以用第三方框架加密矿酵。
一般APP快上線的時候,我們才會做這一步,一年也就這么幾次评疗,因為我是做SDK開發(fā)的砌些,所以經(jīng)常混淆不可避免有巧。
目前反編譯工具有四類
1示姿、apktool 主要用于資源文件的獲取
2岂傲、dex2jar 將apk中的dex文件編譯成jar文件
3、jd-gui 查看反編譯后的jar中的class
4褂痰、jadx 直接查看資源與代碼
apktool:如果APK未加固归薛,解壓后可以看到APK里面的一些資源文件,比如我們看中了某個APP的一些UI控件,或者想分析AndroidManifest里面的啟動是怎樣的诅炉,或者游戲apk包需要改icon和名稱,直接用apktool解壓就行了。
網(wǎng)上隨便找一個apktool版本瞻凤,盡量高一點的,我們反編譯可以用這種方式蛛壳。在當前目錄浮创,存在一個apktool和一個apk溜族,并且在當前目錄打開cmd文件,輸入java -jar apktool_2.4.0.jar d app-debug.apk -o dir摧玫,最后可以得到一個dir文件闸婴,資源什么的都出來了对竣。對于僅僅只需要反編譯需求蛋褥。
指令很多,我通常用我自己的一套反編譯方法,有反編譯,回編譯。
反編譯:需要當前目錄的apk,apktool.jar,apktool.bat,執(zhí)行命令后就會得到一個test的文件夾,注意配置好jdk環(huán)境變量啥的。
xdqxz.keystore是你的簽名文件遥倦,里面包含簽名密碼和alias
Test.apk是要反編譯的目標apk
apktool是你要反編譯工具的版本,名稱就改成apktool
apktool.bat里面的東西為下圖
@echo off
set PATH=%CD%;%PATH%;
java -jar "%~dp0\apktool.jar" %1 %2 %3 %4 %5 %6 %7 %8 %9
Test文件夾就是你反編譯之后的文件夾
回編譯
比如我改了游戲apk里面的icon等等之后,想讓他重新變?yōu)樾碌腶pk
我先把Test文件夾改成huanxiang這個名字,其實改成什么名字都一樣,到時候執(zhí)行命令的時候要同步變化即可
apk解壓后的文件變成APK,但這僅僅是沒簽名的APK
apktool b huanxiang -o new_huanxiang_unsign.apk
要變成簽名的apk執(zhí)行命令jarsigner -verbose -keystore xdqxz.keystore -storepass 123456 -keypass 123456 -signedjar new_huanxiang_signed.apk new_huanxiang_unsign.apk android.keystore -sigalg SHA1withRSA -digestalg SHA1
dex2jar是將apk中的dex文件編譯成jar文件
如果我們有個apk赶撰,想看編譯apk里面dex文件的源碼瘤载,可以用這個工具墨技。
下載dex2jar工具,在工具當前目錄打開cmd文件挎狸,如果目標文件叫app-debug.apk
執(zhí)行命令d2j-dex2jar.bat app-debug.apk -o app-debug.jar就可以在當前目錄得到一個app-debug.jar的jar包
然后用jdu工具去查看這個jar包里面的東西就可以了扣汪。直接把jar拖進去就可以看
jadx
這個工具的作用就是直接可以查看apk里面的代碼,雙擊jadx工具選擇對應的apk就會出現(xiàn)目錄結構锨匆。
混淆
Proguard是一個代碼優(yōu)化和混淆工具崭别。
能夠提供對Java類文件的壓縮、優(yōu)化恐锣、混淆茅主,和預校驗。壓縮的步驟是檢測并移除未使用的類侥蒙、字段暗膜、方法和屬性。優(yōu)化的步驟是分析和優(yōu)化方法的字節(jié)碼鞭衩⊙眩混淆的步驟是使用短的毫無意義的名稱重命名剩余的類娃善、字段和方法。壓縮瑞佩、優(yōu)化聚磺、混淆使得代碼更小,更高效炬丸。
開啟proguard
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
我們常用的混淆方法其實可以有個模板在AS里面能找到
可以拿以上圖左參考瘫寝,混淆的規(guī)則還是挺多的,講幾個最常用稠炬,用的最多最有效的吧焕阿。
我們代碼里面很多沒有在程序里面使用過調(diào)用過的類,打包出去的時候可以混淆過濾掉首启,可以在根目錄的proguard-rules.pro文件里面添加-dontoptimize屬性暮屡,一般來說這個屬性都要添加。
另外用的最多的混淆的三個地方就是:
-keep 指定類和類成員(變量和方法)不被混淆毅桃。
-keep class com.dongnao.proxy.guard.test.Bug
(保護了類名)
-keep class com.dongnao.proxy.guard.test.Bug{
public static void *();
}
(保護了 public static void的沒有參數(shù)的函數(shù))
-keep class com.dongnao.proxy.guard.test.Bug{
*褒纲;
}
(保護所有)
-keepclassmembers 指定類成員不被混淆(就是-keep的縮小版,不管類名了)钥飞。
-keepclassmembers
class com.dongnao.proxy.guard.test.Bug
(都被混淆了)
-keepclasseswithmembers 指定類和類成員不被混淆莺掠,前提是指定的類成員存在。
-keepclasseswithmembers class com.dongnao.proxy.guard.test.Bug
(保護類名读宙,但是沒指定成員彻秆,所以函數(shù)名被混淆)
-keepclasseswithmembers class com.dongnao.proxy.guard.test.Bug{
native <methods>;
}
全被混淆了。注意 前提是指定的類成員存在 因為不存在native函數(shù)论悴,所以這條語句等于無效掖棉,
然后混淆后的apk通過jadx來查看,就會看到類名變成了a/b/c這樣的膀估。那如果我們集成了類似友盟幔亥、bugly等異常上報功能,那么我們怎么知道這個異常到底出現(xiàn)在哪里察纯?
我們在Activity中主動寫一個bug然后生成一個debug的apk
運行產(chǎn)生這樣的日志:
這個日志有兩個問題:
1帕棉、 我們不知道是哪個類報告出的。
2饼记、 不知道這個類是哪一行報出的香伴。
混淆后的代碼錯誤棧恢復方法(outputs/mapping/debug/mapping.txt文件中保存了混淆前后的對應關系)
1.把錯誤信息保存到文件
2.使用工具 sdk/tools/groguard/bin/retrace.bat先配置 -keepattributes SourceFile,LineNumberTable再執(zhí)行 retrace.bat -verbose mappint文件 bug文件
第一個問題很顯然是由于我們的代碼進行了混淆具则。
在開啟混淆后即纲,我們生成apk會產(chǎn)生
dump.txt
說明 APK 中所有類文件的內(nèi)部結構。
這個文件內(nèi)容非常多博肋,可讀性也并不高
mapping.txt
提供原始與混淆過的類低斋、方法和字段名稱之間的轉換蜂厅。
seeds.txt
usage.txt
列出從 APK 移除的代碼膊畴【蛟常可以在這個文件中查看是不是有我們不想被移除的類
最重要的當然就是我們的mapping文件了。通過這個文件我們就能定位到:
出現(xiàn)錯誤的函數(shù)是Bug類中的test函數(shù)唇跨。
我們現(xiàn)在比較簡單稠通,所以一下子就能定位到錯誤函數(shù),如果函數(shù)層級較深买猖,光靠自己比對來查找難度就比較大了改橘。所以sdk中提供了一個工具在tools/proguard/bin中。
我們把logcat里面保存的錯誤堆棧復制到一個文件中:
然后執(zhí)行retrace 腳本(在 Windows 上為 retrace.bat政勃;在 Mac/Linux 上為 retrace.sh)
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
現(xiàn)在錯誤日志一句mapping還原了唧龄。
所以我們每次在發(fā)布版本之后都需要保留這個mapping文件。所以一般異常上報平臺都會提供mapping上傳然后幫助我們分析奸远。
第一個問題解決的,第二個問題是行數(shù)顯示的是Unknow Source
如果希望出現(xiàn)具體行數(shù),我們需要在配置文件中加入
拋出異常時保留代碼行號讽挟,在異常分析中可以方便定位
-keepattributes SourceFile,LineNumberTable
另外還可以配合
-renamesourcefileattribute AAA
使用字符串"AAA"來替代真正的類懒叛,避免泄漏更多的信息
雖然我們的代碼經(jīng)過了混淆,但是實際上耽梅,對于有耐心有條件的人來說薛窥,還是能夠從混淆過后的代碼中看到蛛絲馬跡。
dex2jar: java
https://sourceforge.net/projects/dex2jar/
反編譯后生成了一個jar
然后使用jd-gui打開:
http://jd.benow.ca/
直接跳到了眼姐,更加方便诅迷。
所以只要花功夫,混淆完全能夠被完整的解讀出來众旗。當然并不是說混淆就沒用罢杉。混淆之后解讀難度更大了贡歧。
proguard移除無用代碼還能縮小apk大小滩租。