首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++中的钩子IDispatch v表

C++中的钩子IDispatch v表
EN

Stack Overflow用户
提问于 2010-01-03 00:48:30
回答 2查看 1.8K关注 0票数 3

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

如果我能让它工作,我就可以给已经存在的对象添加新的方法和属性。好的。

首先,我尝试连接到IUnknown ( IDispatch继承自它)的v-table,这很好用。但是,尝试更改IDispatch中的条目根本不起作用。什么都不会发生,代码就像没有钩子一样工作。

这是代码,它非常简单,所以理解起来不会有任何问题

代码语言:javascript
复制
#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); 
*/

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-01-03 01:22:45

代码语言:javascript
复制
// Get pointer of first emtry in IDispatch vtable (GetTypeInfoCount)
unsigned int* v1 = (unsigned int*)iunknown_vtable;

这实际上钩住了IUnknownQueryInterface

下面的调用将路由到您的typecount

代码语言:javascript
复制
//obj->GetTypeInfoCount(&num);
LPVOID dummy;
obj->QueryInterface(IID_NULL, &dummy);
票数 3
EN

Stack Overflow用户

发布于 2010-04-01 05:09:35

我认为你应该重新编码成32位和64位之间的可移植性。

原件:

代码语言:javascript
复制
   // There are three entries in IUnknown, therefore add 12 to go to IDispatch
    void* idispatch_vtable = (void*)(((unsigned int)iunknown_vtable)+12);

便携:

代码语言:javascript
复制
   // 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));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1992092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档