第3章Android Dalvik虚拟机 第二节

来源:互联网 发布:淘宝的分销平台在哪里 编辑:程序博客网 时间:2024/06/10 15:53


第3章 第二节Dalvik虚拟机汇编

1、 环境配置Ubuntu 15.10 IP:192.168.153.130
2、 介绍Dalvik虚拟机汇编


1、 Dalvik汇编指令
1) 指令格式
每16个字符用空格分开例子:
A|B|C|D  E|F|G
2) 每4位字符表示一个字母例子:
A|   (注意:A代表4位字符)
3) 顺序从A~Z的单个字母作为4个操作符,注意:如op表示为8位操作码例子:
A|B|C|D  E|F|op
4) 如出现“ø”表示这个字段所有为0 
5) 偏移值表示例子:
A|B|C|D BBBB


2、 指令的确认
1) 指令格式标示大多以3个字符组成,前面2个位位数字,后1个位为字母
2) 第1个数字是表示指令有多少个16位的字组成
3) 第2个数字是表示指令最多使用寄存器个数。
(注意:“r”表示标示取一定范围内的寄存器)
4) 第3个字母为类型码,表示指令用到的而外的指令
5) 其他特殊情况,如果字母为“s”表示静态连接,“i”指令表示内联处理
例子: 24x
2表示16位字组成,4表示最多4个寄存器个数,x表示无额外数据。


3、 其他一些说明
1) 参数采用“vX”方式表示,它是个寄存器如v0、v1等。
2) 参数采用“#+X”方式表示,它表示一个常量
3) 参数采用“+X”方式表示,它表示一个指令偏移量
4) 参数采用“strom@X”方式表示,它表示一个常量池索引池。
可以是“string”字符串常量的索引池
可以是“type”类型常量的索引池
可以是“field”字段常量的索引池
可以是“meth”方法常量的索引池
例子:A|B|op VBB strom@BBBB
A和B表示各自的4个操作符,op vBB 表示一个寄存器并且附加一个strom@BBBB常量池索引池。其实这指令代表着const-string指令。
要查指令详细信息可以到安卓源码中的Dalvik/docs/instruction-formats.html




 


4、 使用baksmali 工具进行DEX文件反汇编
java -jar baksmali-2.0.3.jar -o baksmaliout Hello.dex
 



5、 使用ddx.jar工具反汇编Hello.dex
java -jar ddx1.5.jar -d ddout Hello.dex
 


6、 两种汇编生成的文件结构一样,方法名和字段类型与代码指令列上它们保持是一致的。
不同点如下:
1) 前者用baksmali反汇编出来的寄存器“.registers” ,而后者ddx反汇编输出来的“.registers”指令前面加上了limit前缀。
2) 前者使用p0作为引用,而后者使用v2作为引用。
3) 前者使用“.parameter”是指定一个函数的参数,而后者“parameter”数组指定参数寄存器
4) 前者使用“.prologue”方法的开始,而后者则没有。
5) 前者使用p命名方法,后者使用v命名方法。


7、 查询andriod源码下的Dalvik 每个字节码的处理过程路径是:
root@strom-virtual-machine:~/android4.0.3/android-4.0.3_r1/dalvik/vm/mterp/c# 
cat OP_MOVE.cpp |more
HANDLE_OPCODE($opcode /*vA, vB*/)
    vdst = INST_A(inst);
    vsrc1 = INST_B(inst);

    ILOGV("|move%s v%d,v%d %s(v%d=0x%08x)",
        (INST_INST(inst) == OP_MOVE) ? "" : "-object", vdst, vsrc1,
        kSpacing, vdst, GET_REGISTER(vsrc1));
    SET_REGISTER(vdst, GET_REGISTER(vsrc1));
    FINISH(1);
OP_END


8、 查看INST_A和INST_B的声明文件如:
#define INST_A(_inst)       (((_inst) >> 8) & 0x0f)
#define INST_B(_inst)       ((_inst) >> 12)
Inst为一个16位指令,INST_A将_inst右移8位后与0x0f相与,也就是获取_inst高8位的低4位作为vdst的值。而_INST_B将_inst右移12位,就是获取_inst的最高4位作为vsrc1


