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