前言:
各位同學(xué)大家好 最近在學(xué)習(xí)逆向的知識(shí)點(diǎn), 所以現(xiàn)在就總結(jié)寫 在學(xué)些這篇文章之前我默認(rèn) 你已經(jīng)看過(guò)我之前出的安卓反編譯的基礎(chǔ)知識(shí)了 如果那個(gè)還不會(huì) 麻煩可以前面去查閱
如果不會(huì)基礎(chǔ)的同學(xué)可以看 安卓反編譯教程 這篇文章
效果圖

image.png

image.png
理論知識(shí)
Smali文件
Smali是將Android字節(jié)碼用可閱讀的字符串形式 表現(xiàn)出來(lái)的一種語(yǔ)言,可以稱之為Android字節(jié)碼的 反匯編語(yǔ)言,即Smali語(yǔ)言是Dalvik的反匯編語(yǔ)言。
作用:
APK文件>dex文件>smali文件>修改代碼
結(jié)構(gòu):
頭文件 – 字段 – 方法 和Java類似
Smali數(shù)據(jù)類型
¨ B----byte
¨ C----char
¨ D----double
¨ F----float
¨ I----int
¨ J----long
¨ S----short
¨ V----void
¨ Z----boolean
¨ [XXX-----array
¨ Lxxx/yyy----object
數(shù)組的表示方式是:在基本類型前加上前中括號(hào)“[”,例如 [I、[F;
對(duì)象的表示則以L作為開頭,格式是LpackageName/objectName;
類的表示:LpackageName/objectName;
內(nèi)部類的表示: LpackageName/objectName$subObjectName;
Smali字段
字段定義:
field public/private [static] [final] varName:<Type>
舉例說(shuō)明(smali -> java):
.field public static HELLO:Ljava/lang/String;
public static String HELLO = "hello";
field private button:Landroid/widget/Button;
private Button button;
field public number:I
public int number =5;
Smali方法
方法定義:
Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type
舉例說(shuō)明( smali -> java 注意:參數(shù)與參數(shù)之間沒有任何分隔符 ):
hello ()V
void hello()
hello (III)Z
boolean hello(int, int, int)
hello (Z[I[ILjava/lang/String;J)Ljava/lang/String;
String hello (boolean, int[], int[], String, long)
Smali方法(smali轉(zhuǎn)java)
smali 代碼 示例
.method private static getCount(II)V
.registers 2
.param p0, "x"
.param p1, "y"
.prologue
.line 28
return-void
.end method
java 代碼示例
private static void getCount(int x,int y){
}
Smali基本語(yǔ)法
field 定義變量
method 方法
parameter 方法參數(shù)
prologue 方法開始
line 12 此方法位于第12行
const/high16 v0, 0x7fo3 把0x7fo3賦值給v0
return-void 函數(shù)返回void
end method 函數(shù)結(jié)束
new-instance 創(chuàng)建實(shí)例
iput-object 對(duì)象賦值
iget-object 調(diào)用對(duì)象
invoke-static 調(diào)用靜態(tài)函數(shù)
invoke-super 調(diào)用父函數(shù)
invoke-direct 調(diào)用函數(shù)
Smali跳轉(zhuǎn)語(yǔ)句
"if-eq vA, vB, :cond_\**" 如果vA等于vB則跳轉(zhuǎn)到:cond_**
"if-ne vA, vB, :cond_\**" 如果vA不等于vB則跳轉(zhuǎn)到:cond_**
"if-lt vA, vB, :cond_\**" 如果vA小于vB則跳轉(zhuǎn)到:cond_**
"if-ge vA, vB, :cond_\**" 如果vA大于等于vB則跳轉(zhuǎn)到:cond_**
"if-gt vA, vB, :cond_\**" 如果vA大于vB則跳轉(zhuǎn)到:cond_**
"if-le vA, vB, :cond_\**" 如果vA小于等于vB則跳轉(zhuǎn)到:cond_**
"if-eqz vA, :cond_\**" 如果vA等于0則跳轉(zhuǎn)到:cond_**
"if-nez vA, :cond_\**" 如果vA不等于0則跳轉(zhuǎn)到:cond_**
"if-ltz vA, :cond_\**" 如果vA小于0則跳轉(zhuǎn)到:cond_**
"if-gez vA, :cond_\**" 如果vA大于等于0則跳轉(zhuǎn)到:cond_**
"if-gtz vA, :cond_\**" 如果vA大于0則跳轉(zhuǎn)到:cond_**
"if-lez vA, :cond_\**" 如果vA小于等于0則跳轉(zhuǎn)到:cond_**
Smali函數(shù)調(diào)用
函數(shù)類型:
- direct - private函數(shù)
- virtual - public和protected函數(shù)
寄存器:
- 本地寄存器用v開頭數(shù)字結(jié)尾的符號(hào)來(lái)表示,如v0、v1、v2、...
- 參數(shù)寄存器則使用p開頭數(shù)字結(jié)尾的符號(hào)來(lái)表示,如p0、p1、p2、...
調(diào)用函數(shù):
1. invoke-static
2. invoke-super
3. invoke-direct
4. invoke-virtual
Smali函數(shù)調(diào)用:invoke-static
invoke-static:
作用:用于調(diào)用static函數(shù)。
例如:
const-string v0, "NDKLIB"
invoke-static {v0}, Ljava/lang/System;-
>loadLibrary(Ljava/lang/String;)V
static void System.loadLibrary(String)
Smali函數(shù)調(diào)用:invoke-super
invoke-direct:
作用:用于調(diào)用private函數(shù)。
例如:
invoke-direct {p0}, Landroid/app/TabActivity;-
><init>()V
init()就是定義在TabActivity中的一個(gè)private函數(shù)
Smali函數(shù)調(diào)用:invoke-virtual
invoke-virtual:
作用:用于調(diào)用protected或public函數(shù)。
例如:
sget-object v0, Lcom/dddd;->bbb:Lcom/ccc;
invoke-virtual {v0, v1}, Lcom/ccc;-
>Messages(Ljava/lang/Object;)V
v0是bbb:Lcom/ccc
v1是傳遞給Messages方法的Ljava/lang/Object參數(shù)
Smali函數(shù)返回結(jié)果
move-result(返回基本數(shù)據(jù)類型)
move-result-object(返回對(duì)象)
const-string v0, ”Tom"
invoke-static {v0}, Lcmb/pbi;-
>hi(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
最后總結(jié)
smali語(yǔ)法比較枯燥和難以閱讀 同學(xué)們一定要耐心去閱讀可以自己寫一些demo 對(duì)照java代碼去閱讀 smali代碼 這樣去學(xué)習(xí)能使我們更快掌握samli的語(yǔ)法 然后才能讓我們?cè)趯?shí)戰(zhàn)用修改smali 里面代碼邏輯 達(dá)到修改和注入的目的 最后希望我都文章能幫助到各位網(wǎng)友的工作和學(xué)習(xí) 如果你覺得文章還不錯(cuò)麻煩給我三連 關(guān)注點(diǎn)贊和轉(zhuǎn)發(fā) 謝謝