我目前工作的一个项目,我需要跟踪的几个系统调用和类似的低层次功能的使用mmap,brk,sbrk。到目前为止,我一直在使用函数插入进行此操作:我编写了一个与要替换的函数同名的包装函数(mmap例如,),并通过设置LD_PRELOAD环境变量将其加载到程序中。我通过加载的指针调用实函数dlsym。
mmap
brk
sbrk
LD_PRELOAD
dlsym
不幸的是,我要包装的函数之一由sbrk内部使用dlsym,因此当我尝试加载符号时程序崩溃。sbrk在Linux中不是系统调用,因此我不能简单地使用syscall它来间接调用它。
syscall
所以我的问题是,如何在不使用同名包装函数的情况下调用库函数dlsym?是否有任何编译器技巧(使用gcc)可以让我引用原始功能?
参见ld的option --wrap symbol。从手册页:
--wrap symbol
--wrap symbol对符号使用包装函数。任何未定义的符号引用都将解析为“ __wrap_symbol”。任何对“ __real_symbol”的未定义引用都将解析为符号。 这可以用来为系统功能提供包装。包装函数应称为“ __wrap_symbol”。如果希望调用系统功能,则应调用“ __real_symbol”。 这是一个简单的示例:
--wrap symbol对符号使用包装函数。任何未定义的符号引用都将解析为“ __wrap_symbol”。任何对“ __real_symbol”的未定义引用都将解析为符号。
__wrap_symbol
__real_symbol
这可以用来为系统功能提供包装。包装函数应称为“ __wrap_symbol”。如果希望调用系统功能,则应调用“ __real_symbol”。
这是一个简单的示例:
void * __wrap_malloc (size_t c) { printf ("malloc called with %zu\n", c); return __real_malloc (c); }
如果您使用–wrap malloc将其他代码与此文件链接,则所有对“ malloc”的调用都会调用函数“ __wrap_malloc”。在 “ __wrap_malloc”中对“ __real_malloc”的调用将调用真实的“ malloc”函数。 您可能还希望提供一个“ __real_malloc”函数,以便不带–wrap选项的链接将成功。如果这样做,则不应将“ __real_malloc” 的定义与“ ”放在同一文件中__wrap_malloc;如果您这样做,则汇编程序可能会在链接程序有机会将其包装到“ malloc”之前解决该调用。
如果您使用–wrap malloc将其他代码与此文件链接,则所有对“ malloc”的调用都会调用函数“ __wrap_malloc”。在 “ __wrap_malloc”中对“ __real_malloc”的调用将调用真实的“ malloc”函数。
malloc
__wrap_malloc
您可能还希望提供一个“ __real_malloc”函数,以便不带–wrap选项的链接将成功。如果这样做,则不应将“ __real_malloc” 的定义与“ ”放在同一文件中__wrap_malloc;如果您这样做,则汇编程序可能会在链接程序有机会将其包装到“ malloc”之前解决该调用。
__real_malloc
另一个选择是可能查看ltrace的源,或多或少地执行相同的操作:-P。
这是个主意。您可以让您LD_PRELOAD的ed库将PLT条目更改为指向您的代码。sbrk()从技术上来说,这仍然可以从您的代码天然地调用该函数。
sbrk()