2013-09-21 6 views
4

자동 압축 풀기 PE 파일의 작동 방식을 이해하려고합니다. 누군가 내 코드가 작동하지 않는 이유를 설명하거나 main() 부분을 고칠 수 있습니까?자동 압축 풀림 실행 파일 C++

#include <iostream> 
#include <Windows.h> 

using namespace std; 

void ExtractResource(const HINSTANCE hInstance, WORD resourceID, const char* outputFilename); 

int main() 
{ 
    HINSTANCE hInst = GetModuleHandle (0); 
    ExtractResource(hInst, 101, "101.dll"); 
    ExtractResource(hInst, 102, "102.dll"); 
    ExtractResource(hInst, 103, "103.dll"); 
    ExtractResource(hInst, 104, "104.dll"); 
    cout << "Files are now extracted!"; 
    Sleep(INFINITE); 
} 


void ExtractResource(const HINSTANCE hInstance, WORD resourceID, const char* outputFilename){ 

     // First find and load the required resource   

     HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(resourceID), "BINARY"); 

     if(hResource==NULL) 

       return; 

     HGLOBAL hFileResource = LoadResource(hInstance, hResource); 



     // Now open and map this to a disk file   

     LPVOID lpFile = LockResource(hFileResource);   

     DWORD dwSize = SizeofResource(hInstance, hResource);    



     // Open the file and filemap   

     HANDLE hFile = CreateFileA(outputFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 

       FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY, NULL);   

     HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);    

     LPVOID lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);    



     // Write the file 

     CopyMemory(lpBaseAddress, lpFile, dwSize);    



     // Unmap the file and close the handles 

     UnmapViewOfFile(lpBaseAddress); 

     CloseHandle(hFilemap); 

     CloseHandle(hFile); 

} 

리소스에 4 개의 dll 파일이 있지만이 파일을 사용하여 추출 할 수 없습니다. 리소스 ID가 정확해야하며 리소스 헤더에서 확인했습니다.

hInst에 문제가 있습니까? 아니면 그 밖의 무엇이 잘못되었을 수 있습니까? 나는 누군가가 나를 도울 수 있기를 바란다. 나는 ~12 개월 전 CC++을 배우기 시작했다. 그래서 나를 용서해 준다.

+0

"할 수 없음"을 정의하십시오. 정확히 어떤 API 호출이 정확히 어떤 오류로 실패합니까? 디버거를 사용하여 찾으십시오. –

+0

괜찮 았지만 리소스를 추출하지 않습니다. VS2012를 사용하고 있습니다. – user2404495

+0

그래서 프로그램을 디버깅하여 디버깅하십시오. –

답변

2

뭔가 잘못되었을 때 함수의 반환 값을 확인하고 적절한 메시지를 출력하지 않는 것 외에는 코드에 아무런 이상이 없습니다. 또한 hInstance를 nullptr로 대체 할 수 있으며 여전히 작동한다는 점에 유의하십시오.

추가 권한이 필요한 위치로 추출하는 경우 관리자 권한으로 프로그램을 실행하거나 관리자 권한을 요청하도록하는 매니페스트를 추가해야 할 수도 있습니다.

bool ExtractResource(std::uint16_t ResourceID, std::string OutputFileName, const char* ResType) 
    { 
     try 
     { 
      HRSRC hResource = FindResource(nullptr, MAKEINTRESOURCE(ResourceID), ResType); 
      if (hResource == nullptr) 
      { 
       return false; 
      } 

      HGLOBAL hFileResource = LoadResource(nullptr, hResource); 
      if (hFileResource == nullptr) 
      { 
       return false; 
      } 

      void* lpFile = LockResource(hFileResource); 
      if (lpFile == nullptr) 
      { 
       return false; 
      } 

      std::uint32_t dwSize = SizeofResource(nullptr, hResource); 
      if (dwSize == 0) 
      { 
       return false; 
      } 

      HANDLE hFile = CreateFile(OutputFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 
      HANDLE hFilemap = CreateFileMapping(hFile, nullptr, PAGE_READWRITE, 0, dwSize, nullptr); 
      if (hFilemap == nullptr) 
      { 
       return false; 
      } 

      void* lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0); 
      CopyMemory(lpBaseAddress, lpFile, dwSize); 
      UnmapViewOfFile(lpBaseAddress); 
      CloseHandle(hFilemap); 
      CloseHandle(hFile); 

      return true; 
     } 
     catch (...) {} 
     return false; 
    } 

하여 Main.cpp :

#include "Resource.h" 

bool Extract(HWND WindowHandle) //WindowHandle for MessageBox parent. 
{ 
    return ExtractResource(101,"101.dll", "BINARY"); 
} 

int main() 
{ 
    std::cout<<"Extracted Successfully: "<<std::boolalpha<<Extract(GetModuleHandle(0)); 
} 

다시 말하지만, 당신이 할 수있는 콘솔 응용 프로그램을 사용하는 수도 있고 것을 매우 조심해야

는 개인적으로, 나는 내 자원의 모든 응용 프로그램에 이들을 사용 리소스가 포함되어 있지 않습니다.

+0

에서 IDE에서 프로그램을 실행할 때 작업 디렉토리를 설정할 수 있습니다. 그저 초보자 일뿐입니다. :) _simple_ 방법으로 코드를 만들 수 있습니까? OP에 게시 된? 프로젝트는 현재 리소스에있는 파일들과 단지 main.cpp 파일만을 가지고 있습니다. 거기에 뭔가가 필요합니까? 그리고 관리자 권한이 필요한 장소에서 파일을 추출하지 않고 데스크톱에서만 실행하려고했지만 아무 일도 일어나지 않습니다. 누군가 내게 배워야 할 곳이 어디에 있는지, 원본 코드를 고칠 수 있다면 큰 도움이 될 것입니다. 또한 그 nullptr 것을 언급 해 주셔서 감사합니다, 그것에 대해 몰랐습니다. – user2404495

+0

어 .. 1 초. 나는 내가 가지고있는 것을 시도하고 단순화 할 것이다. 당신과 거의 같아야합니다 : l – Brandon

+0

리소스를 허용하거나 허용하지 않는 콘솔 어플리케이션을 사용하고있는 것처럼 보이기 때문에 단순화하면 작동하지 않을 수도 있습니다.보통 우리가 자원에 대해 말할 때 우리는 콘솔이 아닌 GUI 프로그램을 언급합니다. 그러나 프로그램에 이미 포함 된 리소스가 있다고 가정하므로이 가정을 기반으로 대답을 간소화합니다. – Brandon

관련 문제