主要思路是找到被hook函數(shù)地址绝页,并將被hook函數(shù)地址執(zhí)行指令替換成jmp <地址偏移量>母怜,這個地址由hook函數(shù)地址和target函數(shù)地址相減計(jì)算而來,jmp相對跳轉(zhuǎn)指令占5個字節(jié)芍瑞,還需要減去這個長度:
需要跳轉(zhuǎn)的地址偏移量=hook地址-被hook地址-5
具體代碼如下:
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <stdint.h>
// 原始函數(shù)
void target_function() {
printf("Original function\n");
}
// 鉤子函數(shù)
void hook_function() {
printf("Hooked function\n");
}
// 設(shè)置內(nèi)聯(lián)鉤子函數(shù)
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;
}
運(yùn)行結(jié)果如下:
從打印結(jié)果可以看出拘领,原方法已經(jīng)被替換為hook方法。
查看objdump也可以計(jì)算出同樣的結(jié)果:
hook函數(shù)地址為0x4005bd烫罩,被hook函數(shù)地址為0x4005ad
則jmp偏移量=0x4005bd - 0x4005ad -5 = 0xb = 11
與偏移量計(jì)算打印結(jié)果符合