0

Linux プログラムの機能をフックしようとしています。基本的に、mprotect で関数の保護を解除して検索し、元の関数アドレス内に jmp を配置して、関数フックにリダイレクトします。

ただし、元の関数をコピーして、変更された関数が必要ないときに呼び出すことができるようにしたいと考えています。私はこのような一種のフックを持っています

int CallHookedFunctionFoobar(int param1, int param2)
{
      if (g_somevariable)
           Foobar_original(param1, param2);
      else
           Foobar_modified(param1, param2);
}

だから私の質問は... どうすれば関数のサイズをバイト単位で知ることができるので、動的に割り当てられたバッファに memcpy() して実行することができますか?

短い逆アセンブラを埋め込んで、RETN オプトコードが見つかるまでオペコードを解析することを考えましたが、まったくすべてのケースで機能するかどうかはわかりません (たとえば、複数の RETN が同じ関数に存在する場合:[)

これを実行したいもう 1 つの理由は、同じ関数が別のライブラリにフックされている可能性があるためです。

4

1 に答える 1

3

まず、これが Linux 固有のものである場合、おそらく実行可能ファイルはELFバイナリです。そのため、ELF ヘッダーを (libelfたとえば、を使用して) 解析するだけで、関数の長さを検索/計算できます。

ただし、なぜこれが必要なのかわかりません。私が考えることができるより簡単なアプローチは、オンザフライで関数にパッチを適用し、最初のいくつかの命令をJMPまたはCALLフック関数に置き換え、上書きされた命令を保存して後でパッチを適用することです。何かのようなもの:

void call_hooked(void (*fn)(), unsigned char *ctx, size_t *n)
{
    unsigned char hook_patch[] = { 0x15, 0x20, 0x7f, 0x48 }; // I bluffed
    *n = sizeof(hook_patch);
    memcpy(ctx, fn, sizeof(hook_patch));
    memcpy(fn, hook_patch, sizeof(hook_patch));
    fn();
}

void call_orig(void (*fn)(), unsigned char *ctx, size_t n)
{
    memcpy(fn, ctx, n);
    fn();
}
于 2013-04-10T18:57:58.733 に答える