Frage

Ich versuche, das Verhalten einer IDispatch-Schnittstelle bereits im System zu ändern. Diese mein Plan zu tun war, anstatt während der Laufzeit und ändern Sie die Zeiger so verweist er auf eine benutzerdefinierte Hook-Methode in die Objekte V-Tabelle einzuhaken.

Wenn ich diese Arbeit bekommen kann ich neue Methoden und Eigenschaften bereits vorhandene Objekte hinzufügen kann. Nizza.

Zuerst habe ich versucht, Einhaken in die V-Tabelle für IUnknown (von dem IDispatch erbt von) und das hat gut funktioniert. Allerdings versuchen, zu ändern entires in IDispatch nicht bei allen. Nichts geschieht überhaupt, der Code funktioniert genauso wie es ohne den Haken hat.

Hier ist der Code, es ist sehr einfach, so dass es keine Probleme geben soll, verstehen

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

}

Vielen Dank im Voraus!

War es hilfreich?

Lösung

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

Dieses süchtig acturely die QueryInterface von IUnknown.

Nach invoke Willen Route zu Ihrem typecount

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

Andere Tipps

Ich denke, man sollte diese zwischen 32 Bit und 64 Bit tragbar sein recodieren

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));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top