【发布时间】:2022-01-24 05:52:18
【问题描述】:
我正在尝试使用 preload.so 中的sscanf(),它是从 preload.c 生成的。
为了检查我的sscanf() from preload.so 是否被调用,我添加了额外的打印语句:printf("test\n");
我有什么遗漏吗?
文件内容如下:
//preload.c
#include <stdarg.h>
#include <stdio.h>
__attribute__((force_align_arg_pointer)) int sscanf(const char *str, const char *format, ...)
{
int ret;
va_list ap;
va_start(ap, format);
printf("test\n");
ret = vsscanf(str, format, ap);
va_end(ap);
return ret;
}
//foo.c
#include <stdio.h>
int main(void)
{
int i;
sscanf("42", "%d", &i);
printf("%d\n", i);
return 0;
}
我正在执行以下步骤:
# gcc -fPIC -shared preload.c -o preload.so -ldl -D_GNU_SOURCE=1
# export LD_PRELOAD=$PWD/preload.so
# gcc foo.c -o foo
test
test
test
test
test
test
test
test
test
test
test
O/p 我得到了:
# echo $LD_PRELOAD
/AMIT/sscanf_override/preload.so
# ./foo
42
# LD_PRELOAD=$PWD/preload.so ./foo
42
预期的输出是:
$ gcc foo.c -o foo
$ LD_PRELOAD=$PWD/preload.so ./foo
test
42
即使 ldd 输出指向 preload.so,如下所示,仍然在执行时优先考虑系统的 sscanf() 而不是 preload.so
root@***sscanf_override]# ldd foo
linux-vdso.so.1 (0x00007fff4a5e0000)
/AMIT/sscanf_override/preload.so (0x00007f1cf270a000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1cf2345000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f1cf2141000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1cf290c000)
[root@***sscanf_override]#
这里的调整是,如果我删除 -D_GNU_SOURCE=1,它会起作用,gcc -fPIC -shared preload.c -o preload.so -ldl 但是如果不将 GNU_SOURCE 定义为将来使用的必要条件,我就无法继续。
正如@Rachid K 所建议的那样,当我重新定义我的 preload.c 时它起作用了:
#include <stdarg.h>
#include <stdio.h>
__attribute__((force_align_arg_pointer)) int sscanf(const char *str, const char *format, ...)
{
int ret;
va_list ap;
va_start(ap, format);
printf("test\n");
ret = vsscanf(str, format, ap);
va_end(ap);
return ret;
}
__attribute__((force_align_arg_pointer)) int __isoc99_sscanf(const char *str, const char *format, ...)
{
int ret;
va_list ap;
va_start(ap, format);
printf("test\n");
ret = vsscanf(str, format, ap);
va_end(ap);
return ret;
}
【问题讨论】:
标签: c linux dynamic-library ld-preload