Android阵营新出机型的cpu基本都是64位了,虽然可以向下兼容armeabi-v7a,但是使用32位的so毕竟不能充分发挥64位cpu的潜力,所以以后arm64-v8a用的会越来越多。但是整个安卓生态圈似乎还没有开源发布的ARM64内联HOOK方案,所以自己动手写了个,姑且取名And64InlineHook吧,需要注意的是仍然是Alpha版。
关于Inline Hook的背景知识这里不再阐述,我仅支持了相对简单的函数首指令改写方案,原则上也支持函数任意位置HOOK(需自行处理堆栈),不支持短函数,也暂不支持AArch32 state。
由于arm64-v8a指令集都是固定的32位,指令地址也因而是4字节对齐,相比变长指令处理起来会相对容易,但是没办法直接操作PC寄存器,A64处理跳转起来会比A32和T32繁琐。
首先是计算需要覆盖的指令数,我的方案是计算目标函数和转接函数的距离,然后决定是使用 B直接转跳 还是 BR寄存器绝对转跳,其中B只会影响一条指令,是比较优的路径,但是它的转跳范围不能超过0b00001111111111111111111111111100;BR需要占用4-5条指令(就我目前的方案而言,即把地址直接写在代码里),因为我们需要设法把地址加载到寄存器,这就需要类似下面的操作,然后为什么是5条指令?因为对于LOAD操作我们需要考虑内存对齐,于是可能需要一条额外的NOP指令来填充。