近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中。当然,文中许多介绍参考了许多零散的文章,本文重点工作在于对相关概念的整理收集,并按相对合理顺序引出后文中对hook技术中的一些难点的解读。
Android平台大多采用了ARM架构的CPU,而ARM属RISC,与X86架构的处理器有不同的特征,本文讲介绍ARM中不容易理解的PC寄存器各种问题,包括ARM流水线、PC寄存器指向问题、ARM和Thumb指令的区分及相关概念在native层hook中的应用问题。
1.ARM寄存器介绍
ARM微处理器共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器。但是这些寄存器不能被同时访问,具体哪些寄存器是可以访问的,取决ARM处理器的工作状态及具体的运行模式。但在任何时候,通用寄存器R14~R0、程序计数器PC、一个状态寄存器都是可访问的。
简言之,在用户模式下ARM可见的寄存器有16个32位的寄存器(R0到R15)和一个当前程序状态寄存器CPSR,其中R15是程序计数器PC,R14用于存储子程序的返回地址LR,R13用于存储堆栈栈顶SP。
本文我们将着重介绍一下R15寄存器,即PC寄存器。理论上,PC寄存器应指向即将执行的下一条指令的地址,然而在实际应用中却发现PC寄存器总不是如此。经过翻看资料发现,该问题是由于ARM存在的指令流水线导致的。
2.ARM流水线介绍
流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一。也就是说,通过划分指令执行过程中的不同阶段,并通过并行执行,从而提高指令的执行效率。ARM7处理器采用了三级流水线结构,包括取指(fetch)、译码(decode)、执行(execute)三级。