我知道 LD_PRELOAD 可用于拦截对共享库中函数的调用(如果应用程序不是静态链接的)。但是,我不知道如何使用它向应用程序添加附加功能或后台线程。
例如,我认为 Berkeley labs checkpoint/restart 使用此方法将后台线程添加到稍后可能会被检查点的应用程序。
所以,现在的问题是,如何在事先不知道从该应用程序调用共享库的哪些函数的情况下,如何使用 LD_PRELOAD 将线程注入到已编译的应用程序中?
我知道 LD_PRELOAD 可用于拦截对共享库中函数的调用(如果应用程序不是静态链接的)。但是,我不知道如何使用它向应用程序添加附加功能或后台线程。
例如,我认为 Berkeley labs checkpoint/restart 使用此方法将后台线程添加到稍后可能会被检查点的应用程序。
所以,现在的问题是,如何在事先不知道从该应用程序调用共享库的哪些函数的情况下,如何使用 LD_PRELOAD 将线程注入到已编译的应用程序中?
这是一件很简单的事情-您可以实现_init函数-这将是void _init(void) {},并且您可以在其中使用pthread_create(假设您将库与-lpthread链接)。您应该使用您需要的其他 -l 依赖项来编译您的库。GCC 将允许您将硬编码的 _init() 替换为另一个入口点,该入口点也由 __attribute(构造函数)指定。无论如何,你的入口点会被 LD 调用。
当您的库被注入时,它会在所有其他库之前被注入,但它自己的依赖项也会得到解决,因此您进行的任何调用通常都可以(一个值得注意的例外是,如果您拦截稍后调用的函数,您需要使用 dlfcn API 安全地执行此操作)。