elf程序在进行动态链接的时候,会将有相同符号名的符号覆盖成LD_PRELOAD指定的so文件中的符号。也就是说,我们可以用自己的so库中的函数替换原来库里有的函数,从而达到hook的目的。
下面我们尝试通过这种hook方式来实现任意地址读/写
测试文件:
test.c:
#include <stdio.h>char xxx[] = "tlsn_wheeler";int main(){puts("nihao");puts(xxx);return 0; }// gcc ./test.c -g -no-pie -o ./test
hook代码:
hook.c:
#include <stdio.h> #include <string.h> #include <dlfcn.h>unsigned char hooking[] = "hook write xD!!!!"; typedef int (*PFN_puts)(const char * s); int puts(const char * s) { void *handle = dlopen("libc.so.6", RTLD_LAZY); PFN_puts old_puts = dlsym(handle, "puts"); // 以备调用 if (!strcmp(s,"nihao")){unsigned long long int hook_addr = 0x000000000404030;// 任意位置读数据unsigned char res[20] ={0}; for(int i=0;i<10;i++){res[i] = *(unsigned char*)(hook_addr+i);}printf("hook read: %s\n",res);// 任意位置写数据for(int i=0;i<13;i++){*(unsigned char*)(hook_addr+i) = hooking[i];}*(unsigned char*)(hook_addr+13) = 0;}else{return old_puts(s);}// printf("hooked!!!");return 0;} // gcc -fPIC -shared -o hook.so hook.c -ldl // LD_PRELOAD=./hook.so ./test
效果: