資源共享吧|易語言論壇|逆向破解教程|輔助開發(fā)教程|網絡安全教程|rigasin.com|我的開發(fā)技術隨記

 找回密碼
 注冊成為正式會員
查看: 2164|回復: 1
打印 上一主題 下一主題

[安卓逆向破解] 零基礎安卓逆向學習之旅(六-下)

[復制鏈接]

8

主題

8

帖子

0

精華

新手上路

Rank: 1

資源幣
19
積分
16
貢獻
0
在線時間
2 小時
注冊時間
2020-2-20
最后登錄
2020-5-2
跳轉到指定樓層
樓主
發(fā)表于 2020-2-24 00:11:11 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
零基礎安卓逆向學習之旅(六-下)

解釋Dalvik字節(jié)碼

下載,配置smali反編譯器

1.下載工具baksmali的相關文件

訪問以下鏈接:

https://bitbucket.org/JesusFreke/smali/downloads





下載baksmali[version].jar文件的最新版本及baksmali腳本,并保存在同一目錄下。

2.配置baksmali工具

    將下載下來的baksmali的jar文件改名為baksmali.jar

    mv baksmali-[version-number].jar baksmali.jar

    確認baksmali腳本擁有可執(zhí)行權限

    chmod +x 700 baksmali

    運用baksmali反編譯.dex文件

    baksmali[Dex filename].dex

    并在生成的out目錄下查看反編譯后的.smali文件




解釋字節(jié)碼

首先是開頭幾行代碼

.class public LExample;

.super Ljava/lang/Object;

.source "Example.java"

這是被編譯后類的元數(shù)據(jù),給出了類名,父類以及源文件,由于所有的java類都是繼承自java.lang.Object的,所以即使在Example.java的代碼中,我們沒有顯式聲明繼承這個類,編譯后也會顯示出來。

