这个问题类似于 Print address of virtual member function
我想使用成员函数指针检索函数的内存位置(在运行时)。目标是记录它们,并使用WinDbg中的'ln'进行事后分析,以使用PDB符号检索它是什么函数。
我不能使用堆栈行走,因为我还没有进入我想要记录的功能。 (而且我不想修改数十亿个函数来返回我的地址......)。
简短样本:
class AClass
{
public :
virtual AFunction(){;}
};
typedef void (AClass::*FxPtr)( void );
[...]
AClass oAClass;
AClass* pSelf = &oAClass;
FxPtr pf = &AClass::AFunction;
DWORD nFctAddress = ???
任何人都知道如何检索地址?
&(pSelf->*pf)
给出错误C2298:'&' :对指向成员函数表达式'
的指针的非法操作我知道成员函数指针是'奇怪的'结构,但是因为我知道'this',有没有办法从vtable中查找潜在的虚函数?
此致
参考:
答案 0 :(得分: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) );
*/
};
它易于访问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可用于通过跟踪识别功能。
答案 1 :(得分:0)
全部在地图文件中。打开地图文件生成并享受。