首页
论坛
专栏
课程

[求助]关于SMALI语法

百年孤独 2012-6-6 21:21 61054
请问哪位大大有SMALI语法的中文版教程?刚接触,想深入看下………………

[防守篇]2018看雪.TSRC CTF 挑战赛(团队赛)11月1日征题开启!

最新回复 (18)
pc小波 1 2012-6-6 23:27
2

0

dalvik字节码有两种类型,原始类型和引用类型。对象和数组是引用类型,其它都是原始类型。
V        void,只能用于返回值类型
Z        boolean
B        byte
S        short
C        char
I        int
J        long(64位)
F        float
D        double(64位)
对象以Lpackage/name/ObjectName;的形式表示。前面的L表示这是一个对象类型,package/name/是该对象所在的包,ObjectName是对象的名字,“;”表示对象名称的结束。相当于java中的package.name.ObjectName。例如:Ljava/lang/String;相当于java.lang.String

数组的表示形式
        [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[])
字段
表示形式:
Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;
即包名,字段名和各字段类型。
寄存器
在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表示。
有两种方式指定一个方法中有多少寄存器是可用的。.registers指令指定了方法中寄存器的总数。.locals指令表明了方法中非参寄存器的数量。
方法的传参
        当一个方法被调用的时候,方法的参数被置于最后N个寄存器中。如果一个方法有2个参数,5个寄存器(v0-v4),那么参数将置于最后2个寄存器——v3和v4。
        非静态方法中的第一个参数总是调用该方法的对象。
例如,非静态方法LMyObject;->callMe(II)V有2个整型参数,另外还有一个隐含的LMyObject;参数,所以总共有3个参数。假如在该方法中指定了5个寄存器(v0-v4),以.registers方式指定5个或以.locals方式指定2个(即2个local寄存器+3个参数寄存器)。当该方法被调用的时候,调用该方法的对象(即this引用)存放在v2中,第一个整型参数存放在v3中,第二个整型参数存放在v4中。
对于静态方法除了没有隐含的this参数外其它都一样。
寄存器的命名方式
有两种方式——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
pc小波 1 2012-6-8 10:39
3

0

补充:
# static fields             定义静态变量的标记
# instance fields        定义实例变量的标记
# direct methods       定义静态方法的标记
# virtual methods      定义非静态方法的标记
构造函数的返回类型为V,名字为<init>。

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
百年孤独 2012-6-10 18:41
4

0

谢谢,有没有更为详细点的命令介绍………………
pc小波 1 2012-6-13 11:29
5

0

举两个例子:

sget-object v5, Lcom/google/youngandroid/runtime;->Lit227:Lgnu/mapping/SimpleSymbol;
获取com.google.youngandroid.runtime中的Lit227字段存入v5寄存器,相当于
gnu.mapping.SimpleSymbol localVariable = com.google.youngandroid.runtime.Lit227;

sput-object v0, Lcom/google/youngandroid/runtime;->Lit78:Lkawa/lang/SyntaxTemplate;
Likewise, this is setting the value of a static field. i.e.
设置com.google.youngandroid.runtime.Lit78的值为v0寄存器中的kawa.lang.SyntaxTemplate类型变量的值。相当于com.google.youngandroid.runtime.Lit78 = kawa.lang.SyntaxTemplate localVariable;
剩下的比较简单你应该能明白了。
wawt 2012-8-16 00:47
6

0

写的真是好!非常值得学习!
周克雷 2012-9-24 19:27
7

0

写得真不错!!!
魔族智者 2012-11-15 13:11
8

0

谢谢楼主分享
ndaye 2013-7-27 01:27
9

0

多谢小波
烈火 2013-7-27 20:51
10

0

很有价值,多谢、波波
飞火 1 2013-11-12 10:44
11

0

写的不错~~
OnlyEnd 2014-3-28 16:43
12

0

mark
FetalError 2014-4-18 12:29
13

0

正在学习,感谢。
bklang 1 2014-4-18 17:32
14

0

求助:packed-switch 0x0
        :pswitch_0
        :pswitch_0
        :pswitch_1

这个switch 的case参数是 0和1么?
xunbu 2014-7-10 10:20
15

0

mark 正在学习 感谢!
cinsondev 2014-7-14 10:46
16

0

mark,感谢分享
weishi 2014-12-11 18:03
17

0

mark 感谢
蟋蟀xd 2015-1-29 18:01
18

0

报错 Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[212,15] no viable alternative at input 'builder'
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[212,23] no viable alternative at input 'Landroid/app/AlertDialog$Builder;'
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[215,98] mismatched input 'Landroid' expecting set null
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[215,106] Error for input '/': Invalid text
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[215,110] Error for input '/': Invalid text
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[217,13] Error for input ';': Invalid text
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[222,99] mismatched input 'Landroid' expecting set null
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[222,107] Error for input '/': Invalid text
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[222,111] Error for input '/': Invalid text
Work\com.uroad.yxw\smali\com\uroad\yxw\start\StartActivity.smali[224,13] Error for input ';': Invalid text
Exception in thread "main" brut.androlib.AndrolibException: Could not smali file: com/uroad/yxw/start/StartActivity.smali
        at brut.androlib.src.SmaliBuilder.buildFile(SmaliBuilder.java:72)
        at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:56)
        at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:41)
        at brut.androlib.Androlib.buildSourcesSmali(Androlib.java:337)
        at brut.androlib.Androlib.buildSources(Androlib.java:298)
        at brut.androlib.Androlib.build(Androlib.java:284)
        at brut.androlib.Androlib.build(Androlib.java:258)
        at brut.apktool.Main.cmdBuild(Main.java:233)
        at brut.apktool.Main.main(Main.java:88)
川zi 2015-8-3 12:38
19

0

好东些,学习了。
返回