2016-09-08 3 views
2

유효한 exe 파일 이미지가 포함 된 메모리 버퍼가 있는데 거기에서 일부 리소스를 추출하고 싶습니다.
나는 FindResource 함수를 사용하고 있지만이 함수는 HMODULE을 필요로하며 exe와 함께 메모리 버퍼가 제공되면 충돌합니다.

임시 파일에 exe를 쓰는 대신 메모리 버퍼로 작업하게 만드는 방법이 있습니까? LoadLibrary을 사용하여로드 한 다음 필요한 작업을 수행하고 있습니까?메모리 버퍼에 FindResource 사용

+2

PE 형식을 구문 분석하고 리소스를 직접 찾을 수 있습니다. –

+1

이제 이것은 문서화되지 않았으므로 그렇게하지 말아야합니다.하지만 메모리 블록이 DWORD로 정렬되어 있다면 (시작해야 함) 시작 주소를 취하는 것만으로 유효한 리소스 전용 'HMODULE'을 얻을 수 있어야합니다. 낮은 비트를 1로 설정합니다. –

답변

3

가 유효한 파일 이미지 형태로

이 들어있는 메모리 버퍼를 가지고? 나는 원시 디스크에서와 같다고 생각한다. FindResource를 사용하려면 '이미지로 매핑 된'메모리가 필요합니다. 하지 열심히지도 당신이 (당신이 전용 액세스 리소스를 원하지만, 메모리에서 실행하지 않을 경우 ) 코드의 예를 자동으로 RAW 이미지 : 유효한 데이터 크기에 대한 검사를 포함

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 % 정확하다 - 제거 __try/__을 제외하고 - - 그것은 여기에 필요하지

당신이 코드

// 내가 @IInspectable 의견에 따라 Test 기능 편집이 검사를 생략하고 단순화 할 수 있습니다

+1

왜 '테스트'기능에 SEH가 있습니까? Win32 예외를 발생시키기 위해 호출 된 함수는 문서화되어 있지 않습니다. – IInspectable

+0

@IInspectable - 이미지의 데이터가 부정확하기 때문에'FindResource'가 접근 위반을 일으킬 수 있습니다. 그러나 우리가 올바른 데이터 (우리는 임베디드 리소스로 이미지를 가지고 있지만 디스크 나 네트워크에서 이미지를 읽을 수 없다)가 확실하다면 - __try/__ except를 건너 뛸 수 있습니다. MapImage에서는 유효한지도 크기 만 확인합니다. 예를 들어,'pinth-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_RESOURCE] .VirtualAddress'가 올바르지 않은 경우는 무엇입니까? 예외 'FindResource' – RbMm

+0

@llnspectable -하지만 당신은 맞습니다 - 이제는'FindResource' 내부 처리 예외를 검사합니다. 그래서 블록을 제외하고 __try \ __을 제거 할 수 있습니다 – RbMm

0

귀하의 옵션 : LoadLibraryEx와 임시 파일 및 부하에 저장

  1. .
  2. PE 파일을 구문 분석하고 리소스를 직접 찾으십시오.
  3. 다양한 메모리 모듈 라이브러리 중 하나와 같은 방식으로 메모리에서 모듈을로드하는 데 필요한 작업을 복제하십시오. 난
관련 문제