手上的机器是 Oneplus 3T, Android 6.0.1 有时候 NFC Emulator 好用,有时候又不行,手工改 libnfc-nxp.conf 有时候可以有时候不可以,主要表现为可能会变成 随机ID 或者 固定为某个特别的ID 所以就很气,想折腾一下能不能从底层搞事情。
基于 libinject2-64 这个库并没有实现 hook 机制,没办法只能搞点事情了。
根据官方的解释,Aarch64已经不支持直接读写PC了,原文:

根据官方的意思,应该用控制流的指令去改变PC,

所以用 BR Xm是可以搞事情的。尝试这么去构造一下跳转,把这些指令覆盖掉准备要hook的函数的内存的前一段空间
_hook_start_s: # 把被hook函数的地址放入x28 LDR x28, _target_fn_address # 跳转到prehook函数地址 BR x28 _target_fn_address: nop
编译一下,objdump得到字节码
a.out: file format elf64-littleaarch64 Disassembly of section .text: 0000000000000000 : 0: 5800005c ldr x28, 8 4: d61f0380 br x28 0000000000000008 : 8: d503201f nop
所以可以有以下代码
struct hook_t {
unsigned int jump[3];
unsigned int store[3];
unsigned char jumpt[20];
unsigned char storet[20];
unsigned int orig;
unsigned int patch;
unsigned char thumb;
unsigned char name[128];
void *data;
};
h->thumb = 0; h->patch = (unsigned int)hook_arm; // prehook函数的地址 h->orig = addr; // 目标函数入口 h->jump[0] = 0x5800005c; // ldr x28, 8 h->jump[1] = 0xd61f0380; // br x28 h->jump[2] = h->patch; // 目标地址 for (i = 0; i < 3; i++) h->store[i] = ((int*)h->orig)[i]; //保存被hook函数的前12字节,方便之后恢复 for (i = 0; i < 3; i++) ((int*)h->orig)[i] = h->jump[i]; // 替换掉被hook函数的前三条指令
上面的代码就完成了对目标函数跳走的逻辑了