我想使用open
从libc
覆盖LD_PRELOAD
:
#include <dlfcn.h>
#include <sys/stat.h>
extern "C" {
int open(const char *path, int flags, mode_t mode)
{
int (*originalOpen)(const char *path, int flags, mode_t mode);
originalOpen = reinterpret_cast<decltype(originalOpen)>(dlsym(RTLD_NEXT, "open"));
//originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
//...
return (*originalOpen)(path, flags, mode);
}
}
我使用g++ -fPIC -shared -o open.so open.cpp -ldl
进行编译。
有人可以告诉我上面的代码为什么起作用,为什么会出错:
error: invalid cast from type ‘void*’ to type ‘int(const char*, int, mode_t)’ {aka ‘int(const char*, int, unsigned int)’}
originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
当我初始化originalOpen
并注释掉该行时?
我使用了gcc version 8.0.1
。
答案 0 :(得分:3)
尝试以下代码:
originalOpen = reinterpret_cast<decltype(open) *>(dlsym(RTLD_NEXT, "open"));
在要创建函数指针时,Decltype获取函数的类型。从函数到其类型的指针都有隐式强制转换,但它们并不等效。这就是使用decltype(original_open)
的版本可以完美工作的原因-original_open
的类型是函数指针而不是函数。