主要思路是找到被hook函数地址,并将被hook函数地址执行指令替换成jmp <地址偏移量>,这个地址由hook函数地址和target函数地址相减计算而来,jmp相对跳转指令占5个字节,还需要减去这个长度:
需要跳转的地址偏移量=hook地址-被hook地址-5
具体代码如下:
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <stdint.h>
// 原始函数
void target_function() {
printf("Original function\n");
}
// 钩子函数
void hook_function() {
printf("Hooked function\n");
}
// 设置内联钩子函数
void set_inline_hook(void *target, void *hook) {
unsigned char *p = (unsigned char *)target;
unsigned char jump[5] = {0xE9}; // jmp 指令
printf("hook: %p\n", hook);
printf("hook: %p\n", (unsigned char *)hook - p - 5);
printf("hook: %d\n", (int)((unsigned char *)hook - p - 5));
*((int *)(jump + 1)) = (int)((unsigned char *)hook - p - 5);
mprotect((void *)((uintptr_t)p & ~0xFFF), 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(p, jump, 5);
mprotect((void *)((uintptr_t)p & ~0xFFF), 0x1000, PROT_READ | PROT_EXEC);
}
int main() {
set_inline_hook((void *)target_function, (void *)hook_function);
target_function();
return 0;
}
运行结果如下:
image.png
从打印结果可以看出,原方法已经被替换为hook方法。
查看objdump也可以计算出同样的结果:
image.png
hook函数地址为0x4005bd,被hook函数地址为0x4005ad
则jmp偏移量=0x4005bd - 0x4005ad -5 = 0xb = 11
与偏移量计算打印结果符合