3

これは過剰に答えられた質問のように思えますが、これは異なります。いくつかのメソッドをエクスポートするこの ActiveX オブジェクトがあります。そのメソッドの 1 つにフックを設定する必要があります。つまりFunc1、 などを使用してこれを行う方法を知っていVirtualProtect()ます。ollydbg を開いて ActiveX DLL を掘り下げるとFunc1、フックを設定する必要がある場所の正確なアドレスが表示されます。

Visual Studio 2008 を使用して、プリコンパイラ ディレクティブを使用しています。

#import "myactx.dll" no_namespace, named_guids, raw_interfaces_only

そして私のコードでは、これをやろうとしています:

LPVOID ptr = &IMyActx::Func1;

コンパイル時にエラーを返します:

エラー C2440: '初期化中': 'HRESULT (__stdcall IMyActx::* )(BSTR,BSTR)' から 'LPVOID' に変換できません。

私が調査したところ、暗黙的なパラメーターのために、クラスへのポインターを関数へのポインターにキャストできないことがわかりましたthis

ただし、この関数を呼び出すつもりはありません。メモリ内のアドレスを知りたいだけで、それをフック ルーチン (LPVOIDポインタを想定) に渡すことができます。

関数を呼び出すことはできるが、メモリ内の生のアドレスを取得できないということは、私には考えられないようです。必要なポインターを取得するためだけに、x86 アセンブリ コードを挿入したくなります。

読んでくれてありがとう。

編集...考えてみると...純粋な仮想クラスであるLPVOID ptr = &IMyActx::Func1;ため、機能しないはずです! IMyActxとにかく、オブジェクトをインスタンス化して生のポインターを取得しようとする前に、いくつかの組み合わせを試しましたが、Func1これまでのところ何も機能しませんでした。Func1への呼び出しが次のように生成されることを ollydbg で確認します。

mov edx, [eax];
call dword ptr ds:[edx + 0x1C];

DWORDしたがって、 atvptr + 0x1Cバイトを読み取る必要があると想定できます。

私の記憶が正しければ、Component Object Model は、常に同じインターフェイス ID が与えられたFunc1ptrであることを保証します。[vptr + 0x1C]永遠に。右?

やや疑似コードで、おそらく次のようなことをします。

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

CoCreateInstance(CLSID_MyActx, 0, CLSCTX_ALL, IID_IMyActxObj, (LPVOID*) &pObj);

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];
4

2 に答える 2

1

COM オブジェクトのメソッドは、実際には通常の関数です。これが、C++ ではなく C で記述された COM クライアントを有効にする理由です。

C クライアント用のヘッダー ファイルを生成することをお勧めします。そうすれば、関数のアドレスを簡単に取得できます。ただし、最初にフックするクラスのインスタンスが必要です。

于 2011-04-10T22:29:32.753 に答える
0

私があなたを正しく理解していれば、クラスメソッドへのポインターを関数ポインターにキャストしたいと考えています。

これは実際には不可能です。

簡単な例:

class A {
    public:
    void func()
    {
        this->var = 0;
    }
    int var;
};

A myObj;
A::func* ptr2 = &(myObj::func); // works
void* ptr = &(myObj::func); // doesn't: what would "this" in line 5 point to?

も使えませんreinterpret_cast

この問題も一度ありました。次に、入力値をオブジェクトへのポインターにマップする関数を作成するだけで済みました。おそらく、メソッドへのポインタを持つことでメソッドを呼び出すラッパー関数を作成できますか?

于 2011-04-10T16:29:24.017 に答える