質問

私はすでに存在しているシステムでは、IDispatchインターフェイスの動作を変更しようとしています。 この私の計画を行うには、実行時にオブジェクトのv-テーブルにフックし、それが代わりにカスタムフックメソッドを指すようポインタを変更することでした。

私はこの仕事を得ることができる場合、私はすでに既存のオブジェクトに新しいメソッドとプロパティを追加することができます。ニースます。

まずはのIUnknown用のVテーブル(のIDispatchから継承する)及びその加工された微細にフックしようとしました。しかし、すべてでは動作しないのIDispatch内の変更のentiresにしようとしています。何が全く起こらない、コードはフックなしでやったように動作します。

ここでは何の問題を理解してはならないので、それは非常にシンプルですが、コードの

#include <iostream>
#include <windows.h>
#include <Objbase.h>
#pragma comment (lib,"Ole32.lib")
using namespace std;

HRESULT __stdcall typecount(IDispatch *self,UINT*u)
{
    cout << "hook" << endl;
    *u=1;
    return S_OK;
}


int main()
{
    CoInitialize(NULL);

    // Get clsid from name
    CLSID clsid;
    CLSIDFromProgID(L"shell.application",&clsid);

    // Create instance
    IDispatch *obj=NULL;
    CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(IDispatch),(void**)&obj);

    // Get vtable and offset in vtable for idispatch
    void* iunknown_vtable= (void*)*((unsigned int*)obj);
    // There are three entries in IUnknown, therefore add 12 to go to IDispatch
    void* idispatch_vtable = (void*)(((unsigned int)iunknown_vtable)+12);

    // Get pointer of first emtry in IDispatch vtable (GetTypeInfoCount)
    unsigned int* v1 = (unsigned int*)iunknown_vtable;

    // Change memory permissions so address can be overwritten
    DWORD old;
    VirtualProtect(v1,4,PAGE_EXECUTE_READWRITE,&old);

    // Override v-table pointer
    *v1 = (unsigned int) typecount;

    // Try calling GetTypeInfo count, should now be hooked. But isn't works as usual
    UINT num=0;
    obj->GetTypeInfoCount(&num);

/*
    HRESULT hresult;
    OLECHAR FAR* szMember = (OLECHAR*)L"MinimizeAll";
    DISPID dispid;
    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
    hresult = obj->GetIDsOfNames(IID_NULL, &szMember, 1,
    LOCALE_SYSTEM_DEFAULT, &dispid) ;
    hresult = obj->Invoke(dispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD,&dispparamsNoArgs, NULL, NULL, NULL); 
*/

}

事前に感謝します!

役に立ちましたか?

解決

// Get pointer of first emtry in IDispatch vtable (GetTypeInfoCount)
unsigned int* v1 = (unsigned int*)iunknown_vtable;

これはacturely QueryInterfaceIUnknownを引っかけます。

あなたのtypecount

に起動しますルートに続いて

//obj->GetTypeInfoCount(&num);
LPVOID dummy;
obj->QueryInterface(IID_NULL, &dummy);

他のヒント

私は、あなたが、これは32ビットと64ビットの間で移植できるように書き直すべきだと思います。

オリジナルます:

   // There are three entries in IUnknown, therefore add 12 to go to IDispatch
    void* idispatch_vtable = (void*)(((unsigned int)iunknown_vtable)+12);

ポータブルます:

   // There are three entries in IUnknown, therefore add 3 pointers to go to IDispatch
    void* idispatch_vtable = (void*)(((DWORD_PTR)iunknown_vtable) + (sizeof(void *) * 3));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top