如何获取指向COM方法的指针以进行挂钩?

时间:2011-04-04 18:38:09

标签: c++ winapi assembly activex member-function-pointers

我知道这似乎是一个过分回答的问题,但这个问题有所不同。 我有这个ActiveX对象导出一些方法。我需要在其中一个方法上设置一个钩子,即Func1,我知道如何通过使用VirtualProtect()等来做到这一点。如果我打开ollydbg并深入研究ActiveX DLL,我会看到确切的地址我需要设置钩子的Func1

使用Visual Studio 2008,我使用预编译器指令:

#import "myactx.dll" no_namespace, named_guids, raw_interfaces_only

在我的代码中,我试图这样做:

LPVOID ptr = &IMyActx::Func1;

在编译时返回错误:

  

错误C2440:'初始化':无法从'HRESULT(__stdcall IMyActx :: *)(BSTR,BSTR)'转换为'LPVOID'。

我研究并发现由于隐含的 this 参数,我无法将指针类转换为指向函数的指针。

但是,我不打算调用此函数。我只是想知道它在内存中的地址,以便我可以将它传递给我的挂钩例程(它需要一个LPVOID指针)。

对我来说这似乎是不可思议的,我可以调用函数但不能在内存中获取其原始地址。它让我想插入一些x86汇编代码来获取我想要的指针。

非常感谢任何建议,感谢阅读。

...编辑 现在想一想...... LPVOID ptr = &IMyActx::Func1;不应该有效,因为IMyActx是一个纯粹的虚拟类!无论如何,我在实例化一个对象之前尝试了一些组合,并尝试将原始指针指向Func1但到目前为止没有任何工作。我在ollydbg中看到对Func1的调用生成为:

mov edx, [eax];
call dword ptr ds:[edx + 0x1C];

所以我可以假设我需要在DWORD个字节处读取vptr + 0x1C并发表意见。

如果我没记错的话,组件对象模型保证在给定相同接口ID的情况下,Func1 ptr始终位于[vptr + 0x1C]。永远。正确?

我可能会做一些像这样的事情,有些伪代码:

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

CoCreateInstance(CLSID_MyActx, 0, CLSCTX_ALL, IID_IMyActxObj, (LPVOID*) &pObj);

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];

2 个答案:

答案 0 :(得分:1)

COM对象的方法实际上是普通函数。这就是使用C语言而不是C ++编写COM客户端的原因。

我建议为C客户端生成头文件,然后可以轻松检索函数地址。但是,您首先需要一个您想要挂钩的类的实例。

答案 1 :(得分:0)

如果我理解正确,你想把一个类方法的指针强制转换为函数指针。

实际上这是不可能的。

简单示例:

class A {
    public:
    void func()
    {
        this->var = 0;
    }
    int var;
};

A myObj;
A::func* ptr2 = &(myObj::func); // works
void* ptr = &(myObj::func); // doesn't: what would "this" in line 5 point to?

您甚至无法使用reinterpret_cast

也有这个问题。然后我只需创建一个将输入值映射到指向对象的指针的函数。也许你可以创建一个包装器函数,通过指向它来调用方法?