Visual Studio — C ++, как мне найти адрес функции-члена?

У меня есть конкретная проблема, которую я пытаюсь решить, мне нужно найти местоположение (в памяти) метода класса. Я думаю, что я столкнулся с синтаксическим ограничением, потому что указатель на метод обрабатывается как 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 обратно к указателю на член, он все равно будет работать!

Во-вторых, местоположение Можно будь громогласным!

Наконец, если я использую отладчик VS2008, чтобы изменить значение targetFunction с member pointerадрес 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 pointers.

Кроме того, у меня были некоторые локальные функции, которые не сообщают правильный адрес (недавно). Есть ли другой способ найти адреса функций, не ограничиваясь поведением компилятора?

0

Решение

Похоже, вы пытаетесь сжать член-функция вызов в один указатель на функцию. Это невозможно.

Помните:

Object x;
x.a(1);

на самом деле коротка для

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

Этот первый аргумент имеет решающее значение, он станет «этим».

Таким образом, вы не можете сделать что-то вроде этого:

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);

Потому что вы ограбили функцию-член в ее объектном контексте.

Невозможно вызвать функцию-член объекта, не имея как адрес функции, так и адрес экземпляра.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]