3

我知道这似乎是一个过度回答的问题,但这个问题是不同的。我有这个导出一些方法的 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];

所以我可以假设我需要阅读DWORDatvptr + 0x1C字节和瞧。

如果我没记错的话,组件对象模型保证它将始终是放置在给定相同接口 ID的Func1ptr 。[vptr + 0x1C]永远。正确的?

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

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

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

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];
4

2 回答 2

1

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

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

于 2011-04-10T22:29:32.753 回答
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.

曾经也遇到过这个问题。然后我只需要创建一个函数,将输入值映射到指向对象的指针。也许您可以创建一个包装函数,在其中通过指向它的指针来调用该方法?

于 2011-04-10T16:29:24.017 回答