C++ : Getting function virtual 'address' with member function pointer

一曲冷凌霜 提交于 2020-02-05 07:19:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!