2013-09-21 86 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或問題還有什麼有可能是錯的?我希望有人能幫助我:)我只是一個月前開始學習C & C++所以原諒我。

+0

定義「不能」。究竟哪個API調用失敗,確切地說是哪個錯誤?使用調試器來查明。 –

+0

它建立良好,但它不提取資源。我正在使用VS2012。 – user2404495

+0

所以,調試你的程序找出原因。 –

回答

2

我看不出什麼毛病比你不檢查函數的返回值,並打印相應的消息時出錯等你的代碼。另外請注意,您可以用nullptr替換hInstance,它仍然有效。

另外請注意,如果你解壓到需要額外權限的位置,你可能要運行程序作爲管理員或補充,迫使它要求管理員權限的清單。

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

這似乎對我來說相當複雜,就像我說的只是個初學者:)有沒有做的工作,我的代碼任何_simple_方式張貼在OP?該項目目前只有資源中的文件,只有main.cpp文件。我需要別的東西嗎?不,我不是在任何需要管理員權限的地方解壓文件,只是試圖在桌面上運行它,但沒有任何反應。如果有人能幫我學習,修復原始代碼,我會非常感激。還要感謝提及那個nullptr的東西,不知道那個。 – user2404495

+0

呃..一秒。我會盡量簡化我的工作。它應該與您的幾乎相同:l – Brandon

+0

另請注意,如果我簡化它,則可能無法正常工作,因爲您似乎在使用可能允許或可能不允許資源的控制檯應用程序。通常當我們談到資源時,我們指的是GUI程序而不是控制檯。但是,我會假設你已經將資源嵌入到了你的程序中,所以我會根據這個假設簡化答案。 – Brandon