如何调用从LD_PRELOAD加载的库构造函数中的可执行文件?

时间:2014-03-20 14:35:28

标签: c gcc ld shared-libraries ld-preload

我希望能够从我预加载的库中调用可执行文件。要做到这一点 -

我有一个简单的可执行文件

的main.c

#include <stdio.h>

void callme()
{
    printf("callme\n");
}

int main(int argc, char *argv[])
{
    callme();
    return 0;
};

这是用

编译的
gcc -m32 main.c

我现在想要预加载一个库,以便在callme之前调用main

preload.c

extern void callme();

void preload_init() __attribute__((constructor));
void preload_fini() __attribute__((destructor));

void preload_init()
{
    callme();
}

void preload_fini()
{
    callme();
}

这是用

编译的
gcc -D_GNU_SOURCE -shared -o libpreload.so preload.c -fPIC -m32 -ldl

现在我有a.outlibpreload.so

当我尝试运行此

LD_PRELOAD=./libpreload.so ./a.out
./a.out: symbol lookup error: ./libpreload.so: undefined symbol: callme

要调试这个我试过

LD_DEBUG=symbols LD_PRELOAD=./libpreload.so ./a.out

此输出包含此行

13184:     symbol=callme;  lookup in file=./a.out [0]

所以它看起来像是在查找callme符号的正确位置。

nm a.out的输出包括以下行

080483b4 T callme

我是否必须以一种从a.out外部可以从外部访问callme的方式进行编译?

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

-rdynamic添加到程序的编译标志中。默认情况下,只有共享库与动态符号表链接(动态链接器(例如/lib/ld-linux.so.2)用于按名称查找函数地址的表)。

如果没有动态符号表,您也无法在自身二进制文件上使用dlsym