Question

Je suis en train de modifier le comportement d'une interface IDispatch déjà présent dans le système. Pour ce faire, mon plan était d'accrocher dans les objets v-table lors de l'exécution et de modifier les pointeurs afin qu'il pointe vers une méthode de crochet personnalisé à la place.

Si je peux obtenir ce travail que je peux ajouter de nouvelles méthodes et propriétés à des objets déjà existants. Nice.

D'abord, j'ai essayé de brancher dans le v-table pour IUnknown (à partir de laquelle IDispatch hérite de) et qui a bien fonctionné. Cependant essayer de changer entires dans IDispatch ne fonctionne pas du tout. Rien ne se passe pas du tout, le code fonctionne comme il l'a fait sans le crochet.

Voici le code, il est très simple donc il ne devrait pas y avoir de problèmes à comprendre

#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); 
*/

}

Merci d'avance!

Était-ce utile?

La solution

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

accroché acturely la QueryInterface de IUnknown.

Après invoquer acheminera votre typecount

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

Autres conseils

Je pense que vous devriez recoder que ce soit portable entre 32 bits et 64 bits

Original:

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

Portable:

   // 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));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top