Android逆向入門之常見Davlik字節(jié)碼解析
破解流程
破解Android程序流程:反編譯—>分析–>修改–>回編譯–>簽名,這些都是在命令行中操作,當然也有集成了這些操作的工具:
macos:Android-Crack-Tool
Windows:Android Killer
相關(guān)知識
寄存器
這里解釋下寄存器的概念,寄存器是用來存儲
寄存器是CPU內(nèi)部用來存放數(shù)據(jù)的一些小型存儲區(qū)域,用來暫時存放參與運算的數(shù)據(jù)和運算結(jié)果。也就是存儲來存儲數(shù)據(jù)的?,F(xiàn)在所有手機都是用的arm芯片
這里說一些題外話:比較常見的CPU有intel的X86架構(gòu)的CPU的還有arm架構(gòu)的CPU,其中intel的X86架構(gòu)的cpu指令集有復(fù)雜指令集和精簡指令集,arm中只有精簡指令集。
復(fù)雜指令集和精簡指令集
所謂復(fù)雜和簡單就是根據(jù)是否要根據(jù)程序來設(shè)計指令來提高計算機的性能,復(fù)雜指令集會根據(jù)應(yīng)用程序來增加一些復(fù)雜功能的指令集,這樣也就導(dǎo)致CPU的指令越來越多越設(shè)計越復(fù)雜造價也越高,而精簡指令集則不會根據(jù)程序來設(shè)計指令集,那么怎么提高性能?
jvm和davlik的一些區(qū)別
翻譯成機器碼的工作就是由高級語言的編譯器來做的,把這些工作交給了編譯器。所以兩種區(qū)別就是復(fù)雜指令集會根據(jù)程序來增加自己的指令集達到提高計算機性能的作用,精簡指令集則是交給了編譯器去做指令轉(zhuǎn)換的工作。由于加入了編譯器的轉(zhuǎn)換所以運行速度會慢,而且占用的內(nèi)存也會變多,同樣的程序在arm芯片的手機上和intel芯片的電腦上,手機上占用的空間更多。精簡指令集的arm架構(gòu)還有一個特點是其寄存器特別多,而davlik虛擬機利用這個特性對原本java虛擬機進行了改動:
java虛擬機中每個線程都會有一個PC計數(shù)器和一個java棧,PC計數(shù)器用于記錄程序執(zhí)行到哪個地方,java棧中用來記錄java方法的調(diào)用記錄叫做棧幀,每調(diào)用一個方法就會分配一個新棧并壓入java棧,每個棧幀都包含局部變量區(qū),求值棧(jvm叫做操作數(shù)棧),局部變量區(qū)用來存儲方法的參數(shù)和局部變量,求值棧用于保存求值的中間結(jié)果及調(diào)用其他方法的參數(shù)。方法運算時從棧中的局部變量區(qū)取數(shù)據(jù)進行運算將結(jié)果存放在操作數(shù)棧中,最后返回的時候從操作數(shù)棧中彈出結(jié)果
而davlik虛擬機運行時中也為每一個線程維護了一個PC計數(shù)器和一個調(diào)用棧,不同的是這個調(diào)用棧中維護了一個寄存器列表,至于虛擬寄存器分配多少個是根據(jù)方法結(jié)構(gòu)體中的registers字段給出,davlik虛擬機根據(jù)這個字段創(chuàng)建一份虛擬的寄存器列表。將java棧幀中的局部變量區(qū)和操作數(shù)棧換成了寄存器列表來存儲。所以java虛擬機是基于棧架構(gòu),而davlik虛擬機基于寄存器架構(gòu)
常見Davlik字節(jié)碼解釋
1.常見Davlik字節(jié)碼:
定義字段類型:
check-cast 寄存器(操作數(shù)),定義的類型;
舉例:
check-cast v0,Lcom/android/Launcher2/launcherApplication;代表定義v0的類型為LauncherApplication
字段寫入字段讀?。ㄍㄓ媒忉專?br />
總結(jié):指令 目的操作數(shù) 源操作數(shù)
前面代表指令 寄存器中的值(操作數(shù)) 所屬類 變量名 變量屬性
本質(zhì)上指令操作的還是操作數(shù),根據(jù)指令變量是讀取還是被賦值
讀取get:讀取變量賦值給操作數(shù)
賦值set:賦值變量的值為操作數(shù)的值
靜態(tài)字段寫入:
const 寄存器 ,值所對應(yīng)的ID(0X0代表為null)
sput-object 寄存器,字段所屬的類;->字段名字:字段類型
const/4 v3, 0x0
sput-object v3, Lcom/disney/Class1;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler;
將0x00(代表null)存入v3寄存器中
將v3寄存器中的值寫入Class1中的globalIapHandler變量,該變量類型為GlobalPurchaseHandler,
也就是Class1.globalIapHandler = null;
靜態(tài)字段讀取:
sget -object 寄存器, 字段所屬的類;->字段名稱:字段類型
舉例:
sget-object v0, Lcom/disney/Class1;->PREFS_INSTALLATION_ID:Ljava/lang/String;
讀取Class1中的PREFS_INSTALLATION_ID變量,該變量類型為String
普通字段寫入:
.local v0, args:Landroid/os/Message;
const/4 v1, 0x12
iput v1, v0, Landroid/os/Message;->what:I
將args變量存入v0寄存器中
將0X12傳入到v1寄存器中
設(shè)置Message中的what變量為v1的值
相當于 args.what=18;
普通字段讀?。?/p>
iget-object 寄存器 p0(代表該變量所在類的示例即this), 字段所屬的類;->字段名字:zidaun1:字段類型
舉例:
iget-object v0, p0, Lcom/disney/Class1;->_view:Lcom/disney/Class2;
從v0寄存器中拿Class1中的_view變量,這個變量類型為Class2
調(diào)用方法:
invoke-virtual {寄存器:調(diào)用者(p0代表this)和方法參數(shù)信息}, 方法所在的類;->方法名(參數(shù)) 返回值
舉例:
invoke-virtual {p0},Lcom/android/Launcher2/Launcher;_>getApplication()L android/app/Application;
java實現(xiàn)代碼為:(this.)getApplication();
調(diào)用父類方法:
invoke-super {寄存器 :代表調(diào)用者和參數(shù)},方法所屬的類;->方法名稱(參數(shù)類型)返回值【V代表無返回值】
invoke-super {p0,p1},Landroid/app/ActivityGroup;->onCreate(Landroid/os/Bundle;)V
調(diào)用接口:
invoke-interface {寄存器【和方法一樣也是調(diào)用者和方法參數(shù)信息】}, 方法所屬的接口全名;->方法名(參數(shù)類型)返回值
invoke-interface {v3,v6,v9},Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z
java實現(xiàn)代碼為:v3.getBoolean(v6,v9);
判斷語句:
一,if-nez(與if-eqz相反)
if-nez 寄存器(里面存儲的是操作數(shù)), :標號處
如果操作數(shù)不為null或者不為0或者不相等就跳轉(zhuǎn)到標號處執(zhí)行代碼
舉例:
move resule v0 (將上一條命令的結(jié)果賦值給v0)
if-nez v0, :cond_0
(判斷其值不為0【條件為真】就跳轉(zhuǎn)到cond_0標號處,反之程序繼續(xù)執(zhí)行直到執(zhí)行到return-void指令處)
二,if-eqz
表示在結(jié)果為0或者相等時跳轉(zhuǎn)(與if-nez相反)
方法返回:
return-void 沒有返回值
破解程序
分析修改smail文件
1.修改完smali文件安裝到手機上
重新編譯,回編譯命令為
apktool b 文件地址
回編譯中常見的錯誤:
1.提示"at brut.androlib.Androlib.buildResourcesFull(Androlib.java:477)"
解釋:該問題為打包資源出錯,程序使用的的API版本號和apkool中framework-res.apk基于Android的版本不一致導(dǎo)致
舉例:程序使用的API版本號為25;而apkttol版本號為2.2.2其對應(yīng)的framework-res.apk的版本是基于Android6.0的,
其API為23。兩者不一致
解決方法為:找一臺API和程序使用的API版本號一致的android設(shè)備,從中獲取framework-res.apk,并把這個apk安裝到本地
使用命令:
(1.)獲取android設(shè)備中的framework-res.apk:
adb pull /system/framework/framework-res.apk
(2.)安裝到本地apktool中
apktool if ./framework-res.apk
重新簽名
編譯完生成的APK文件是沒有進行簽名的,所以不能安裝。
通過signapk對APK文件進行簽名
使用命令:
cat /User/android/Program/signapk
#!/bin/sh
java -jar ~/Program/signapk_jar/signapk.jar ~/Program/signapk_jar/testkey.x509.pem ~/Program/signapk_jar/testkey.pk8 $1 signed.apk
這些文件都可以從android源碼中提取。
接著完成apk的簽名操作:
signapk 編譯后未簽名的apk文件地址
簽名后完成后會在上面的文件地址里面生成sign.apk文件
到此這篇關(guān)于Android逆向入門之常見Davlik字節(jié)碼解析的文章就介紹到這了,更多相關(guān)Android Davlik 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android項目實戰(zhàn)之Glide 高斯模糊效果的實例代碼
這篇文章主要介紹了Android項目實戰(zhàn)之Glide 高斯模糊效果的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06Android SeekBar控制視頻播放進度實現(xiàn)過程講解
這篇文章主要介紹了Android SeekBar控制視頻播放進度實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-04-04Android編程設(shè)計模式之責(zé)任鏈模式詳解
這篇文章主要介紹了Android編程設(shè)計模式之責(zé)任鏈模式,詳細分析了Android設(shè)計模式中責(zé)任鏈模式的概念、原理、應(yīng)用場景、使用方法及相關(guān)操作技巧,需要的朋友可以參考下2017-12-12Android編程之電池電量信息更新的方法(基于BatteryService實現(xiàn))
這篇文章主要介紹了Android編程之電池電量信息更新的方法,主要基于BatteryService實現(xiàn)該功能,以實例形式分析了Android獲取電池電量的具體步驟與實現(xiàn)技巧,需要的朋友可以參考下2015-11-11