自解压可执行C ++ [英] Self-Extracting Executable C++

查看:197
本文介绍了自解压可执行C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何自解压PE文件工作。可以有人解释为什么我的代码不工作,或修复main()部分。

I am trying to understand how self-extracting PE files work. Can somebody explain why my code isn't working, or fix the main() part.

#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文件,使用它提取它们。

I have 4 dll-files in resources, but I can't extract them using this. The resource ID´s should be correct, I checked it from resource header.

hInst 中的问题吗?还有什么可能是错的?我希望有人可以帮助我:)我只有一个月前开始学习C& C ++这样原谅我。

Is the problem in hInst or what else there could be wrong? I hope somebody could help me :) I have just a ~month ago started learning C & C++ so forgive me.

推荐答案

我没有看到代码的任何错误,除非你不检查函数的返回值,出错。还要注意,你可以用nullptr替换hInstance,它仍然可以工作。

I do not see anything wrong with your code other than you not checking the return values of functions and printing appropriate messages when something goes wrong. Also note that you can replace the hInstance with nullptr and it still works.

还要注意,如果你提取到一个需要额外权限的位置,你可能需要运行

Also note that if you are extracting to a location that requires extra permissions, you might have to run your program as administrator or add a manifest that forces it to ask for administrator privileges.

个人而言,我在任何资源应用程式中使用这些资料:

Personally, I use these in any of my resource applications:

    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应用程式,没有嵌入其中的资源。

Again, be very wary that you are using a CONSOLE application which may or may not have a resource embedded in it.

这篇关于自解压可执行C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