#include <stdio.h>
struct Class {
virtual void AFunction( void ) { printf("1"); }
};
struct AClass : public Class {
virtual void AFunction( void ) { printf("2"); }
};
typedef void (AClass::*FxPtr)(void);
int main( void ) {
union {
FxPtr pf;
int rf[2];
};
pf = &AClass::AFunction;
printf( "sizeof(pf)=%i\n", sizeof(pf) );
printf( "%08X\n", pf );
printf( "%08X %08X\n", rf[0], rf[1] );
/*
error: ISO C++ forbids taking the address of a bound member function
to form a pointer to member function. Say '&AClass::AFunction'
AClass a;
FxPtr qf = &a.AFunction;
printf( "sizeof(qf)=%i\n", sizeof(qf) );
*/
};
Легко получить доступ к vtable, но не так просто определить функцию по ее адресу.
Некоторые варианты:
1) Разбор файла .map, загрузка и поиск имени класса по typeid (или по экземпляру VMT из карты), а затем адрес функции по его имени.
2) Напишите статическую функцию, вызывающую данный виртуальный метод для данного объекта, посмотрите, как
смотрит в asm и получает смещение функции в vtable из ее кода, затем читает адрес
?adr_CFunction@Class@@SIXPAU1@@Z PROC ; Class::adr_CFunction, COMDAT
; _This$ = ecx
; 8 : static void adr_CFunction( Class* This ) { This->CFunction(); }
mov eax, DWORD PTR [ecx]
mov edx, DWORD PTR [eax+8]
jmp edx
?adr_CFunction@Class@@SIXPAU1@@Z ENDP ; Class::adr_CFunction
3) Есть изящные опции, такие как "/ Gh enable _penter function call", которые позволяют получить
адреса всех функций, хотя после вызова, но до того, как функция действительно что-то делает. Затем .map можно использовать для идентификации функции по трассе.