3

数週間前から解決できない問題があります。解決策があると確信しており、ここにアイデアがあるかもしれません。

次のような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したのと同じプロセスで実行しているため、 dlopen("libaudio.so") を呼び出すこともでき、以前のプロセスと同じライブラリへの参照を取得できます。

dlsym(HAL_MODULE_INFO_SYM) を呼び出して、同じ公開構造を取得することもできます。次に、 openと *open_output_stream* を呼び出し、理論的にはポインタをwrite関数に変更します。

しかし、私の最初の C 知識では、それはプロセスのインスタンスには影響せず、私自身のインスタンスにのみ影響します。

これは、プロセスのインスタンスの背後に元のwrite関数がまだあり、私のインスタンスだけがMY_WRITE_FUNCTIONを呼び出すことを意味します。

プロセスにHAL_MODULE_INFO_SYMを強制的にリロードさせ、 HAL_MODULE_INFO_SYM->methods->open(device)をリコールさせる方法がわかりません。したがって、このシンボルを変更しても機能しません。

外側のコードを変更することも、libaudio.so を変更することもできません。私は自分の小さな libplugin.so にしかアクセスできません。

誰かが私を助けることができれば、彼はとても感謝しています.

4

1 に答える 1

1

できると思いますが、プロセスが呼び出すlibaudio.soに介入した場合に限ります。

その時点で、 in のアドレスを取得HAL_MODULE_INFO_SYMlibaudio.sodlopen提案したように を使用)、methodsポインターをどこかにコピーして、独自のメソッド構造へのポインターに置き換えることができます。その構造体のメソッドは、保存されたポインターから元のメソッドを呼び出すだけです。
これ自体は何も達成しませんが、openメソッドは real を呼び出した後open、返さdevれた を見て操作することができます。

間に合わなかった場合、プロセスには既にdevポインターがあり、それを変更する方法はありません。

libaudio.soしかし、それはすべて壊れやすいように見え、実装の詳細に依存することを警告したいと思います. 特にライブラリが将来変更された場合は、非常に簡単に問題が発生します。

于 2013-06-11T10:39:15.377 に答える