4.smali語(yǔ)法學(xué)習(xí)筆記

smali語(yǔ)言還是相對(duì)純機(jī)器碼來(lái)說(shuō),比較容易理解的
--但最好是結(jié)合工具一起學(xué)--
--還可以參考其他的整理文章--

先來(lái)一個(gè)最簡(jiǎn)單的模型類


simpeModel.java

對(duì)應(yīng)的smali


simpleModel.smali

(表格只是簡(jiǎn)單做一個(gè)映射關(guān)系的整理)

java smali description
package .class 包名
extends .super 父類名
class .source 類名
params .field 定義字段
int I int類型
Integer Ljava/lang/Integer Integer類型
引用類型 Lxx/xx/xx 該引用類型的完整包名
boolean Z 布爾值
byte B 字節(jié)
short S 短整型
char C 字符
long J 長(zhǎng)整型
float F 浮點(diǎn)數(shù)
double D 浮點(diǎn)數(shù)
void V 無(wú)
數(shù)組類型 [ 數(shù)組
function .method 定義方法
constructor 構(gòu)造器方法
.prologue 開始了
.registers 申請(qǐng)寄存器的個(gè)數(shù),貌似不用關(guān)心這個(gè)
.line x 對(duì)應(yīng)源java文件行數(shù)
兩個(gè)簡(jiǎn)單的方法
image.png

func1括號(hào)里有Lxx/xx/xx說(shuō)明有形參,形參類型是String,也有返回值,返回值類型也是String
.param 指名 形參名 value
.prologue以下開始正式的代碼邏輯
.line 38 ,源碼38行的代碼
return-object 返回該對(duì)象的引用,其實(shí)就是把p0里的值返回來(lái)。

func2無(wú)形參,返回值類型String
const-string 聲明了一個(gè)String 類型的變量 ,值是 "abcdefg"
.local 說(shuō)是 指定了使用的局部變量的個(gè)數(shù),我這里簡(jiǎn)單的認(rèn)為,就是把v0給了一個(gè)局部變量 func2string

簡(jiǎn)單的if-else判斷
fun3的smali

沒(méi)想到這么長(zhǎng)。
這里有點(diǎn)繞,根據(jù)


跳轉(zhuǎn)指令
if-else跳轉(zhuǎn)指令

當(dāng)vB為0的時(shí)候


image.png

則直接翻譯smali為

L93-int類型形參num,放到寄存器p1

L96~L97-源碼47行,如果p1的值小于等于0,跳到cond_3

L99~L102-源碼49行,結(jié)束local寄存器p1,跳到goto_2,
返回p1的值

L104~L109-源碼48行,重開寄存器p1,cond_3 入口
如果p1的值 不等于0,跳到cond_7
否則(也就是p1等于0)把 0x0這個(gè)值給p1,然后跳到goto_2

L113~L115 -也就是源碼49行,cond_7入口,
neg-int對(duì)第一個(gè)p1進(jìn)行求補(bǔ),然后把值給第二個(gè)p1

L117~L118 -goto_2入口,end_method

是不是感覺(jué)和java代碼func3看起來(lái)不一樣?
我給自己的解釋是類似java內(nèi)存模型發(fā)生了重排序的優(yōu)化,也不知道對(duì)不對(duì),有大神知道的話評(píng)論區(qū)求解答。
不過(guò)回過(guò)頭來(lái)再看這個(gè)smali,
順序上雖然和源碼順序并不一致,但是按照直接翻譯的意思去寫java代碼

if( p1 <= 0){
    if(p1 != 0)return -p1
    else return 0
} else return p1

結(jié)果是一樣的。

再來(lái)一個(gè)


image.png
image.png

有了func3的翻譯經(jīng)驗(yàn)
func4就很好翻譯了
if-eqz p1,也就是形參num p1等于0的話,直接到cond_3,賦值0,最后返回。
其余的直接返回p1

if(p1 == 0)return 0
else return p1

這個(gè)優(yōu)化感覺(jué)更能說(shuō)服自己了,==操作比!=操作更簡(jiǎn)單

來(lái)一個(gè)switch跳轉(zhuǎn)


switch

太長(zhǎng)了

L145~L146-源碼59行,拿p1做switch(packed-switch關(guān)鍵字)偏移區(qū)pswitch_data_a
要看到底部
L174~L179-實(shí)際上只有兩個(gè)case需要做判斷 pswitch-6和pswitch-8(也就是兩個(gè)偏移區(qū))
L156~L163-pswitch_6,把0x0給v0,跳到goto_5
L165~L172-pswitch_8,把0x1給v0,跳到goto_5
L151~L154-goto_5入口把int型的本地(.local關(guān)鍵字)參數(shù)result指向寄存器v0,返回v0
其余的 把0x29a給v0

int result;
switch(p1){
  case pswitch_6:
          result = 0;
          break;
  case pswitch_8:
          result = 1;
          break;
  default:
          result = 0x29a;
          break;
}
return result;

相當(dāng)于幫我優(yōu)化了case -1,因?yàn)閏ase -1和default都是同樣的處理方法


常用的加log打印信息的方法


image.png
System.out.println("sout");
Log.d("log", func2())

那加入在有些情況下,調(diào)用Log.d,該類并沒(méi)有引入
android.util.Log包怎么辦?


通過(guò)完整的包名調(diào)用
我發(fā)誓這兩種寫法,smali編譯出來(lái)是一樣的

放一個(gè)四哥的自定義代碼添加方案
以上筆記,僅供參考。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,169評(píng)論 1 10
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,623評(píng)論 18 399
  • 一、海賊錢包 活動(dòng)時(shí)間:4月12日-4月18日(7天) 活動(dòng)內(nèi)容:活動(dòng)期間內(nèi)每日累計(jì)充值指定金額,可以獲得對(duì)應(yīng)獎(jiǎng)勵(lì)...
    趙様閱讀 330評(píng)論 0 0
  • 《我們》 是被同一道雷電劈中的兩棵樹 是黑夜里最高傲的兩朵火苗 是被巨石隔開的兩條河 是暴風(fēng)驟雨里相擁合流的兩條路...
    何攔偉閱讀 398評(píng)論 6 5
  • 七號(hào)田閱讀 117評(píng)論 0 1

友情鏈接更多精彩內(nèi)容