在C ++中挂钩IDispatch v表

我试图修改系统中已经存在的IDispatch接口的行为。 要做到这一点,我的计划是在运行时入对象v表,并修改指针,使其指向自定义钩子方法。

如果我能得到这个工作,我可以添加新的方法和属性已经存在的对象。 尼斯。

首先,我尝试连接到IUnknown的v-table(从中inheritanceIDispatch)并且工作正常。 但是,尝试更改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; 

这突破了IUnknownQueryInterface

以下调用将路由到您的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));