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

发布于 2024-10-30 01:22:10 字数 1489 浏览 1 评论 0原文

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

因此我可以假设我需要读取 vptr + 0x1C 字节处的 DWORD ,并且瞧。

如果我没记错的话,组件对象模型保证它始终是位于 [vptr + 0x1C] 且具有相同接口 ID 的 Func1 ptr。永远。正确的?

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

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

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

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];

I know this seems like a over-answered question but this one is different.
I have this ActiveX object which exports some methods. I need to set a hook on one of its methods, namely Func1, I know how to do this by using VirtualProtect(), etc. If I open ollydbg and dig into the ActiveX DLL I see exactly the address of the Func1 where I need to set the hook.

Using Visual Studio 2008, I am using the precompiler directive:

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

And in my code I am trying to do this:

LPVOID ptr = &IMyActx::Func1;

which returns an error when compiling:

error C2440: 'initializing' : cannot convert from 'HRESULT (__stdcall IMyActx::* )(BSTR,BSTR)' to 'LPVOID'.

I researched and found that I can't cast a pointer-to-class-method to a pointer-to-function because of the implicit this param.

However, I don't intend to call this function. I just want to know its address in memory so that I can pass it to my hooking routine (which expects a LPVOID pointer).

This seems inconceivable to me that I can call a function but not get its raw address in memory. It makes me want to insert some x86 assembly code just to get the pointer I want.

Any suggestion is greatly appreciated, thanks for reading.

EDIT...
Now thinking of it... LPVOID ptr = &IMyActx::Func1; should not work because IMyActx is a pure virtual class! Anyway I tried some combinations before of instantiating an object and trying to get the raw pointer to Func1 but nothing worked so far. I see in ollydbg that a call to Func1 is generated as:

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

So I can assume I need to read the DWORD at vptr + 0x1C bytes and voilá.

If I recall correctly, the Component Object Model guarantees that it will always be the Func1 ptr laying at [vptr + 0x1C] given the same Interface ID. forever. Right?

I will probably do something like this, in somewhat pseudo-code:

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

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

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡忘如思 2024-11-06 01:22:10

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

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

Methods of COM objects actually are ordinary functions. That's what enables COM clients written in C instead of C++.

I recommend generating the header file for a C client, the function address will then be easily retrieved. You do first need an instance of the class you intend to hook, however.

奢望 2024-11-06 01:22:10

如果我理解正确的话,您想将指向类方法的指针转换为函数指针。

这实际上是不可能的。

简单的例子:

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

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

If I understand you correctly, you want to cast a pointer to a class method into a function pointer.

This actually is not possible.

Simple example:

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?

You cannot even use reinterpret_cast.

Had this problem once, too. Then I simply had to create a function that maps the input value to a pointer to the object. Maybe you could create a wrapper function in which you call the method by having a pointer to it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文