馬上加入Android 台灣中文網,立即免費下載應用遊戲。
您需要 登錄 才可以下載或查看,沒有帳號?註冊
x
【情景分析】Android apk,反編譯之後,我們能閱讀到的代碼是 dalvik位元組碼 - smali 。有時候,工作需要,必須破解apk裡面的一些協議或者方法。以此,借鑒經驗,來開發自己的項目。
【語法】
一. 資料類型
- 原始類型:
-
- V void,只能用於返回值類型
- Z boolean
- B byte
- S short
- C char
- I int
- J long(64位)
- F float
- D double(64位)
-
- 引用類型:
-
- 對像 和 數組
複製代碼
Smail表現形式
- 原始類型:用大寫字母代替即可,用法無異
- 引用類型:
-
- 對像:<strong> L + 包名.對像 +</strong> ;
- 對象的表示則以L作為開頭,格式是LpackageName/objectName;(注意必須有個分號跟在最後),例如String對像在smali中為:Ljava/lang/String;,其中java/lang對應java.lang包,String就是定義在該包中的一個對象。
- 數組:<strong>[ + 資料類型</strong>
- 數組的表示方式是:在基本類型前加上前中括號「[」,例如int數組和float數組分別表示為:[I、[F [I——表示一個整型一維數組,相當於java中的int[]。
- 對於多維數組,只要增加[就行了。[[I相當於int[][],[[[I相當於int[][][]。注意每一維的最多255個。
- 對像數組的表示:[Ljava/lang/String;表示一個String對像數組。
複製代碼
二. 方法
方法定義:
- 表示形式:Lpackage/name/ObjectName;->MethodName(III)Z
- Lpackage/name/ObjectName;表示類型,MethodName是方法名。III為參數(在此是3個整型參數),Z是返回類型(bool型)。
- 方法的參數是一個接一個的,中間沒有隔開。
- 一個更複雜的例子:
- method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
- 在java中則為:
- String method(int, int[][], int, String, Object[])
複製代碼
內部類:
- 既然類是用LpackageName/objectName;來表示,那類裡面的內部類又如何在smali中引用呢?答案是:LpackageName/objectName$subObjectName;。也就是在內部類前加「$」符號
複製代碼
字段:
- 表示形式:
- Lpackage/name/ObjectName;->FieldName:Ljava/lang/String; 即包名,字段名和各字段類型。
複製代碼
標記說明:
- # static fields 定義靜態變量的標記
- # instance fields 定義實例變量的標記
- # direct methods 定義靜態方法的標記
- # virtual methods 定義非靜態方法的標記
- 構造函數的返回類型為V,名字為<init>。
複製代碼
語法:If語句
- if-eq p1, v0, :cond_8 表示如果p1和v0相等,則執行cond_8的流程:
- :cond_8
- invoke-direct {p0}, Lcom/paul/test/a;->d()V
- 調用com.paul.test.a的d()方法
- if-ne p1, v0, :cond_b 表示不相等則執行cond_b的流程:
- :cond_b
- const/4 v0, 0x0
- invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
- invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
- move-result v0
-
- 大概意思就是調用com.paul.test.a的setPressed方法,然後再調用父類View的onKeyUp方法,最後 return v0
複製代碼
三. 寄存器(重點)
概念:
- 在dalvik位元組碼中,寄存器都是32位的,能夠支援任何類型。64位類型(Long和Double型)用2個寄存器表示。
- 有兩種方式指定一個方法中有多少寄存器是可用的。
- .registers指令指定了方法中寄存器的總數。 [注意:一個方法內,不允許超過15個;如果超過15個,需要做特殊處理,處理方法找google大神,度娘]
- .locals指令表明了方法中非參寄存器的數量。
複製代碼
命名方式
- 有兩種方式——V命名方式和P命名方式。P命名方式中的第一個寄存器就是方法中的第一個參數寄存器。在下表中我們用這兩種命名方式來表示上一個例子中有5個寄存器和3個參數的方法。
- v0 第一個local register
- v1 第二個local register
- v2 p0 第一個parameter register
- v3 p1 第二個parameter register
- v4 p2 第三個parameter register
- 你可以用任何一種方式來引用參數寄存器——他們沒有任何差別。
- 注意:baksmali預設對參數寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers選項。
- 使用P命名方式是為了防止以後如果要在方法中增加寄存器,需要對參數寄存器重新進行編號的缺點。
- Long/Double值
- Long和double類型是64位的,需要2個寄存器(切記切記)。
- 例如,對於非靜態方法LMyObject;->MyMethod(IJZ)V,參數分別是LMyObject;,int,long,bool。故該方法需要5個寄存器來存儲參數。
-
- p0 this
- p1 I
- p2,p3 J
- p4 Z
複製代碼 |
評分
-
查看全部評分
|