Home > Blockchain >  How to embed an exe file into another exe file as a resource in C ?
How to embed an exe file into another exe file as a resource in C ?

Time:02-11

I am trying to use a pre-build .exe file as a resource in my C project, after searching I done the following steps:

Step1 Create a new C project and place the following code in the Source.cpp file

#include<iostream>
#include<Windows.h>
#include<fstream>
#define IDB_EMBEDEXE 52
using namespace std;
int main() {

    int count = 2;

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), __TEXT("BINARY"));
    HGLOBAL hGlobal = LoadResource(NULL, hResource);
    size_t exeSiz = SizeofResource(NULL, hResource);
    void* exeBuf = LockResource(hGlobal);

    ofstream outfile((char*)exeBuf, ios::out | ios::binary);
    if (!outfile)
        exit(9);
    outfile.write((char*)exeBuf, exeSiz);
    system((char*)exeBuf);

    return 0;
}

Step2 Create a new resource file (.rc)
1- Project>Add new item
2- From Installed>Visual C >Resource choose Resource File (.rc) let us name it Resource.rc

Step3 Edit the header file resource.h that has just created from Step2, add the following line to the header file:
#define IDB_EMBEDEXE 52

Step4 Edit the Resource.rc file by right click on it>Open with>Source Code (Text) Editor, add the following code just after the first #include statment (i.e. after #include "resource.h"

#define IDB_EMBEDEXE 52
IDB_EMBEDEXE    BINARY      "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"

After doing exactly these steps, I still get the following error in the cmd (not in the Visual Studio):

'MZ' is not recognized as an internal or external command, operable program or batch file.

And the program ends with code 0

I think calling system() what causes the problem, especially the argument I passed.

Note that the binary representation of the sum2num.exe file starts with MZ....

CodePudding user response:

If your #define is already in resource.h, there is no need to duplicate it in your source code. Just use #include "resource.h" in your code instead.

In any case, you should be using the pre-defined RCDATA resource type, instead of creating a custom BINARY type.

That being said, your use of ofstream and system() are both wrong. You are passing them the resource's raw binary data, but they are expecting a file path instead. You are using a file path in your .rc file to specify the file whose binary data is copied into the resource. The resource does not contain that file path, as you are clearly expecting.

Try this instead:

resource.h

...
#define IDB_EMBEDEXE 52
...

Resource.rc

#include "resource.h"
...
IDB_EMBEDEXE    RCDATA      "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"
...

Source.cpp

#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include "resource.h"
using namespace std;
        
int main() {

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), RT_RCDATA);
    if (!hResource)
        return 1;

    HGLOBAL hGlobal = LoadResource(NULL, hResource);
    if (!hGlobal)
        return 2;

    DWORD exeSiz = SizeofResource(NULL, hResource);
    if (!exeSiz)
        return 3;

    void* exeBuf = LockResource(hGlobal);
    if (!exeBuf)
        return 4;

    char tempPath[MAX_PATH] = {};
    if (!GetTempPathA(MAX_PATH, path))
        return 5;

    string fullPath = string(tempPath)   "sum2num.exe";

    ofstream outfile(fullPath.c_str(), ios::binary);
    if (!outfile.is_open())
        return 6;

    int res = (outfile.write((char*)exeBuf, exeSiz)) ? 0 : 7;
    outfile.close();

    if (res == 0) {
        system(fullPath.c_str());
    }

    remove(fullPath.c_str());

    return res;
}
  • Related