问题
This question is similar to Print address of virtual member function
I would like to retrieve the memory location of a function (in runtime), using a member function pointer. The goal is to log them, and do a post-mortem analysis, using 'ln' in WinDbg to retrieve which function it was, using PDB symbols.
I can't use stack walking since I am not yet into the function I want to log. (and I do not want to modify billions of functions to return me their address...).
Short sample:
class AClass
{
public :
virtual AFunction(){;}
};
typedef void (AClass::*FxPtr)( void );
[...]
AClass oAClass;
AClass* pSelf = &oAClass;
FxPtr pf = &AClass::AFunction;
DWORD nFctAddress = ???
Anyone has an idea how I can retrieve the address ?
&(pSelf->*pf)
gives 'error C2298: '&' : illegal operation on pointer to member function expression'
I know that member function pointers are 'weird' structures, but since I know the 'this', is there a way to look-up the potentially virtual function from the vtable ?
Regards,
refs:
- Member Function Pointers
- Pointers to member functions are very strange animals
回答1:
#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) );
*/
};
Its easy to access vtable, but not so simple to identify the function by its address.
Some options:
1) Parse the .map file, load, and look up the class name by typeid (or by VMT instance from map), then function address by its name.
2) Write a static function calling a given virtual method for given object, see how it
looks in asm, and retrieve the function's offset in vtable from its code, then read the address
?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) There're nifty options like "/Gh enable _penter function call", which allow to retrieve
addresses of all functions, after the call though, but before the function actually does anything. Then .map can be used to identify the function by the trace.
回答2:
It's all in the map file. Turn on map file generation and enjoy.
来源:https://stackoverflow.com/questions/4998318/c-getting-function-virtual-address-with-member-function-pointer