从 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;
或者您可以尝试在作业左侧使用非常难看的引用。
如果您获取地址的函数是 virtual
和 myClassInstance
指向派生类,或者涉及多重继承,则可能会出现其他复杂情况。
风险自负。
【讨论】:
以上是关于从 Dll 调用具有偏移地址的成员函数的主要内容,如果未能解决你的问题,请参考以下文章