覆盖函数指针后面的c静态函数
我有一个问题,几个星期以来一直无法解决。 我相信有一个解决方案,也许这里有一个想法 有一个名为libaudio.so的共享库,如下所示:覆盖函数指针后面的c静态函数,c,static,shared-libraries,overriding,C,Static,Shared Libraries,Overriding,我有一个问题,几个星期以来一直无法解决。 我相信有一个解决方案,也许这里有一个想法 有一个名为libaudio.so的共享库,如下所示: static ssize_t out_write(..) { // /!\ I need to overwrite/extend this function return 0; } static int adev_open_output_stream(struct audio_stream_out **stream_out) { st
static ssize_t out_write(..)
{
// /!\ I need to overwrite/extend this function
return 0;
}
static int adev_open_output_stream(struct audio_stream_out **stream_out)
{
struct stream_out *out;
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
if (!out)
return -ENOMEM;
out->stream.write = out_write; // pointer to static function above
*stream_out = &out->stream;
return 0;
}
static int adev_open(hw_device_t** device)
{
struct audio_device *adev;
adev = calloc(1, sizeof(struct audio_device));
if (!adev)
return -ENOMEM;
adev->hw_device.open_output_stream = adev_open_output_stream; // pointer to static function above
*device = &adev->hw_device.common;
return 0;
}
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open, // this function can be called after obtained via dlsym() below
};
struct audio_module HAL_MODULE_INFO_SYM = {
.methods = &hal_module_methods, // this field is public available and can be called via dlsym()
};
下面我的代码(也是一个名为libplugin.so的共享库)作为一个进程下的插件运行
此进程以前打开libaudio.so(如上),获取*HAL_MODULE\u INFO\u SYM*并调用
HAL_MODULE_INFO_SYM->methods->open(device)
我无法访问进程的设备-实例,因此我不能用
struct audio_stream_out **stream_out
device->open_output_stream(stream_out)
stream_out.write = MY_WRITE_FUNCTION
但我希望:
由于我运行的进程与以前dlopen'd the libaudio.so的进程相同,因此我也可以调用dlopen(“libaudio.so”),并将获得与以前进程相同的对此库的引用
我也可以调用dlsym(HAL_MODULE_INFO_SYM),然后获得相同的公共结构。
然后我可以调用open和*open\u output\u stream*,然后理论上更改指向write函数的指针
但是,从我开始的C语言知识来看,这不会影响流程的实例,只会影响我自己的实例
这意味着:进程在其实例后面仍然有原始的write-函数,只有我的实例才会调用my_write_函数
我不知道如何强制进程重新加载HAL\u模块信息\u SYM并调用HAL\u模块信息\u SYM->方法->打开(设备)-因此更改此符号无效
我不能更改外部代码,也不能更改libaudio.so。我只能访问我自己的小libplugin.so
如果有人能帮助我,我将非常感激。我认为这是可以做到的,但前提是你在调用libaudio.so之前进行干预 那时,您可以在
libaudio.so
中获得HAL\u MODULE\u INFO\u SYM
的地址(按照您的建议,使用dlopen
),将方法
指针复制到某个地方,并将其替换为指向您自己方法结构的指针。该结构中的方法只需从保存的指针调用原始方法。就其本身而言,这没有任何作用,但是您的
open
方法可以在调用真实的open
后,查看返回的dev
并对其进行操作
如果您没有及时完成,进程已经有了它的dev
指针,我认为您无法更改它
但我想提醒大家,这一切似乎都很脆弱,取决于
libaudio.so
实现的细节。这很容易导致麻烦,特别是如果将来更改库。您希望覆盖函数指针而不是实际的函数代码,对吗?还有,我猜你要找的符号不是从库中导出的?libaudio.so是如何构造和构建的?正如我所说的,我对C语言比较陌生,所以我不明白你问的所有问题。但我知道,调用我的libplugin.so的进程以前称为handle=dlopen('libaudio.so',现在称为RTLD_);dlsym(手柄、HAL\u模块\u信息\u SYM)->方法->打开(设备);和设备->打开输出流(..)。除了libplugin.so以外的所有代码都不在我的范围内,并且在一个不受我控制的运行系统上。out->stream.write
等。您知道变量out
未初始化,指向la-la-land吗?它不指向已分配的内存。当然这不可能是真正的代码,请发布它。如果这是真实的代码,那么函数指针是众多严重问题中最小的一个……哦,你说得对。编辑,谢谢!是的,这会起作用,但遗憾的是,我的插件是在libaudio之后加载的。因此,顺序无法更改:)我几乎没有寻找强制重新加载该部分的方法。。