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

Call a member function with offset address from Dll

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

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

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

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

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;

或者您可以尝试在作业左侧进行非常丑陋的引用转换。

如果您获取地址的函数是 virtual 并且 myClassInstance 指向派生的 class,或者如果涉及多重继承,则可能会出现额外的复杂情况。

自行承担风险。