我知道这似乎是一个过分回答的问题,但这个问题有所不同。
我有这个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];
答案 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
。
也有这个问题。然后我只需创建一个将输入值映射到指向对象的指针的函数。也许你可以创建一个包装器函数,通过指向它来调用方法?