Я пытаюсь понять, как работают самораспаковывающиеся PE-файлы. Может кто-нибудь объяснить, почему мой код не работает, или исправить часть main ().
#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-файла в ресурсах, но я не могу извлечь их, используя это. Идентификаторы ресурса должны быть правильными, я проверил это из заголовка ресурса.
Проблема в hInst
или что там еще может быть не так? Я надеюсь, что кто-то может мне помочь 🙂 Я только месяц назад начал изучать C & С ++ так что прости меня.
Я не вижу ничего плохого в вашем коде, кроме того, что вы не проверяете возвращаемые значения функций и не печатаете соответствующие сообщения, когда что-то идет не так. Также обратите внимание, что вы можете заменить 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));
}
Опять же, будьте очень осторожны, если вы используете приложение CONSOLE, которое может иметь или не иметь встроенный ресурс.
Других решений пока нет …