Virtual Table is one of the most fascinating stuff for C++ programmer. Well, did you ever peek into virtual table, which is the real engine of virtual functions?


The first 4 bytes of an objects points to another pointer which points to virtual table. Casting it to DWORD*, we can parse all virtual functions. Once you get function address, you can get the function name by calling – SymFromAddr(). Have a look at code snippet.

#include <ImageHlp.h>
...
// Get list of virtual functions.
void CRabbitDlg::ParseVtable()
{
// Initialize symbols.
InitializeSymbols();
// We are going to parse vtable of CWinApp object.
DWORD* pBase = (DWORD*)(AfxGetApp());
DWORD* pVptr = (DWORD*)*pBase;
// Iterate through VirtualTable.
DWORD Index = 0;
DWORD FnAddr = pVptr[Index];
while( FnAddr )
{
// Translate FunctionAddress to FunctionName.
CString FunctionName;
GetSymbolNameFromAddr( FnAddr, FunctionName );
// Format and add to list.
CString Final;
Final.Format( _T("%0x - %s"), FnAddr, FunctionName.operator LPCTSTR());
m_List.AddString( Final );
// Next function pointer.
FnAddr = pVptr[++Index];
}
}
// Initialize Symbol engine.
void CRabbitDlg::InitializeSymbols()
{
DWORD Options = SymGetOptions();
Options |= SYMOPT_DEBUG;
Options |= SYMOPT_UNDNAME;
::SymSetOptions( Options );
// Initialize symbols.
::SymInitialize ( GetCurrentProcess(),
NULL,
TRUE );
}
// Get symbol name from address.
void CRabbitDlg::GetSymbolNameFromAddr( DWORD SymbolAddress, CString& csSymbolName )
{
DWORD64 Displacement = 0;
SYMBOL_INFO_PACKAGE SymbolInfo = {0};
SymbolInfo.si.SizeOfStruct = sizeof( SYMBOL_INFO );
SymbolInfo.si.MaxNameLen = sizeof(SymbolInfo.name);
// Get symbol from address.
::SymFromAddr( GetCurrentProcess(),
SymbolAddress,
&Displacement,
&SymbolInfo.si );
csSymbolName = SymbolInfo.si.Name;
}

Don’t forget to include ImageHlp.lib to project settings.

Targeted Audiance – Intermediate.