我有一个问题,几个星期后我无法解决。 我确信有一个解决方案,也许这里有一个想法。
有一个名为 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)
{
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_INFO_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
但是我希望:
由于我在以前执行过相同的过程中运行 libaudio.so ,我也可以调用dlopen(“libaudio.so”)并获得与此库相同的引用作为之前的过程。
我也可以调用dlsym(HAL_MODULE_INFO_SYM),然后获得相同的公共结构。 然后我可以调用 open 和* open_output_stream *然后理论上将指针更改为 write -function。
但是,用我开始的C知识,这不会影响流程的实例,只会影响我自己的实例。
这意味着:该过程仍然在其实例后面有原始的写入功能,只有我的实例会调用 MY_WRITE_FUNCTION 。
我知道无法强制流程重新加载 HAL_MODULE_INFO_SYM 并调用 HAL_MODULE_INFO_SYM-> methods-> open(设备) - 所以更改此符号会不会不行。
我无法更改外部代码,也无法更改libaudio.so。我只能访问自己的小libplugin.so。
如果有人可以帮助我,我会非常感激。
答案 0 :(得分:1)
我认为可以这样做,但只有在>之前干预过程才会调用libaudio.so
。
那时,您可以在HAL_MODULE_INFO_SYM
中获取libaudio.so
的地址(使用dlopen
,如您所建议的那样),将methods
指针复制到某处并替换为指向您自己的方法结构的指针。该结构中的方法只是从保存的指针调用原始方法
就其本身而言,这没有任何效果,但是在调用真实open
之后,您的open
方法可以查看返回的dev
并对其进行操作。
如果你没有及时完成,那么该进程已经有dev
指针,我认为你无法改变它。
但我想警告你,这一切似乎都很脆弱,并且取决于libaudio.so
实施的细节。它很容易导致麻烦,特别是如果将来更改库。