綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[教程] Smail語法(1)

[複製連結] 查看: 1871|回覆: 0|好評: 0
跳轉到指定樓層
樓主
fam1001 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2016-3-28 13:24

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
【情景分析】Android apk,反編譯之後,我們能閱讀到的代碼是 dalvik位元組碼 - smali 。有時候,工作需要,必須破解apk裡面的一些協議或者方法。以此,借鑒經驗,來開發自己的項目。
【語法】

一. 資料類型
  1. 原始類型:

  2. V void,只能用於返回值類型
  3. Z     boolean
  4. B   byte
  5. S   short
  6. C   char
  7. I   int
  8. J   long(64位)
  9. F   float
  10. D   double(64位)

  11. 引用類型:

  12. 對像 和 數組
複製代碼

Smail表現形式
  1. 原始類型:用大寫字母代替即可,用法無異
  2. 引用類型:

  3.   對像:<strong> L + 包名.對像 +</strong> ;
  4.       對象的表示則以L作為開頭,格式是LpackageName/objectName;(注意必須有個分號跟在最後),例如String對像在smali中為:Ljava/lang/String;,其中java/lang對應java.lang包,String就是定義在該包中的一個對象。
  5.     數組:<strong>[ + 資料類型</strong>
  6.      數組的表示方式是:在基本類型前加上前中括號「[」,例如int數組和float數組分別表示為:[I、[F [I——表示一個整型一維數組,相當於java中的int[]。
  7.    對於多維數組,只要增加[就行了。[[I相當於int[][],[[[I相當於int[][][]。注意每一維的最多255個。
  8.    對像數組的表示:[Ljava/lang/String;表示一個String對像數組。
複製代碼

二. 方法

方法定義:
  1. 表示形式:Lpackage/name/ObjectName;->MethodName(III)Z
  2.     Lpackage/name/ObjectName;表示類型,MethodName是方法名。III為參數(在此是3個整型參數),Z是返回類型(bool型)。
  3.     方法的參數是一個接一個的,中間沒有隔開。
  4. 一個更複雜的例子:
  5. method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
  6. 在java中則為:
  7. String method(int, int[][], int, String, Object[])
複製代碼


內部類:
  1. 既然類是用LpackageName/objectName;來表示,那類裡面的內部類又如何在smali中引用呢?答案是:LpackageName/objectName$subObjectName;。也就是在內部類前加「$」符號
複製代碼


字段:
  1. 表示形式:
  2. Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;  即包名,字段名和各字段類型。
複製代碼


標記說明:
  1. # static fields             定義靜態變量的標記
  2. # instance fields        定義實例變量的標記
  3. # direct methods       定義靜態方法的標記
  4. # virtual methods      定義非靜態方法的標記
  5. 構造函數的返回類型為V,名字為<init>。
複製代碼


語法:If語句
  1. if-eq p1, v0, :cond_8 表示如果p1和v0相等,則執行cond_8的流程:
  2.     :cond_8
  3.     invoke-direct {p0}, Lcom/paul/test/a;->d()V
  4. 調用com.paul.test.a的d()方法
  5. if-ne p1, v0, :cond_b 表示不相等則執行cond_b的流程:
  6.     :cond_b
  7.     const/4 v0, 0x0
  8.     invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
  9.     invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
  10.     move-result v0
  11.   
  12. 大概意思就是調用com.paul.test.a的setPressed方法,然後再調用父類View的onKeyUp方法,最後 return v0
複製代碼


三. 寄存器(重點)

概念:
  1. 在dalvik位元組碼中,寄存器都是32位的,能夠支援任何類型。64位類型(Long和Double型)用2個寄存器表示。
  2. 有兩種方式指定一個方法中有多少寄存器是可用的。
  3.   .registers指令指定了方法中寄存器的總數。 [注意:一個方法內,不允許超過15個;如果超過15個,需要做特殊處理,處理方法找google大神,度娘]
  4.   .locals指令表明了方法中非參寄存器的數量。
複製代碼


命名方式
  1. 有兩種方式——V命名方式和P命名方式。P命名方式中的第一個寄存器就是方法中的第一個參數寄存器。在下表中我們用這兩種命名方式來表示上一個例子中有5個寄存器和3個參數的方法。
  2. v0  第一個local register
  3. v1  第二個local register
  4. v2  p0  第一個parameter register
  5. v3  p1  第二個parameter register
  6. v4  p2  第三個parameter register
  7. 你可以用任何一種方式來引用參數寄存器——他們沒有任何差別。
  8. 注意:baksmali預設對參數寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers選項。
  9. 使用P命名方式是為了防止以後如果要在方法中增加寄存器,需要對參數寄存器重新進行編號的缺點。

  10. Long/Double值
  11. Long和double類型是64位的,需要2個寄存器(切記切記)。
  12. 例如,對於非靜態方法LMyObject;->MyMethod(IJZ)V,參數分別是LMyObject;,int,long,bool。故該方法需要5個寄存器來存儲參數。

  13. p0  this
  14. p1  I
  15. p2,p3   J
  16. p4  Z
複製代碼
「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)

評分

參與人數 3碎鑽 +2 幫助 +3 收起 理由
Jabbar + 1 + 1 非常讃
球-球 + 1 好內容,老衲來為這篇文章開開光.
bebravelove77 + 1 + 1 很給力!

查看全部評分

收藏收藏3 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
回覆

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則