This is a simple function i wrote to make sure that no functions in your virtual table are outside the .code section of the module you specify.
-
struct FCodeSize
-
{
-
int Begin;
-
int End;
-
};
-
-
FCodeSize GetModuleCodeSectionInfo( HMODULE hmModule )
-
{
-
FCodeSize codeReturn;
-
-
memset( &codeReturn, 0, sizeof( FCodeSize ) );
-
-
unsigned long moduleLong = reinterpret_cast<unsigned long>( hmModule );
-
-
IMAGE_DOS_HEADER *pDos = static_cast<IMAGE_DOS_HEADER *>((LPVOID)hmModule);
-
-
if( !pDos )
-
return codeReturn;
-
-
if( pDos->e_magic != IMAGE_DOS_SIGNATURE )
-
return codeReturn;
-
-
IMAGE_NT_HEADERS *pNTHead = reinterpret_cast<IMAGE_NT_HEADERS *>( moduleLong + pDos->e_lfanew);
-
-
if( !pNTHead )
-
return codeReturn;
-
-
if( pNTHead->Signature != IMAGE_NT_SIGNATURE )
-
return codeReturn;
-
-
IMAGE_OPTIONAL_HEADER *pOptionalHead = reinterpret_cast<IMAGE_OPTIONAL_HEADER *>( &pNTHead->OptionalHeader );
-
-
if( !pOptionalHead )
-
return codeReturn;
-
-
codeReturn.Begin = (moduleLong + pOptionalHead->BaseOfCode);
-
codeReturn.End = (codeReturn.Begin + pOptionalHead->SizeOfCode);
-
-
return codeReturn;
-
}
-
-
bool CheckTableReferences( HMODULE hModule, void *pTable, int SizeOfTable )
-
{
-
FCodeSize moduleCodeSize = GetModuleCodeSectionInfo( hModule );
-
-
if( !moduleCodeSize.Begin || !moduleCodeSize.End )
-
return true; //error, return true to avoid false-positives
-
-
unsigned long *Table = (unsigned long *)pTable;
-
-
if( !Table || !*Table )
-
return true; //error, return true to avoid false-positives
-
-
unsigned long *Internal = (unsigned long *)*Table;
-
-
for( int i = 0; i < SizeOfTable; i++ )
-
{
-
unsigned long TableFunctionAddress = static_cast<unsigned long>( Internal[ i ] );
-
-
if( !TableFunctionAddress )
-
continue;
-
-
if( TableFunctionAddress >= moduleCodeSize.Begin && TableFunctionAddress <= moduleCodeSize.End )
-
{
-
//success
-
continue;
-
}
-
else
-
{
-
//failure, outside of range
-
return false;
-
}
-
}
-
-
return true;
-
}