从 Dll 调用具有偏移地址的成员函数

Posted

技术标签:

【中文标题】从 Dll 调用具有偏移地址的成员函数【英文标题】:Call a member function with offset address from Dll 【发布时间】:2019-10-18 09:08:41 【问题描述】:

我在 dll 中有未导出的成员函数。 我正在尝试使用之前提取的 base + offset 地址调用此函数。 我在从类实例进行实际调用时遇到问题。

我能够从 dll 中获取模块的基址和函数的偏移量。 我调用该函数时出错,因为它不是我班级的成员。

HMODULE hDll = GetModuleHandleA("myModule.dll");

void *(funcPtr)() = (void(*)())((char *)&hDll + 0x101E07); //this is the non exported function address
myClassInstance->funcPtr();

我收到一个错误:

'funcPtr' is not a member of 'MyClass'

如何从myClassInstance 拨打funcPtr

【问题讨论】:

这不是明智的代码,您只需使用funcPtr() 来调用该函数。如果您希望变量成为该类的成员,则以这种方式声明它,而不是使用局部变量。请注意此代码is very unreliable. 所以只能这样调用静态函数?我无法将 funcPtr 添加到 MyClass。这是一个没有导出函数的给定类。 【参考方案1】:

这不是一件简单的事情。首先,您需要将您的指针声明为成员函数指针:

void (MYCLASS::*funcPtr)();

你会调用它通过

(myClassInstance->*funcPtr)();

然后你需要一些方法来存储一个值。您不能将char *(或void *)指针转换为成员函数指针。您必须使用某种形式的双关语。

典型的方式是使用memcpy

void *addr = (char *)&hDll + 0x101E07;
memcpy(&funcPtr, &addr, sizeof(void *));

另一种可能性,因为从 DLL 获取成员函数的地址已经超出了未定义行为的范围,可能是使用联合:

union MemFuncPtr 
    void *addr;
    void (MYCLASS::*memfun)();
    // Can be expanded to include other member function pointer types if necessary
;

那么你就可以了

MemFuncPtr mfp;
mfp.addr = (char *)&hDll + 0x101E07;
funcPtr = mfp.memfun;

或者您可以尝试在作业左侧使用非常难看的引用。

如果您获取地址的函数是 virtualmyClassInstance 指向派生类,或者涉及多重继承,则可能会出现其他复杂情况。

风险自负。

【讨论】:

以上是关于从 Dll 调用具有偏移地址的成员函数的主要内容,如果未能解决你的问题,请参考以下文章

未导出成员函数时,从 C# 调用 C++ 本机/非托管成员函数

DLL导出类静态成员函数问题

我有一个具有偏移参数并想要循环的函数

从 DLL 访问类成员(不是 LIB !!!)

从指向对象的指针调用成员函数指针时调用错误的函数

结构体变量字节填充