繁体   English   中英

覆盖函数指针后面的c静态函数

[英]Overwrite c static function behind function-pointer

我有一个问题,几个星期后我无法解决。 我确信有一个解决方案,也许这里有一个想法。

有一个名为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知识,这不会影响过程的实例,只影响我自己的实例。

这意味着:进程仍然在其实例后面有原始的write -function ,只有我的实例才会调用MY_WRITE_FUNCTION

我知道无法强制进程重新加载HAL_MODULE_INFO_SYM并调用HAL_MODULE_INFO_SYM-> methods-> open(设备) - 因此更改此符号将不起作用。

我无法更改外部代码,也无法更改libaudio.so。 我只能访问自己的小libplugin.so。

如果有人可以帮助我,我会非常感激。

我认为它可以完成,但只有在进程调用libaudio.so 之前进行干预。

那时,您可以在HAL_MODULE_INFO_SYMlibaudio.so的地址(使用dlopen ,如您所建议的),将methods指针复制到某处并用指向您自己的方法结构的指针替换它。 该结构中的方法只是从保存的指针调用原始方法。
就其本身而言,这没有任何成果,但是在open真正的open之后,你的open方法可以看到返回的dev并操纵它。

如果你没有及时完成,那么进程已经有了它的dev指针,我认为你无法改变它。

但我想警告你,这一切看起来都很脆弱,并且取决于libaudio.so实现的细节。 它很容易导致麻烦,特别是如果将来更改库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM