Android APK文件(4、Smali語法)

smali語言是Davlik的寄存器語言,語法上和彙編語言類似,Dalvik VM與JVM的最大的區別之一就是Dalvik VM是基於寄存器的。基於寄存器的意思是,在smali裏的全部操做都必須通過寄存器來進行。html

參考網址

靜態分析Android程序——smali文件解析java

blog.csdn.net/hp910315/ar…android

Smali基本語法(一)數組

blog.csdn.net/l_o_s/artic…bash

Android smali語法app

blog.csdn.net/Rozol/artic…ide

Android studio動態調試smali

www.cnblogs.com/goodhacker/…工具

數據類型

smali類型 java類型
V void (用於返回類型)
Z boolean
B byte
S short
C char
I int
J long (64 bits)
F float
D double (64 bits)

類定義

Kotlin代碼post

class MainActivity : AppCompatActivity() {
    ...
}
複製代碼

Smaliui

.class public final Lapp/santaone/customer/voip/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.kt"

...
複製代碼

總結:

  • L 表示這是一個對象類型
  • .class <訪問權限> <關鍵修飾字> <類名;>
  • .super <關鍵修飾字> <父類名;>
  • .source <源文件名>

變量定義

Kotlin代碼

private var incomingSip: String? = null
private var isOutgoing = false
複製代碼

Smali

# instance fields
.field private incomingSip:Ljava/lang/String;
.field private isOutgoing:Z
複製代碼

總結:

  • 註釋,註釋由#開頭,後面的instance fields, 意爲實例的字段,即變量字段。
  • .field表示,這是一個字段。 private,表明私有的,isOutgoing,是變量名。:Z,是變量的類型。
  • [I :表示一個整形的一維數組。

方法定義

Kotlin代碼

override fun onStart() {
    super.onStart()
}
複製代碼

Smali

.method protected onStart()V
    .locals 0

    .line 248
    invoke-super {p0}, Landroidx/appcompat/app/AppCompatActivity;->onStart()V

    return-void
.end method
複製代碼

總結:

  • .method表示,這是一個方法。protected,訪問權限。onStart,方法名。V,返回類型。

寄存器

Kotlin代碼

private fun print(string: String) {
    Log.d(TAG, string)
}
複製代碼

Smali

.method private print(Ljava/lang/String;)V
    .registers 3
    .param p1, "string"    # Ljava/lang/String;

    .prologue
    .line 29
    const-string v0, "MainActivity"

    invoke-static {v0, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 30
    return-void
.end method
複製代碼

總結:

  • android變量都是存放在寄存器中的,寄存器爲32位,能夠支持任何類型,其中long和double是64爲的,須要使用兩個寄存器保存。
  • 寄存器採用v和p來命名,v表示本地寄存器,p表示參數寄存器。
  • v0 v1 v2 v... // .locals 寄存器的命名。
  • p0 p1 p2 p... // .registers 寄存器的命名。
  • .registers 3 說明該方法有三個寄存器。其中一個本地寄存器v0,兩個參數寄存器p0,p1。沒有看到p0,緣由是p0存放的是this。若是是靜態方法的話就只有2個寄存器了,不須要存this。

運算

smali 描述
add-int v0, p1, p2 v0 = p1 + p2
sub-int v0, p1, p2 v0 = p1 - p2
mul-int v0, p1, p2 v0 = p1 * p2
div-int v0, p1, p2 v0 = p1 / p2
rem-int v0, p1, p2 v0 = p1 % p2
and-int v0, p1, p2 v0 = p1 & p2
or-int v0, p1, p2 v0 = p1 │ p2
xor-int v0, p1, p2 v0 = p1 ^ p2
shl-int v0, p1, p2 v0 = p1 << p2
... ...

指令

smali 描述
return-void 直接返回
return v0 返回v0
return-object v0 返回v0(對象)
return-wide v0 給v0(雙寄存器的值)
invoke-virtual 調用通常方法
invoke-super 調用父類方法
invoke-direct 調用private/構造方法
invoke-static 調用靜態方法
invoke-interface 調用interface方法
const(/4, /16, ,/high16) vx, num 把nun賦給vx寄存器, num爲(4bit, 16bit, 32bit(int), 16bit(float))
const-wide(/16, ,/high16) vx, num 把num賦給vx和vx+, num爲(?, 64bit(long), 64bit(double))
const-string( , -jumbo) vx, string "Unicode"字符串賦給vx (通常, 過長)
const-class vx, class 將Class賦值給vx
if-eq v0, v1 if (v0 == v1)
if-ne v0, v1 f (v0 != v1)
if-gt v0, v1 if (v0 > v1)
if-ge v0 if (v0 >= v1)
if-lt v0 if (v0 < v1)
if-le v0 if (v0 <= v1)
if-eqz v0 if (v0 == 0)
if-nez v0 if (v0 != 0)
if-gtz v0 if (v0 > 0)
if-gez v0 if (v0 >= 0)
if-ltz v0 if (v0 < 0)
if-lez v0 if (v0 <= 0)
iget0 取值(int)
iget-wide0 取值(雙寄存器值)
iget-object0 取值(對象指針)
iget-boolean0 取值(bool)
iget-byte0 取值(字節)
iget-char0 取值(字符)
iget-short0 取值(short)
iput0 賦值(int)
iput-wide0 賦值(雙寄存器值)
iput-object 0 賦值(對象指針)
iput-boolean0 賦值(bool)
iput-byte0 賦值(字節)
iput-char0 賦值(字符)
iput-short0 賦值(short)

smali插樁

smali插樁,插樁的原理就是靜態的修改apk的samli文件,而後從新打包。

  1. 反編譯獲得smali
  2. 修改smali代碼
  3. 從新打包簽名

結尾

Android APK文件(1、編譯打包過程)

Android APK文件(2、解壓和反編譯)

Android APK文件(3、AAPT2工具使用)

Android APK文件(4、Smali語法)

相關文章
相關標籤/搜索