gpt4 book ai didi

C++,如何找到成员函数的地址?

转载 作者:行者123 更新时间:2023-11-28 03:05:14 27 4
gpt4 key购买 nike

我有一个要解决的特定问题,我需要找到类方法的位置(在内存中)。我想我遇到了语法约束,因为指向方法的指针被处理为 member pointer示例:

class Foo {
public:
int targetFunction(int value) { return value + 5; }
};

DWORD findLocation() { // ignore the fact that DWORD might not equal pointer size.
int (Foo::*address)(int) = &(Foo::targetFunction); // member function pointer
void* typeHide = (void*)&address; // Remove type
DWORD targetAddress = *(DWORD*)typeHide; // Convert type from void* to DWORD* and dereference to DWORD
return targetAddress;
}

int (Foo::*address)(int) = 也可以写成 auto address =

现在,在 VS2008 中,它显示 Foo::targetFunction的地址是“0x000F B890”但是&Foo::targetFunction是“0x000F 1762

首先,成员指针使用成员指针运算符可以正常工作 .*->* .如果我将 targetAddress 转换回成员指针,它仍然有效!

其次,location可以是一个thunk函数!

最后,如果我使用 VS2008 的调试器从 member pointer 更改 targetFunction 的值的地址 1762 到 VS 调试器报告值 B890,我的代码工作正常!

是否有特定于 C++ 的方法来获取地址值 (B890) 而不是成员指针值 (1762)?


根据要求,这是我正在努力工作的代码:

BYTE overwriteStorage[300][2];

void NOP(void)
{
// hackish, but works for now.
}

void disableOlderVersions(DWORD _address, int index)
{
//...
_address = findLocation();

DWORD protectionStorage = 0;

VirtualProtect((void *)_address, 1+4, PAGE_WRITECOPY, &protectionStorage); // windows.h: Make Read/Write the location in code
{
BYTE *edit = (BYTE*)_address;
overwriteStorage[index][0] = *(edit+0); // store previous value to revert if needed
*(edit+0) = 0XE9; // JUMP (32-bit)

overwriteStorage[index][1] = *(edit+1); // store second value
signed int correctOffset = (signed int)NOP - (signed int)_address - 5; // calculate 0xE9 relative jump
*(signed int*)(edit+1) = correctOffset; // set jump target
}
VirtualProtect((void *)_address, 1+4, PAGE_EXECUTE, &protectionStorage);
}

如果我替换 findLocation 的第一行来自member pointer实际 function pointer它工作得很好。但是,我还需要读写几个类方法,这个方法被奇怪的 member pointer 破坏了。

另外,我也有一些本地函数也没有报告正确的地址(最近)。有没有可能有另一种方法来查找函数地址而不受编译器行为的约束?

最佳答案

听起来您正在尝试将成员函数 调用压缩为单个函数指针。这是不可能的。

记住:

Object x;
x.a(1);

实际上是

的缩写
a(&x /*this*/, 1 /*arg1, ... */); //approximation, leprechauns may be involved in actual implementations.

第一个参数很关键,它将变成“this”。

所以你不能这样做:

class Object {
public:
void f(int);
}

typedef void (*FNPTR)(int);
Object a;
void (Object::* memberFuncPtr)(int);
void* nerfedPtr = (void*)memberFuncPtrl
FNPTR funcPtr = static_cast<FNPTR>(nerfedPtr);
funcPtr(1);

因为你已经剥夺了它的对象上下文的成员函数。

没有函数地址和实例地址就无法调用对象成员函数。

关于C++,如何找到成员函数的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19887115/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com