2016-09-08 10 views
2

私は、有効なexeファイルイメージを含むメモリバッファを持っていて、そこからいくつかのリソースを抽出したいと思います。
私はFindResource関数を使用していますが、この関数は、HMODULEを予期し、exeでメモリバッファを提供するとクラッシュします。

exeファイルをテンポラリファイルに書き込んだり、LoadLibraryを使って読み込んだり、必要な作業をしたりする代わりに、メモリバッファで動作させる方法はありますか?メモリバッファでのFindResourceの使用

+2

PEフォーマットを解析して、自分でリソースを見つけることができます。 –

+1

これは文書化されていないので、あなたはそれをしてはいけませんが、あなたのメモリブロックがDWORDに整列していれば、開始アドレスを取るだけで有効なリソースのみ 'HMODULE'を得ることができます。低ビットを1に設定します。 –

答えて

3

が有効なファイル画像形式で

が含まれているメモリバッファを持っていますか?私は生の(ディスクのように)よりも推測します。 FindResourceを使用するには、「イメージとしてマップされた」メモリが必要です。 (あなたが唯一のアクセスリソースをしたい場合が、メモリからそれを実行していない)ハード自己によってあなたの生の画像をマッピングしていないコードの例:有効なデータサイズのチェックを含む

PVOID MapImage(PIMAGE_DOS_HEADER pvRawData, ULONG cbRawData) 
{ 
    if (cbRawData < sizeof(IMAGE_DOS_HEADER)) 
    { 
     return 0; 
    } 

    if (pvRawData->e_magic != IMAGE_DOS_SIGNATURE) 
    { 
     return 0; 
    } 

    ULONG e_lfanew = pvRawData->e_lfanew, s = e_lfanew + sizeof(IMAGE_NT_HEADERS); 

    if (e_lfanew >= s || s > cbRawData) 
    { 
     return 0; 
    } 

    PIMAGE_NT_HEADERS pinth = (PIMAGE_NT_HEADERS)RtlOffsetToPointer(pvRawData, e_lfanew); 

    if (pinth->Signature != IMAGE_NT_SIGNATURE) 
    { 
     return 0; 
    } 

    ULONG SizeOfImage = pinth->OptionalHeader.SizeOfImage, SizeOfHeaders = pinth->OptionalHeader.SizeOfHeaders; 

    s = e_lfanew + SizeOfHeaders; 

    if (SizeOfHeaders > SizeOfImage || SizeOfHeaders >= s || s > cbRawData) 
    { 
     return 0; 
    } 

    s = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pinth->FileHeader.SizeOfOptionalHeader; 

    if (s > SizeOfHeaders) 
    { 
     return 0; 
    } 

    ULONG NumberOfSections = pinth->FileHeader.NumberOfSections; 

    PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)RtlOffsetToPointer(pinth, s); 

    ULONG Size; 

    if (NumberOfSections) 
    { 
     if (e_lfanew + s + NumberOfSections * sizeof(IMAGE_SECTION_HEADER) > SizeOfHeaders) 
     { 
      return 0; 
     } 

     do 
     { 
      if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData)) 
      { 
       union { 
        ULONG VirtualAddress, PointerToRawData; 
       }; 

       VirtualAddress = pish->VirtualAddress, s = VirtualAddress + Size; 

       if (VirtualAddress > s || s > SizeOfImage) 
       { 
        return 0; 
       } 

       PointerToRawData = pish->PointerToRawData, s = PointerToRawData + Size; 

       if (PointerToRawData > s || s > cbRawData) 
       { 
        return 0; 
       } 
      } 

     } while (pish++, --NumberOfSections); 
    } 

    PVOID ImageBase = VirtualAlloc(0, SizeOfImage, MEM_COMMIT, PAGE_READWRITE); 

    if (!ImageBase) 
    { 
     return 0; 
    } 

    memcpy(ImageBase, pvRawData, SizeOfHeaders); 

    if (NumberOfSections = pinth->FileHeader.NumberOfSections) 
    { 
     do 
     { 
      --pish; 

      if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData)) 
      { 
       memcpy(RtlOffsetToPointer(ImageBase, pish->VirtualAddress), 
        RtlOffsetToPointer(pvRawData, pish->PointerToRawData), Size); 
      } 

     } while (--NumberOfSections); 

    } 

    return ImageBase; 
} 

void Test(PVOID pvRawData, ULONG cbRawData, PCWSTR lpType, PCWSTR lpName) 
{ 
    if (HMODULE ImageBase = (HMODULE)MapImage((PIMAGE_DOS_HEADER)pvRawData, cbRawData)) 
    { 
     if (HRSRC hResInfo = FindResource(ImageBase, lpName, lpType)) 
     { 
      if (HGLOBAL hg = LoadResource(ImageBase, hResInfo)) 
      { 
       __nop(); 
      } 
     } 

     VirtualFree(ImageBase, 0, MEM_RELEASE); 
    } 
} 

MapImage。しかし(pvRawData、cbRawData)が100%正しいことをご確認してください場合 - あなたは、このチェックをスキップし、コード

//を簡素化することができ、私は@IInspectableコメントに基づいてTest機能を編集 - それはここ

を必要としない - 以外__try/__を削除
+1

なぜ 'Test'関数にSEHがありますか? Win32の例外を発生させるために呼び出される関数はすべて記述されていません。 – IInspectable

+0

@IInspectable - 画像のデータが不正確なため、 'FindResource'がアクセス違反を引き起こす可能性があります。しかし、正しいデータ(埋め込みリソースとしてイメージがありますが、ディスクやネットワークから読み取ることはできません)が正しいとすれば、__try/__以外はスキップできます。 MapImageでは地図の有効なサイズのみをチェックします。しかし、例えば 'pinth-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_RESOURCE] .VirtualAddress'が間違っていればどうなるでしょうか?例外は 'FindResource'で – RbMm

+0

@Inspectable - しかしあなたは正しいです - 私は' FindResource'内部処理例外をチェックするので、ブロックを除いて__try \ __を取り除くことができます – RbMm

0

あなたのオプション:LoadLibraryExと一時ファイルや負荷に保存

  1. PEファイルを解析し、リソースを自分で探します。
  2. さまざまなメモリモジュールライブラリの1つの方法でメモリからモジュールをロードするために必要なアクションを複製します。私は
関連する問題