Skip to content

COFF形式ファイルのいろいろ

hangedman edited this page Dec 15, 2016 · 29 revisions

資料

Microsoft PE形式ファイルおよびCOFF形式ファイルの仕様書

Locreate:再配置のアナグラム

アレ用の何か

20161215022206

考察

上の図で言うところの _printf というシンボルと同様の再配置情報を計算したい

疑似コードから逆算

  • アレ用の何か から ObjFile.cpp
//! 再配置情報を考慮してセクションデータが等しいか調べる。
bool ObjFile::IsEqualSection(
  int           i_section_index,
  const BYTE*   i_data,
  int           i_size
) const
{
  bool                          retval           = false;
  const IMAGE_SECTION_HEADER*   section_header_p = NULL;
  const BYTE*                   section_data_p   = NULL;
  const IMAGE_RELOCATION*       relocations      = NULL;
  int                           reloc_count      = 0;
  size_t                        cmp_index        = 0;
  size_t                        cmp_size         = 0;
  
  do
  {
    // セクションヘッダへのポインタを取得。
    section_header_p = GetSectionHeaderP(i_section_index);
    // セクションデータへのポインタを取得。
    section_data_p = GetSectionDataP(i_section_index);
    if( section_header_p == NULL || section_data_p == NULL )
    {
      _RPTF1(_CRT_WARN,
             "* ERROR * : セクションインデックス %d は有効ではありません。\n",
             i_section_index
            );
      break;
    }
    
    // 再配置情報を取得。
    reloc_count = GetRelocationCount(i_section_index);
    relocations = GetRelocations(i_section_index);
    if( reloc_count && relocations == NULL )
    {
      _RPTF0(_CRT_WARN, "再配置情報が壊れています。\n");
      break;
    }
    
    // 再配置情報がある場合は最初の再配置情報のオフセットまで比較。
    // ない場合は引数の i_size 分比較。
    cmp_size = reloc_count ? relocations[0].VirtualAddress : i_size;
    if( memcmp(i_data, section_data_p, cmp_size) == 0 )  // 最初のブロックが等しい
    {
      retval = true;
      // 全てのブロックが等しいか調べる。
      for(int i = 1; i <= reloc_count; i++)
      {
        cmp_index = relocations[i - 1].VirtualAddress + sizeof(DWORD);
        if( i == reloc_count )
        {
          cmp_size = section_header_p->SizeOfRawData
                   - (relocations[i - 1].VirtualAddress +  sizeof(DWORD))
                   ;
        }
        else
        {
          cmp_size = relocations[i].VirtualAddress
                   - (relocations[i - 1].VirtualAddress +  sizeof(DWORD))
                   ;
        }
        
        if( cmp_size
        &&  memcmp(i_data + cmp_index, section_data_p + cmp_index, cmp_size) != 0 )
        {
          retval = false;
          break;
        }
      }
    }
  }
  while( 0 );
  
  return retval;
}
Clone this wiki locally