接著是Example.java的構造函數(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  //這個方法的聲明

即這個方法名為init,返回一個void類型,訪問標志位是public。

.registers1

這個方法只使用一個寄存器,一個方法在運行前都需要確定所需寄存器的數(shù)量。

.prologue

聲明接下來是一個prologue方法,這是每個java方法都有的,它保證這個方法是以繼承形式被調用的,這就是在下邊一行調用了另一個名為init的方法,這是java.lang.Object的init方法。

invoke-direct{p0}, Ljava/lang/Object;-><init>()V

invoke-direct指令需要兩個參數(shù):p0寄存器和被調用方法的指針。

invoke-direct是用來調用一個非靜態(tài)直接方法(non-static direct method),一個不可重寫的,private實例方法或構造方法。

上邊代碼即是調用java.lang.Object類的構造方法這個非靜態(tài)直接方法。

return-void   返回一個void類型,并退出當前函數(shù)。

.endmethod  標志著這個方法的結束。

    接下來則是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

這個方法接收一個java.lang.String類型的數(shù)組,返回void類型,且這方法是靜態(tài)方法,訪問屬性為public。

sget-object操作:sget-object v0, Ljava/lang/System;

->outjava/io/PrintStream;

官網描述erform the identified object static field operation withthe identified static field, loading or storing into the value register.

執(zhí)行獲取對象靜態(tài)成員的操作,找靜態(tài)成員,將其加載/存儲到存放值的寄存器中

sget-object接收兩個參數(shù):

一個寄存器,用于存儲操作的結果

一個是將被存儲到上邊的寄存器的對象的引用

即這行代碼是獲取一個對象實例,并將其存放到寄存器中,v0是這方法的棧幀里的第一個寄存器。

const-string指令:const-string v1, "Hello World!\n"

獲取一個字符串并將其存儲在第一參數(shù)指定的寄存器中。

const/4v2, 0x0

將常數(shù)0放入第三個寄存器v2中。

new-arrayv2, v2, [Ljava/lang/Object;

new-array指令是構造一個指定類型和元素個數(shù)的數(shù)組,并將它存放在左起第一個寄存器中,這指令執(zhí)行后,v2寄存器中存放的應是一個元素個數(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指令的官網定義"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用來調用一個普通的虛方法(方法屬性不為private,static或final,且不是構造方法)

其參數(shù)格式:

invoke-kind{vC, vD, vE, vF, vG}, meth@BBBB

其中,vC,vD,vE,vF,vG是用來向被調用的方法傳遞參數(shù)的寄存器,方法的具體代碼由參數(shù)meth@BBBB指定,每個B表示4bit,即這個指令接收一個16位的方法引用

所以實例中的代碼,是調用一個名為java.io.PrintStream.printf方法,接收參數(shù):java.lang.String對象和java.lang.Object類型的數(shù)組,最后返回java.io.PrintStream類型的對象 。

將DEX反編譯為java

1.下載相關工具

Dex2Jarhttps://sourceforge.net/projects/dex2jar/?source=typ_redirect下載最新.zip包

JD-GUI:訪問http://jd.benow.ca/  下載最新.jar。

2.運用Dex2Jar將.dex文件轉成.jar文件

    [path-of-Dex2Jar]/dex2jar.shExample.dex   //生成Example_dex2jar.jar文件





3.在JD-GUI上打開上邊生成的.jar文件,查看java源代碼

java-jar jd-gui-[version]  //打開JD-GUI    點擊File->Open。



選擇上邊的.jar文件打開,查看java源代碼。


反編譯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

下載實例apk文件,將文件改名為sieve.zip,并解壓為sieve,在sieve/lib/armeabi/*.so路徑下便可找到Android原生庫文件。

2.確認工具objdump在AndroidNDK中路徑

[android-ndk-path]/toolchains/arm-linux-androideabi-[version]/prebuilt/[arch]/bin/在該目錄下找到objdump工具:./arm-linux-androideabi-objdump。






3.反編譯原生庫

arm-linux-androideabi-objdump–D [native library].so




使用GDB server調試Android進程

1.將Android NDK下的gdbserver文件拷貝到設備上

這需要一部已經root的Android設備或一臺Android模擬器。

emulator-avd [avd name]  //啟動AVD

adbshell  //進入設備shell

重新掛載系統(tǒng)目錄,以讀-寫權限mount系統(tǒng)目錄/system

mount  //查看當前各個塊設備的掛載信息,確定/system的掛載信息(mount | grep system)



mount -o rw,remount [device] /system  //重新掛載/system,改為讀-寫




gdbserver位于[NDK-path]/prebuit/android-arm64/gdbserver/gdbserver

pushgdbserver /system/bin/.   //將gdbserver拷貝到設備上



2.運用gdbserver抓取進程

ps  //查看設備正在運行的進程信息




選取com.android.email進程作為實驗進程,其PID為1009


gdbserver:[tcp-port number] –attach [PID]  //抓取進程,連接TCP端口

gdbserver:31337 –attach 1009

3.在本地主機上運行gdb進行調試

adb forward tcp:[device port-number] tcp:[local port-number]  //端口交互

gdb位于[NDK-path]/prebuilt/[system]/bin/gdb

運行gdb



進入gdb后,運行下邊命令,調試目標進程

target remote :[PID]  //[PID]為本機TCP交互端口




現(xiàn)在便可與運行在Android設備上的進程中的內存段和寄存器進行交互了。。。。。。





回復

使用道具 舉報

2

主題

302

帖子

0

精華

終身高級VIP會員

Rank: 7Rank: 7Rank: 7

資源幣
4
積分
309
貢獻
0
在線時間
37 小時
注冊時間
2020-8-14
最后登錄
2023-2-6

終身VIP會員

沙發(fā)
發(fā)表于 2020-9-19 08:38:15 | 只看該作者
祝資源共享吧越來越火!
回復 支持 反對

使用道具 舉報

 點擊右側快捷回復  

本版積分規(guī)則

小黑屋|資源共享吧 ( 瓊ICP備2023000410號-1 )

GMT+8, 2025-4-10 21:27 , Processed in 0.051560 second(s), 14 queries , MemCached On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回復 返回頂部 返回列表