用静态或动态链接包装符号

问题描述 投票:0回答:1

我想以一种有效的方式包装库符号(即,创建一个调用原始功能的自定义覆盖(在我的二进制及其依赖的库两者上强制使用),无论我是静态链接库还是静态链接库)动态地。

如果我使用-Wl,--wrap方法(gcc / clang),它可用于静态链接,但与动态链接一起使用不会使动态链接的库调用包装的符号。如果我创建了一个通过dlsym调用原始函数的直接替代,则它确实会使相关的(动态)库使用包装的符号,但这需要我动态链接。

是否有一种方法可以同时使用两种链接?

下面的示例构建脚本演示了该问题:

#!/bin/sh -eu

cat > main.c <<EOF
#define _GNU_SOURCE
#include <stdio.h>
extern int puts_from_lib(void);
int nr_puts;
#if !DLSYM

    //this only works with static linking
    int __real_puts(char const*);
    int __wrap_puts(char const*X)
    {
        __real_puts("OVERRIDE");
        nr_puts++;
        return __real_puts(X);
    }

#else

    //this only works with dynamic linking
    #include <dlfcn.h>
    int puts(char const *X)
    {
        int (*real_puts)(char const*)=(int(*)(char const*))dlsym(RTLD_NEXT,"puts");
        real_puts("OVERRIDE");
        nr_puts++;
        return real_puts(X);
    }

#endif

int main(int C, char **V)
{
    printf("\\nV[0]=%s\n", V[0]);
    puts("puts from main");
    puts_from_lib();
    printf("nr_puts = %d\\n", nr_puts);
}
EOF


cat > lib.c <<EOF
#include <stdio.h>
int puts_from_lib(void)
{
    return puts("puts from lib");
}
EOF

mac=-DDLSYM

gcc -g -DDLSYM lib.c  -c -fpic
gcc -g -DDLSYM main.c  -c -fpic -o dmain.o
gcc -g main.c  -c -fpic
gcc lib.o -o lib.so -shared
rm -f lib.a; ar rcs lib.a lib.o
gcc dmain.o $PWD/lib.so  -o shared -ldl
gcc dmain.o lib.a  -o static_with_dlsym -static -ldl
gcc main.o lib.a -Wl,--wrap=puts  -o static -static
gcc main.o $PWD/lib.so  -Wl,--wrap=puts -o broken_shared -ldl
./static
./shared
./broken_shared
./static_with_dlsym

构建脚本输出:

V[0]=./static
OVERRIDE
puts from main
OVERRIDE
puts from lib
nr_puts = 2

V[0]=./shared
OVERRIDE
puts from main
OVERRIDE
puts from lib
nr_puts = 2

V[0]=./broken_shared
OVERRIDE
puts from main
puts from lib
nr_puts = 1
Segmentation fault (core dumped)
c linker static-linking dynamic-linking
1个回答
-1
投票

发布的代码显示了__wrap_puts()的原型,但未定义例程。尝试创建与此类似的例程:

© www.soinside.com 2019 - 2024. All rights reserved.