简体   繁体   English

C ++:使用成员函数指针获取函数虚拟“地址”

[英]C++ : Getting function virtual 'address' with member function pointer

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. 目的是记录它们,并使用WinDbg中的'ln'进行事后分析,并使用PDB符号检索它的功能。

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' 给出“错误C2298:'&':对指向成员函数表达式的指针的非法操作”

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 ? 我知道成员函数指针是“怪异”的结构,但是由于我知道“ this”,有没有办法从vtable查找潜在的虚函数?

Regards, 问候,

refs: 参考:

#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. 它易于访问vtable,但通过其地址识别功能并不那么简单。
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. 1)解析.map文件,加载并按typeid(或按map中的VMT实例)查找类名,然后按名称查找函数地址。
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 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) 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. 3)有一些漂亮的选项,例如“ / Gh enable _penter function call”,它允许在调用之后但在函数实际执行任何操作之前检索所有函数的地址。 Then .map can be used to identify the function by the trace. 然后,可以使用.map通过跟踪来识别功能。

It's all in the map file. 全部都在地图文件中。 Turn on map file generation and enjoy. 打开地图文件生成并享受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM