溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Smali——初識

發布時間:2020-08-01 11:29:43 來源:網絡 閱讀:720 作者:wauoen 欄目:開發技術

原文鏈接:https://github.com/JesusFreke/smali/wiki

一、概述

    smali和backsmali是dalvik虛擬機使用的dex文件的匯編器和反匯編器,它寬松的語法基于Jasmin/dedexer語法,并支持dex格式的所有功能。

二、寄存器

    dalvik字節碼中,寄存器是32位的,可以存放任意類型的值。64位數據類型可以使用連個寄存器來存放。

(1)指定一個方法中寄存器的數量

    有兩種方式可以指定一個方法中可用寄存器的數量。.register指令指定了方法中寄存器的總數,另一種方式,.locals指令指定了方法中非參數寄存器的數量。寄存器的數量包括存放方法參數的寄存器。

(2)方法的參數是如何傳入一個方法

    當一個方法被執行,方法的參數將被存放到最后n個寄存器中。如果一個方法有兩個參數,五個寄存器(v0-v4),則參數將被存放到最后兩個寄存器v3和v4中。

    非靜態方法的第一個參數總是執行該方法的對象。例如,非靜態方法LMyObject;->callMe(II)V中有兩個×××參數,但是它在兩個×××參數之前隱含一個LMyObject;參數,所以該方法中總共有三個參數。

    我們可以指定這個方法中有五個寄存器,可以使用.registers 5指令或者.local 2指令(連個local寄存器和3個參數寄存器)。一旦這個方法被執行,執行該方法的對象將會被存放到v2中,第一個×××參數存放到v3中,第二個×××參數被存放到v4中。

    對于靜態方法也是一樣的,只是沒有隱含該參數。

(3)寄存器命名

    存在兩種寄存器命名方案,正常的v命名方案和針對參數的p命名方案。p命名方案中第一個寄存器是方法中第一個參數。上個例子中有三個參數和總共五個寄存器。下表分別是v命名方案和p命名方案:

LocalParam
v0
第一個local寄存器
v1
第二個local寄存器
v2p0第一參數寄存器
v3p1第二個參數寄存器
v4p2第三個參數寄存器

(4)引入參數寄存器的動機

    p命名方案的引進是很實用的事情,用來解決在編輯smali代碼時一個普通的問題。

    例如存在一個有一定數量參數的方法,你將在該方法中添加一些代碼并且你發現你需要一個額外的寄存器。此時你想:“沒什么大不了的,我只需要修改.register指令就可以了”。不幸的的是,它并沒有這么簡單。注意,參數被存放在最后的寄存器中。如果你增加了寄存器的數量,也就是說你改變了參數get和put的位置。所以你不得不改變.register指令并且必須對每個參數寄存器進行重新編碼。但是如果你使用p命名方案,你可以簡單的改變寄存器的數量而不需要擔心重新編碼已經存在的寄存器。

    注意:默認情況下,baksmali使用p命名方法。如果你想強制baksmali使用v命名方案,你可以使用

-p/--no-parameter-register選項。

(5)Long、Double

    前面提到過,long和double是64位值,需要兩個寄存器。這一點是非常重要的。例如,你有個一非靜態方法:LMyObject;->MyMethod(IJZ)V.該方法的參數為:LMyObject;、int、long、bllo。所以該方法需要5個寄存器存放所有的參數:

RegisterType
p0this
p1I
p2,p3J
p4Z

三、Types、Methods、Fields

(1)Types

    dalvik的字節碼有兩大類型:primitive types和reference types。Reference types是對象和數組,其他的都是primitive type。

    primitives用一個字母表示。這些縮略詞不是我提出來的,它們實際上以字符串形式存放在dex文件中。在dex-format.html文檔中有詳細的說明。

Vvoid-can only be used for return types
Zboolean
Bbyte
Sshort
Cchar
Iint
Jlong(64bits)
Ffloat
Ddouble(64bits)

    對象的形式:Lpackage/name/ObjectName;L表示它是一個對象類型,package/name/是對象的包,ObjectName是對象的名字,;表示對象名字的結尾。在java中等價于package.name.ObjectName。例如,Ljava/lang/String;等價于java.lang.String。數組的形式[I-表示為一維×××數組,例如:int[]。要表示多維數組只需要簡單的增加‘[’的數量。[[I=int[][],[[[I=int[][][]等等。注意:數組的最大維度為255.也可以表示對象的數組,例如:[Ljava/lang/String;表示一個字符串數組。

(2)Methods

    methods總是被表示為一個非常冗長的形式包括:包含方法的類型、方法的名稱、參數的類型和返回類型。虛擬機需要這些信息才能正確的定位方法,在字節碼中執行靜態方法。

Methods形式例子:

    Lpackage/name/ObjectName;->MethodName(III)Z

在這個例子中:Lpackage/name/ObjectName;為類型,MethodsName是方法的名稱。(III)Z是方法的聲明。III表示有三個int類型的參數,Z表示返回類型是boolean。

一個更加復雜的例子:

    method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

java中表示為:

    String method(int,int[][],int,String,Object[])

(3)Fields

    同樣的,fields總是表示為一個冗長的形式包括:包含field的類型、field的名稱、field的類型。同樣的,這是為了讓虛擬機可以找到正確的field,同樣的適用于字節碼上的靜態分析。

Fieldsde 形式:

    Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

向AI問一下細節
推薦閱讀:
  1. 初識UNIX
  2. puppet 初識

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女