新手上路
- 資源幣
- 19
- 積分
- 16
- 貢獻(xiàn)
- 0
- 在線時(shí)間
- 2 小時(shí)
- 注冊時(shí)間
- 2020-2-20
- 最后登錄
- 2020-5-2
|
零基礎(chǔ)安卓逆向?qū)W習(xí)之旅(六-下)
解釋Dalvik字節(jié)碼
下載,配置smali反編譯器
1.下載工具baksmali的相關(guān)文件
訪問以下鏈接:
https://bitbucket.org/JesusFreke/smali/downloads
1.jpg (20.35 KB, 下載次數(shù): 88)
下載附件
保存到相冊
2020-2-24 00:05 上傳
下載baksmali[version].jar文件的最新版本及baksmali腳本,并保存在同一目錄下。
2.配置baksmali工具
將下載下來的baksmali的jar文件改名為baksmali.jar
mv baksmali-[version-number].jar baksmali.jar
確認(rèn)baksmali腳本擁有可執(zhí)行權(quán)限
chmod +x 700 baksmali
運(yùn)用baksmali反編譯.dex文件
baksmali[Dex filename].dex
并在生成的out目錄下查看反編譯后的.smali文件
2.jpg (32.16 KB, 下載次數(shù): 90)
下載附件
保存到相冊
2020-2-24 00:05 上傳
解釋字節(jié)碼
首先是開頭幾行代碼
.class public LExample;
.super Ljava/lang/Object;
.source "Example.java"
這是被編譯后類的元數(shù)據(jù),給出了類名,父類以及源文件,由于所有的java類都是繼承自java.lang.Object的,所以即使在Example.java的代碼中,我們沒有顯式聲明繼承這個(gè)類,編譯后也會(huì)顯示出來。
接著是Example.java的構(gòu)造函數(shù)的smali代碼
#direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public constructor <init>()V //這個(gè)方法的聲明
即這個(gè)方法名為init,返回一個(gè)void類型,訪問標(biāo)志位是public。
.registers1
這個(gè)方法只使用一個(gè)寄存器,一個(gè)方法在運(yùn)行前都需要確定所需寄存器的數(shù)量。
.prologue
聲明接下來是一個(gè)prologue方法,這是每個(gè)java方法都有的,它保證這個(gè)方法是以繼承形式被調(diào)用的,這就是在下邊一行調(diào)用了另一個(gè)名為init的方法,這是java.lang.Object的init方法。
invoke-direct{p0}, Ljava/lang/Object;-><init>()V
invoke-direct指令需要兩個(gè)參數(shù):p0寄存器和被調(diào)用方法的指針。
invoke-direct是用來調(diào)用一個(gè)非靜態(tài)直接方法(non-static direct method),一個(gè)不可重寫的,private實(shí)例方法或構(gòu)造方法。
上邊代碼即是調(diào)用java.lang.Object類的構(gòu)造方法這個(gè)非靜態(tài)直接方法。
return-void 返回一個(gè)void類型,并退出當(dāng)前函數(shù)。
.endmethod 標(biāo)志著這個(gè)方法的結(jié)束。
接下來則是main方法的smali代碼:
.method public static main([Ljava/lang/String;)V
.registers 4
.prologue
.line 3
sget-object v0,Ljava/lang/System;->outjava/io/PrintStream;
const-string v1, "Hello World!\n"
const/4 v2, 0x0
new-array v2, v2, [Ljava/lang/Object;
invoke-virtual {v0, v1, v2},Ljava/io/PrintStream;->printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
.line 4
return-void
.end method
第一行:.method public static main([Ljava/lang/String;)V
這個(gè)方法接收一個(gè)java.lang.String類型的數(shù)組,返回void類型,且這方法是靜態(tài)方法,訪問屬性為public。
sget-object操作:sget-object v0, Ljava/lang/System;
->outjava/io/PrintStream;
官網(wǎng)描述erform the identified object static field operation withthe identified static field, loading or storing into the value register.
執(zhí)行獲取對象靜態(tài)成員的操作,找靜態(tài)成員,將其加載/存儲(chǔ)到存放值的寄存器中
sget-object接收兩個(gè)參數(shù):
一個(gè)寄存器,用于存儲(chǔ)操作的結(jié)果
一個(gè)是將被存儲(chǔ)到上邊的寄存器的對象的引用
即這行代碼是獲取一個(gè)對象實(shí)例,并將其存放到寄存器中,v0是這方法的棧幀里的第一個(gè)寄存器。
const-string指令:const-string v1, "Hello World!\n"
獲取一個(gè)字符串并將其存儲(chǔ)在第一參數(shù)指定的寄存器中。
const/4v2, 0x0
將常數(shù)0放入第三個(gè)寄存器v2中。
new-arrayv2, v2, [Ljava/lang/Object;
new-array指令是構(gòu)造一個(gè)指定類型和元素個(gè)數(shù)的數(shù)組,并將它存放在左起第一個(gè)寄存器中,這指令執(zhí)行后,v2寄存器中存放的應(yīng)是一個(gè)元素個(gè)數(shù)為0,java.lang.Object類型的數(shù)組.上一行const/4v2, 0x0先將0放入v2的原因。
最后是非常常見的指令 :
invoke-virtual{v0, v1, v2},Ljava/io/PrintStream;->printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
invoke-virtual指令的官網(wǎng)定義"invoke-virtual is used to invoke a normal virtualmethod (a method that is not private, static, or final, and is also not a constructor)."
invoke-virtual用來調(diào)用一個(gè)普通的虛方法(方法屬性不為private,static或final,且不是構(gòu)造方法)
其參數(shù)格式:
invoke-kind{vC, vD, vE, vF, vG}, meth@BBBB
其中,vC,vD,vE,vF,vG是用來向被調(diào)用的方法傳遞參數(shù)的寄存器,方法的具體代碼由參數(shù)meth@BBBB指定,每個(gè)B表示4bit,即這個(gè)指令接收一個(gè)16位的方法引用
所以實(shí)例中的代碼,是調(diào)用一個(gè)名為java.io.PrintStream.printf方法,接收參數(shù):java.lang.String對象和java.lang.Object類型的數(shù)組,最后返回java.io.PrintStream類型的對象 。
將DEX反編譯為java
1.下載相關(guān)工具
Dex2Jarhttps://sourceforge.net/projects/dex2jar/?source=typ_redirect下載最新.zip包
JD-GUI:訪問http://jd.benow.ca/ 下載最新.jar。
2.運(yùn)用Dex2Jar將.dex文件轉(zhuǎn)成.jar文件
[path-of-Dex2Jar]/dex2jar.shExample.dex //生成Example_dex2jar.jar文件
3.jpg (22.45 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2020-2-24 00:06 上傳
3.在JD-GUI上打開上邊生成的.jar文件,查看java源代碼
java-jar jd-gui-[version] //打開JD-GUI 點(diǎn)擊File->Open。
4.jpg (39.42 KB, 下載次數(shù): 88)
下載附件
保存到相冊
2020-2-24 00:06 上傳
選擇上邊的.jar文件打開,查看java源代碼。
5.jpg (26 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2020-2-24 00:07 上傳
反編譯app的原生庫
1.獲取Android原生庫文件(.so)。
Sieve – A password manager app, showcasing some common Android vulnerabilities at
https://www.mwrinfosecurity.com/system/assets/380/original/sieve.apk
下載實(shí)例apk文件,將文件改名為sieve.zip,并解壓為sieve,在sieve/lib/armeabi/*.so路徑下便可找到Android原生庫文件。
2.確認(rèn)工具objdump在AndroidNDK中路徑
[android-ndk-path]/toolchains/arm-linux-androideabi-[version]/prebuilt/[arch]/bin/在該目錄下找到objdump工具:./arm-linux-androideabi-objdump。
6.jpg (42 KB, 下載次數(shù): 85)
下載附件
保存到相冊
2020-2-24 00:07 上傳
3.反編譯原生庫
arm-linux-androideabi-objdump–D [native library].so
7.jpg (31.02 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2020-2-24 00:08 上傳
使用GDB server調(diào)試Android進(jìn)程
1.將Android NDK下的gdbserver文件拷貝到設(shè)備上
這需要一部已經(jīng)root的Android設(shè)備或一臺(tái)Android模擬器。
emulator-avd [avd name] //啟動(dòng)AVD
adbshell //進(jìn)入設(shè)備shell
重新掛載系統(tǒng)目錄,以讀-寫權(quán)限mount系統(tǒng)目錄/system
mount //查看當(dāng)前各個(gè)塊設(shè)備的掛載信息,確定/system的掛載信息(mount | grep system)
8.jpg (41.43 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2020-2-24 00:08 上傳
mount -o rw,remount [device] /system //重新掛載/system,改為讀-寫
9.jpg (32.74 KB, 下載次數(shù): 89)
下載附件
保存到相冊
2020-2-24 00:08 上傳
gdbserver位于[NDK-path]/prebuit/android-arm64/gdbserver/gdbserver
pushgdbserver /system/bin/. //將gdbserver拷貝到設(shè)備上
10.jpg (9.91 KB, 下載次數(shù): 86)
下載附件
保存到相冊
2020-2-24 00:09 上傳
2.運(yùn)用gdbserver抓取進(jìn)程
ps //查看設(shè)備正在運(yùn)行的進(jìn)程信息
11.jpg (41.24 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2020-2-24 00:09 上傳
選取com.android.email進(jìn)程作為實(shí)驗(yàn)進(jìn)程,其PID為1009
12.jpg (5.14 KB, 下載次數(shù): 81)
下載附件
保存到相冊
2020-2-24 00:10 上傳
gdbserver:[tcp-port number] –attach [PID] //抓取進(jìn)程,連接TCP端口
gdbserver:31337 –attach 1009
3.在本地主機(jī)上運(yùn)行g(shù)db進(jìn)行調(diào)試
adb forward tcp:[device port-number] tcp:[local port-number] //端口交互
gdb位于[NDK-path]/prebuilt/[system]/bin/gdb
運(yùn)行g(shù)db
13.jpg (37.01 KB, 下載次數(shù): 83)
下載附件
保存到相冊
2020-2-24 00:10 上傳
進(jìn)入gdb后,運(yùn)行下邊命令,調(diào)試目標(biāo)進(jìn)程
target remote :[PID] //[PID]為本機(jī)TCP交互端口
14.jpg (48.6 KB, 下載次數(shù): 94)
下載附件
保存到相冊
2020-2-24 00:11 上傳
現(xiàn)在便可與運(yùn)行在Android設(shè)備上的進(jìn)程中的內(nèi)存段和寄存器進(jìn)行交互了。。。。。。
|
|