-
-
[原创]开源 基于C++实现的armv8asmjit
-
发表于:
2017-9-29 23:20
7855
-
[原创]开源 基于C++实现的armv8asmjit
缘由:
那时候也想转android端逆向。也想对arm指令研究一番。去看过capstore源码,里面做了很多优化,不方便学习。而且capstore对arm和armv8是完全分开处理的。从android 6.0开始,已经开始使用armv8架构了。觉得armv8以后是趋势。所以打算干脆拿armv8指令练手。本想写个反汇编引擎, 但capstore写的已经特别好了,写出来自己也不会用。也就提不起什么兴趣。由于那时候对vmp也比较感兴趣。拜读过xiaowei的Wproject代码,也自己参照Wproject实现过精简版(只模拟了几条指令,主要是为了研究学习),对vmp也理解个大概。但是wp不支持arm,听说作者也不打算写了。然后就想要不自己写个arm版本的。就算写不成也能学习到不少。说干就干,第一个难题就摆在眼前。Wproject的虚拟机引擎是由开源项目asmjit生成的。但是asmjit不支持arm和armv8。没办法,只能自己参照手册写一个。
armv8 A64:
通用寄存器文件和堆栈指针:
通用寄存器文件中的31个通用寄存器被命名为R0-R30,并编码在指令寄存器字段,值为0-30。编码值31的通用寄存器字段表示根据指令和操作数位置,指定当前堆栈指针或零寄存器。当在特定指令变量中使用寄存器时,它们必须有资格指示操作数数据大小,32位或64位,以及指令的数据大小。当数据大小为32位时,使用寄存器的低32位,并在读取时忽略高32位并在写入时清零。
通用寄存器文件和堆栈指针:
通用寄存器文件中的31个通用寄存器被命名为R0-R30,并编码在指令寄存器字段,值为0-30。编码值31的通用寄存器字段表示根据指令和操作数位置,指定当前堆栈指针或零寄存器。当在特定指令变量中使用寄存器时,它们必须有资格指示操作数数据大小,32位或64位,以及指令的数据大小。当数据大小为32位时,使用寄存器的低32位,并在读取时忽略高32位并在写入时清零。
AArch64
指令解析:
和X86有所不同,X86根据第一个字节能确定操作码。而
AArch64需要根据类别。
AArch64长度是固定4字节大小。根据第25-28bit来确定属于哪一大类指令。
AArch64将指令归为以下几大类(如下图):
拿ADR指令举例:ADR指令属于Data Processing-immediate这个大类下,PC-rel. addressing这个子类中。
从上图可以看到根据第31位决定是ADR指令还是ADRP指令。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课