9、 ILOGV用来输出调试信息
10、 SET_REGISTER用来设置寄存器的值,GET_REGISTER用来获取寄存器的值。
11、 其他寄存器大小类型为:GET_REGISTER_WIDE、GET_REGISTER_FLOAT声明如下:


# define GET_REGISTER(_idx)                 (fp[(_idx)])
# define SET_REGISTER(_idx, _val)           (fp[(_idx)] = (_val))


fp 为ARM栈寄存器,如在虚拟机运行某个函数时它会指向函数的局部变量区,说白了就是维护一份寄存器的列表。GET_REGISTER宏以”_idx“为索引返回一个寄存器值,而SET_REGISTER中的”_idx “为索引使用用来设置寄存器的值,(注意:一个是返回一个是设置)


12、开启寄存器的验证则使用#ifdef CHECK_REGISTER_INDICES,这个为真时会判断” _idx “是否小于寄存器的值,条件不成立说明超出了范围,虚拟机会抛出异常assert(!”bas reg”).


13、FINISH计算指令的长度,然后将pc的寄存器加上计算出来的偏移量,这样指令执行完成后,会执行下一条指令。


14、v和p的两种不同的寄存器写法一致但名称不值,p的寄存器更甚一筹因为比较好容易判断是局部变量寄存器还是参数寄存器,而且在较长的代码的情况下优势更加甚一筹。


15、Dalvik字节码的类型分为如下:


V void - can only be used for return types       # void只用于返回值类型
Z boolean # 布尔型
B byte # 字节型
S short # 短整型
C char # 字符类型
I int # 整型类型
J long (64 bits) # 长整型
F float # 单精度浮点数
D double (64 bits) # 双精度浮点型


16、Dalvik 方法例子:
Method (I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
对应的java形式代码为:
String method(int,int[][],int,String,Object[])


使用baksmali 工具反编译出来的代码为“.method“指令开始,以“.end method”指令结束。
已#virtual method 表示一个虚方法,而 # direct methods 表示一个直接方法。


17、Dalvi 字段例子:
Ljava/lang/System;->out:Ljava/io/PrintStream;


使用baksmali 工具反编译出来的代码为“.field”指令开头,如开头已“.instance field”表示一个实例字段,它是一个静态字段。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 不知怀孕喝了酒怎么办 香氛蜡烛记忆环怎么办 我吃了马兜铃怎么办呀 肝肾衰弱有毒素怎么办 肾阴虚阳虚都有怎么办 吃辣刺激胃疼怎么办 舌头没有舌苔有裂纹疼痛怎么办 舌苔厚黄是怎么回事且口臭怎么办 舌苔厚白是怎么回事且口臭怎么办 长期有舌苔白厚怎么办 小孩的舌苔厚白怎么办 口苦口臭舌苔黄怎么办 婴儿的舌苔厚白怎么办 舌苔黄厚口臭痒怎么办 想让月经提前来怎么办 宝宝拉肚子怎么办吃什么好 投资p2p跑路了怎么办 借钱不还怎么办最有效 朋友借小钱不还怎么办 网络上贷款不还怎么办 网贷实在还不了怎么办 娱乐平台跑路了怎么办 360借条被拒了怎么办 网贷注册太多了怎么办 汽车大绿本丢了怎么办 网贷平台跑路怎么办 电脑中了1kb病毒怎么办 360网页走丢了怎么办 被信和汇金起诉怎么办 qq号搜不到好友怎么办 gta5买的车炸了怎么办 ipad千牛缩小了怎么办 求生之路2卡顿怎么办 仙剑奇侠传1凤凰怎么办打 水温报警灯亮了怎么办 遇到拿刀的歹徒怎么办 微信公众号被骗怎么办 苹果ad账号忘了怎么办 苹果手机想换id怎么办 苹果6按键不会动怎么办 app充值不到账怎么办