51Testing软件测试论坛

标题: Android 反编译 -smali语法 [打印本页]

作者: 技术小妞    时间: 2015-8-1 17:19
标题: Android 反编译 -smali语法

前面有说过android反编译的工具,如何进行反编译。反编译后可以得到jar或者得到smali文件。Android采用的是java语言 进行开发,但是Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali。我们反编译得到的代 码,jar的话可能很多地方无法正确的解释出来,如果我们反编译的是smali则可以正确的理解程序的意思。因此,我们有必要熟悉smali语法。

类型的表示
java里面包含两种类型,原始类型和引用类型(包括对象),同时映射到smali也是有这两大类型。
原始类型
对象类型
L 表示这是一个对象类型
package/name 该对象所在的包
ObjectName 对象名称
; 标识对象名称的结束
数组的表示
[I 表示一个int型的一维数组,相当于int[];
增加一个维度增加一个[,如[[I表示int[][]
数组每一个维度最多255个;
对象数组表示也是类似,如String数组的表示是[Ljava/lang/String
寄存器与变量
java中变量都是存放在内存中的,android为了提高性能,变量都是存放在寄存器中的,寄存器为32位,可以支持任何类型,其中long和double是64为的,需要使用两个寄存器保存。
寄存器采用v和p来命名
v表示本地寄存器,p表示参数寄存器,关系如下
如果一个方法有两个本地变量,有三个参数
当然,如果是静态方法的话就只有5个寄存器了,不需要存this了。
.registers 使用这个指令指定方法中寄存器的总数
.locals 使用这个指定表明方法中非参寄存器的总数,放在方法的第一行。
方法和字段的表示
方法的定义
比如我下面的一个方法
使用编译后是这样
从上面可以看到函数声明使用.method开始 .end method结束,java中的关键词private,static 等都可以使用,同时使用签名来表示唯一的方法,这里是sum(II)I。
声明成员
.field private namepackage/name/ObjectName;
比如:private TextView mTextView;表示就是
.field private mTextViewandroid/widget/TextView;
private int mCount;
.field private mCount:I
指令执行
smali字节码是类似于汇编的,如果你有汇编基础,理解起来是非常容易的。
比如:
move v0, v3 #把v3寄存器的值移动到寄存器v0上.
const v0, 0x1 #把值0x1赋值到寄存器v0上。
invoke-static {v4, v5}, Lme/isming/myapplication/MainActivity;->sum(II)I #执行方法sum(),v4,v5的值分别作为sum的参数。
其他
通过前面我们可以看到,smali就是类似汇编,其中很多命令,我们可以去查它的手册来一一对应。学习时,我们可以自己写一个比较简单的java文件,然后转成smali文件来对照学习。
下面,我贴一个我写的一个比较简单的java文件以及其对应的smali,其中包含if判断和for循环。
java文件:
对应的smali:


作者: empire    时间: 2015-10-29 16:49
好文章,学习了,怒赞




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2