首页
社区
课程
招聘
[原创]dalvik解释器阅读笔记
发表于: 2015-8-26 01:19 10352

[原创]dalvik解释器阅读笔记

2015-8-26 01:19
10352
环境:android 4.4.3
本人移动安全小菜一枚,最近在研究indroid的源码,发现里面原来是在dalvik里面插桩,所以就先把dalvik是如何解析指令的过程研究了一番。给人的感觉是这块要是研究透了,万能脱壳真的是可以的。因为无论dex怎么隐藏,最终还是要交给dalvik去解释执行。
Smali汇编一共有200多条不同的指令,每条指令对应的操作码对应源码在dalvik/libdex/DexOpcodes.h文件中,操作码用1个字节表示。smali汇编是不定长指令,而且对应的指令是基于“寄存器”的(每个寄存器都是32位)。(详细的dalvik指令大家看非虫大大的那本书,或者看谷歌提供的资料)。
下面主要拿c语言版本的dalvik解释器进行分析。源码的路径在dalvik/vm/mterp/out/InterpC-portable.cpp。

dalvik真正对指令解析是从dvmInterpretPortable(Thread* self)函数开始的。
下面对几个最重要的变量进行说明:
curMethod*:当前执行的方法。对应的结构体源码在dalvik/vm/oo/Object.h。
fp:这就是dalvik用来模拟寄存器的指针。
pc:pc就是用来取dalvik指令的。
inst:当前执行的指令。通过fetch(0)这个宏来获取的,注意它是2个字节大小。如果大于2个字节,就必须再次通过fetch(_offset)来取源操作数或者目的操作数,fetch(_offset)定义为:#define FETCH(_offset)     (pc[(_offset)])。每一条指令执行完成之后会通过FINSH(_Offset)这个宏来调节pc,使其指向下一条指令的地址。
retval:与函数返回值有关。
methodClassDex:看赋值过程就能明白。从当前执行的方法找到当前方法所在的类,从所在的类找到它所属的dex。
DEFINE_GOTO_TABLE(handlerTable);这个宏是非常重要的。这个宏也定义在dalvik/libdex/DexOpcodes.h,

经过宏替换,相当于定义了一个数组名为handlerTable的数组,里面的每一个数据也是宏,宏的定义就在dalvik/vm/mterp/out/InterpC-portable.cpp文件中。
# define H(_op)     &&op_##_op。##就是进行参数连接。最终经过宏展开后,该数组的第一个数据为:&&op_OP_NOP。其余的一样进行替换。为啥里面的数据都是void*类型,实际是因为&& 之后op_OP_NOP是标号。
下面额外说明一个关于标号的用法。因为dalvik解释器每一条指令都是goto 标号去执行的。

这个程序就会输出2222222222222 这一行。
接着对dvmInterpretPortable(Thread* self) 函数继续分析:

FINISH(0)就是对第一条指令进行解析。

ADJUST_PC(_offset)这个宏的作用实际上就是用来调节pc的位置,使pc每次指向我们要执行指令的位置。FETCH(0)前面已经说过,获得这条指令的前两个字节赋给inst。
下面看goto *handlerTable[INST_INST(inst)]这句. INST_INST(inst)也是一个宏。宏定义:#define INST_INST(_inst) ((_inst) & 0xff)  可知,这是用来取操作码的。
而操作码的数值实际上跟前面说的handlerTable索引是一一对应的。假设此时操作码值为0,根据前面提到的标号用法,此时goto *handlerTable[INST_INST(inst)]就是goto op_OP_NOP。
接着FINISH(0)往下看,下面就是每一条指令如何执行的宏。比如第一条指令为

HANDLE_OPCODE(OP_NOP) 同样也是一个宏。宏定义为:
#define  HANDLE_OPCODE(_op) op_##_op:
进行替换就成了op_OP_NOP:。这就跟前面的goto连上了。
当然NOP是什么都不做,直接FINISH(1)调节pc的位置获取下一条指令了。
每一条指令执行完成之后都会调用FINISH这个宏。通过前面执行完的指令大小,设置对应的FINISH宏参数,调节pc位置。
这个就是一个最简单的指令分析了,还有一些细节性的东西没有说清楚,还请见谅。对于其它复杂的指令,大家也可以对着分析,就会发现更细致的东西,比如fp指针是如何模拟寄存器的等等。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 1392
活跃值: (5177)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
2
跟着楼主学习。哈哈
2015-8-26 08:13
0
雪    币: 50
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
额....indroid的源码在哪里有?我也想学习一下~谢谢
2015-8-27 18:18
0
雪    币: 98
活跃值: (364)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
4
github里有
2015-8-27 20:28
0
雪    币: 7818
活跃值: (1073)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
这也不是说Indroid代码呀,只是说了最简单的dvm执行流程。
2016-3-16 10:23
0
游客
登录 | 注册 方可回帖
返回
//