Scan Virtual Table for Abnormalities

December 11th, 2009 s0beit Leave a comment Go to comments

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.

  1. struct FCodeSize
  2. {
  3.  int  Begin;
  4.  int  End;
  5. };
  6.  
  7. FCodeSize GetModuleCodeSectionInfo( HMODULE hmModule )
  8. {
  9.  FCodeSize codeReturn;
  10.  
  11.  memset( &codeReturn, 0, sizeof( FCodeSize ) );
  12.  
  13.  unsigned long moduleLong = reinterpret_cast<unsigned long>( hmModule );
  14.  
  15.  IMAGE_DOS_HEADER *pDos = static_cast<IMAGE_DOS_HEADER *>((LPVOID)hmModule);
  16.  
  17.  if( !pDos )
  18.   return codeReturn;
  19.  
  20.  if( pDos->e_magic != IMAGE_DOS_SIGNATURE )
  21.   return codeReturn;
  22.  
  23.  IMAGE_NT_HEADERS *pNTHead = reinterpret_cast<IMAGE_NT_HEADERS *>( moduleLong + pDos->e_lfanew);
  24.  
  25.  if( !pNTHead )
  26.   return codeReturn;
  27.  
  28.  if( pNTHead->Signature != IMAGE_NT_SIGNATURE )
  29.   return codeReturn;
  30.  
  31.  IMAGE_OPTIONAL_HEADER *pOptionalHead = reinterpret_cast<IMAGE_OPTIONAL_HEADER *>( &pNTHead->OptionalHeader );
  32.  
  33.  if( !pOptionalHead )
  34.   return codeReturn;
  35.  
  36.  codeReturn.Begin  = (moduleLong + pOptionalHead->BaseOfCode);
  37.  codeReturn.End  = (codeReturn.Begin + pOptionalHead->SizeOfCode);
  38.  
  39.  return codeReturn;
  40. }
  41.  
  42. bool CheckTableReferences( HMODULE hModule, void *pTable, int SizeOfTable )
  43. {
  44.  FCodeSize moduleCodeSize = GetModuleCodeSectionInfo( hModule );
  45.  
  46.  if( !moduleCodeSize.Begin || !moduleCodeSize.End )
  47.   return true; //error, return true to avoid false-positives
  48.  
  49.  unsigned long *Table = (unsigned long *)pTable;
  50.  
  51.  if( !Table || !*Table )
  52.   return true; //error, return true to avoid false-positives
  53.  
  54.  unsigned long *Internal = (unsigned long *)*Table;
  55.  
  56.  for( int i = 0; i < SizeOfTable; i++ )
  57.  {
  58.   unsigned long TableFunctionAddress = static_cast<unsigned long>( Internal[ i ] );
  59.  
  60.   if( !TableFunctionAddress )
  61.    continue;
  62.  
  63.   if( TableFunctionAddress >= moduleCodeSize.Begin && TableFunctionAddress <= moduleCodeSize.End )
  64.   {
  65.    //success
  66.    continue;
  67.   }
  68.   else
  69.   {
  70.    //failure, outside of range
  71.    return false;
  72.   }
  73.  }
  74.  
  75.  return true;
  76. }
  1. No comments yet.
  1. No trackbacks yet.
You must be logged in to post a comment.