LD_PRELOAD,patchelf 与 hook

之前一篇文章说明过 elf 当中的符号决议顺序,最先被解析的符号先入为主,作为最终被使用的符号,本篇的用到的代码同之前的一篇相同。

LD_PRELOAD

LD_PRELOAD 的原理就是在先于所有依赖的动态库,提前加载 LD_PRELOAD  环境变量当中指定的库。

main.out 依赖外部动态库 libmyprintf.so 的 myprintf 函数,依赖的动态库在编译时,被写入到可执行文件当中,可以使用

readelf -d

来查看。

LD_PRELOAD,patchelf 与 hook

 加入此时另外有个动态库 libmsgprint.so 当中,也导出了函数 myprintf,可以使用 libmsgprint.so 中的 myprintf 来覆盖 libmsgprint.so 当中的 myprintf.

LD_PRELOAD,patchelf 与 hook

 patchelf

相较于 LD_PRELOAD 的那种非侵入的方式,可以使用 patchelf 来直接修改可执行的 elf  二进制文件,将 libmsgprint.so 库也加入到可执行文件的依赖库列表当中,而且要在之前的 libmyprintf.so 函数之前。

LD_PRELOAD,patchelf 与 hook

 hook

如果在先入为主的函数当中调用因为滞后被加载而被覆盖的符号,这样就能实现 hook 的效果。hook 这里使用 RTLD_NEXT 这个伪句柄,需要起始就定义 _GNU_SOURCE 宏,因为并没有被 SYSv3 标准定义。

//msgprint.c

#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>


void myprintf(char* msg)
{
    printf("comes from libmsgprint.so %s\n", msg);

    void (*out)(char* msg) = dlsym(RTLD_NEXT,"myprintf");
    out(msg);
}

LD_PRELOAD,patchelf 与 hook

 

上一篇:智能指针


下一篇:怎么设置 HSTS 头字段