Smali語法(二)
本文主要根據(jù)一個(gè)簡(jiǎn)單的demo來簡(jiǎn)單介紹下smali語法.
1: 源碼-MainActivity
demo中主頁面的代碼很簡(jiǎn)單, 兩個(gè)button+對(duì)應(yīng)的點(diǎn)擊事件.
11 public class MainActivity extends AppCompatActivity {
12
13 @Override
14 protected void onCreate(Bundle savedInstanceState) {
15 super.onCreate(savedInstanceState);
16 setContentView(R.layout.activity_main);
17 findViewById(R.id.btn_start).setOnClickListener(view -> {
18 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
19 startActivity(intent);
20 });
21
22 findViewById(R.id.btn_test).setOnClickListener(view -> test());
23 }
24
25 private void test() {
26 }
27 }
這里我加上了源碼中對(duì)應(yīng)的行數(shù).方便下面對(duì)應(yīng)smali分析.
2: smali 文件
我們根據(jù)apk獲取到smali文件如下:
.class public Lcom/test/accessbilitytest/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.java"
# direct methods
.method public constructor <init>()V
.registers 1
.line 11
invoke-direct {p0}, Landroidx/appcompat/app/AppCompatActivity;-><init>()V
return-void
.end method
.method private test()V
.registers 1
.line 26
return-void
.end method
# virtual methods
.method public synthetic lambda$onCreate$0$MainActivity(Landroid/view/View;)V
.registers 4
.param p1, "view" # Landroid/view/View;
.line 18
new-instance v0, Landroid/content/Intent;
const-string v1, "android.settings.ACCESSIBILITY_SETTINGS"
invoke-direct {v0, v1}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
.line 19
.local v0, "intent":Landroid/content/Intent;
invoke-virtual {p0, v0}, Lcom/test/accessbilitytest/MainActivity;->startActivity(Landroid/content/Intent;)V
.line 20
return-void
.end method
.method public synthetic lambda$onCreate$1$MainActivity(Landroid/view/View;)V
.registers 2
.param p1, "view" # Landroid/view/View;
.line 22
invoke-direct {p0}, Lcom/test/accessbilitytest/MainActivity;->test()V
return-void
.end method
.method protected onCreate(Landroid/os/Bundle;)V
.registers 4
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.line 15
invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
.line 16
const v0, 0x7f0b001c
invoke-virtual {p0, v0}, Lcom/test/accessbilitytest/MainActivity;->setContentView(I)V
.line 17
const v0, 0x7f080048
invoke-virtual {p0, v0}, Lcom/test/accessbilitytest/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
new-instance v1, Lcom/test/accessbilitytest/-$$Lambda$MainActivity$IjKj-Gn1BX-W2NglRcBa8cBCb0M;
invoke-direct {v1, p0}, Lcom/test/accessbilitytest/-$$Lambda$MainActivity$IjKj-Gn1BX-W2NglRcBa8cBCb0M;-><init>(Lcom/test/accessbilitytest/MainActivity;)V
invoke-virtual {v0, v1}, Landroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 22
const v0, 0x7f080049
invoke-virtual {p0, v0}, Lcom/test/accessbilitytest/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
new-instance v1, Lcom/test/accessbilitytest/-$$Lambda$MainActivity$cM1FSKBLATCUARbrJwEG_i9d7Tc;
invoke-direct {v1, p0}, Lcom/test/accessbilitytest/-$$Lambda$MainActivity$cM1FSKBLATCUARbrJwEG_i9d7Tc;-><init>(Lcom/test/accessbilitytest/MainActivity;)V
invoke-virtual {v0, v1}, Landroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 23
return-void
.end method
3: smali解析
這里我們根據(jù)獲取到的MainActivity.smali來具體介紹下smali.
3.1: 頭信息
.class public Lcom/test/accessbilitytest/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.java"
頭信息三行: 分別指定了當(dāng)前類的類名;父類的類名;單前類的源文件
3.2: 構(gòu)造方法
# direct methods
.method public constructor <init>()V
.registers 1
.line 11
invoke-direct {p0}, Landroidx/appcompat/app/AppCompatActivity;-><init>()V
return-void
.end method
- .method 是方法聲明.
- .method public constructor <init>()V : 聲明了一個(gè)公共的(public)無參構(gòu)造函數(shù). 這里需要注意: Java源碼中可能并沒有顯式地提供一個(gè)無參構(gòu)造函數(shù),但編譯過程(通過AOSP的build系統(tǒng)纹磺,比如
aapt
)會(huì)自動(dòng)生成這樣的構(gòu)造器. - <init>是默認(rèn)無參構(gòu)造函數(shù)名稱. ()V:表示返回值為空,并且無參數(shù).
- .registers指定了方法內(nèi)使用寄存器的總數(shù),也就是說 registers指令告知編譯器分配多少空間來存放這些臨時(shí)變量
- .line 11表明該代碼行對(duì)應(yīng)于源文件中的第11行峦睡。在實(shí)際編譯過程中膀估,這通常是注釋的一部分,幫助追蹤原始代碼位置雨涛。
- invoke-direct是間接調(diào)用父類的構(gòu)造函數(shù)
- {p0}: 是參數(shù)列表,p0 是第一個(gè)參數(shù)的位置引用,對(duì)于構(gòu)造函數(shù)而言兜挨,通常不需要提供參數(shù),因?yàn)闃?gòu)造函數(shù)是用來初始化新創(chuàng)建的對(duì)象的眯分,所以這里是空參數(shù)列表.
- Landroidx/appcompat/app/AppCompatActivity 這部分指定了要調(diào)用的具體構(gòu)造函數(shù)屬于 AppCompatActivity 類
- return-void: 結(jié)束構(gòu)造函數(shù)并返回void(即無返回值).
- .end method 結(jié)束方法
3.3: 普通方法
.method private test()V
.registers 1
.line 26
return-void
.end method
這里就很簡(jiǎn)單了, 代表聲明了一個(gè)名稱為test的私有方法. 該方法無返回值, 位于源碼的第26行.
3.4: 點(diǎn)擊事件方法
# virtual methods
.method public synthetic lambda$onCreate$0$MainActivity(Landroid/view/View;)V
.registers 4
.param p1, "view" # Landroid/view/View;
.line 18
new-instance v0, Landroid/content/Intent;
const-string v1, "android.settings.ACCESSIBILITY_SETTINGS"
invoke-direct {v0, v1}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
.line 19
.local v0, "intent":Landroid/content/Intent;
invoke-virtual {p0, v0}, Lcom/test/accessbilitytest/MainActivity;->startActivity(Landroid/content/Intent;)V
.line 20
return-void
.end method
synthetic: 這是編譯器生成的,并非源碼直接提供的.
lambda0$MainActivity 是方法的標(biāo)識(shí)符拌汇,通常在匿名內(nèi)部類中.
(Landroid/view/View;)V 則聲明了 該方法的參數(shù)為View, 無返回值.
.param p1, "view" # Landroid/view/View; 這一行是用來聲明方法參數(shù)的, p1代表了第一個(gè)參數(shù). "view"是參數(shù)名.
new-instance v0, Landroid/content/Intent;這一行代表了創(chuàng)建新對(duì)象的指令, Landroid/content/Intent 代表了創(chuàng)建對(duì)象的類型.
const-string v1, "android.settings.ACCESSIBILITY_SETTINGS" 是一段常量字符串賦值指令."android.settings.ACCESSIBILITY_SETTINGS"就是實(shí)際的字符串?dāng)?shù)據(jù).
invoke-direct {v0, v1}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V 則是代表了創(chuàng)建了Intent對(duì)象,傳入了字符串類型參數(shù). (Ljava/lang/String;)V 描述了參數(shù)列表和返回類型,其中 V 表示無返回值
.local v0, "intent":Landroid/content/Intent; 這一行則是代表了局部變量的聲明.
3.5: onCreate方法
onCreate方法中有一些類似的我們就省略了.
invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V: 這一行用于聲明父類onCreate的調(diào)用,{p0,p1}p0這里指的是當(dāng)前對(duì)象的引用(self) ,p1則代表了參數(shù)bundle.
-
const v0, 0x7f0b001c : 是一條常量指令弊决,它告訴編譯器將數(shù)值0x7f0b001c存儲(chǔ)到寄存器v0中噪舀。
這里的0x7f0b001c是一個(gè)十六進(jìn)制的整數(shù)魁淳,通常在資源ID(Resource ID)的表示中看到,因?yàn)樗赡軐?duì)應(yīng)于XML布局文件中的某個(gè)控件id与倡、字符串資源或其他資源. 我們可以全局搜索就可以看到0x7f0b001c,是在R$layout.smali 中定義的: .field public static final activity_main:I = 0x7f0b001c.
move-result-object v0:將findViewById的結(jié)果賦值給同樣名為v0的變量
本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布界逛!