Skip to content

Instantly share code, notes, and snippets.

@CoolOppo
Created July 21, 2014 04:34
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save CoolOppo/7c84f0897d0e7d3f9abe to your computer and use it in GitHub Desktop.
Save CoolOppo/7c84f0897d0e7d3f9abe to your computer and use it in GitHub Desktop.
How to Embed an exe Inside Another exe as a Resource and Then Launch It

How to Embed an exe Inside Another exe as a Resource and Then Launch It

While working on a utility project today, I stumbled upon wanting to embed an executable inside another executable. Sounds fun doesn’t it? And what is even more fun is to be able to launch the embedded exe!

Basically, here’s how it works. You embed Foo.exe inside Bar.exe. And by embed I mean, add Foo.exe as a resource in Bar.exe and then, from Bar.exe’s code, you can launch Foo.exe using CreateProcess().

So before answering the "Why?" lets answer the "How?"

Rename Foo.exe to Foo.txt. We do this just to be safe and to prevent the resource compiler (manager) from throwing unwanted errors. Now add Foo.txt as a normal resource in Bar.exe. Create an entry in Bar.exe’s resource script as below:

IDR_FOO     RCDATA   "Foo.txt"

And of course, you need to #define IDR_FOO in the resource header file. Just make sure it's a unique value.

The steps are:

  1. From within Bar.exe’s code, get a pointer to the first byte of Foo.txt

  2. You should know the size of Foo.txt in bytes.

  3. Using the pointer copy that many bytes into a separate file. ("\\Voila.exe")

  4. Call CreateProcess() on \\Voila.exe

Let’s dive into the code (from the entry point of Bar.exe):

HRSRC hrsrc = NULL;
HGLOBAL hGlbl = NULL;
BYTE * pExeResource = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD size = 7168;//hardcoding the size of the exe resource (in bytes)
hrsrc = FindResource(hInstance, (LPCWSTR)IDR_FOO, RT_RCDATA);

if (hrsrc == NULL)
{
	return FALSE;
}

hGlbl = LoadResource(hInstance, hrsrc);

if (hGlbl == NULL)
{
	return FALSE;
}

pExeResource = (BYTE*)LockResource(hGlbl);

if (pExeResource == NULL)
{
	return FALSE;
}

   
hFile = CreateFile(L"\\Voila.exe", GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile != INVALID_HANDLE_VALUE)
{
	DWORD bytesWritten = 0;
	WriteFile(hFile, pExeResource, size, &bytesWritten, NULL);
	         CloseHandle(hFile);
}

int ret = CreateProcess(L"\\Voila.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);

First, we find the resource using its resource identifier and then load it. Next we use LockResource() to get the pointer to the first byte of the resource data, which in this case would be the executable code. One downside, if you may say so, is that you need to know the exact size of the executable beforehand. Of course its easy to find out and I think its not a problem to hardcode because the size of the embedded executable won’t change, but if you still insist, you can use SizeOfResource().

Once you get the pointer, just copy all the bytes into another file, using WriteFile().

And finally do a CreateProcess() on the file you just created.

@Merith-TK
Copy link

So before answering the "Why?" lets answer the "How?"

You never answered the "why"...

@JaanDev
Copy link

JaanDev commented Nov 6, 2020

Can I delete my Foo.exe after that?
(I mean Foo.txt)

@darknessraider
Copy link

what is the resource script

@someniatko
Copy link

You never answered the "why"...

@Merith-TK In my case, I'd like to create a tool which embeds other tool to do the job, in order to not depend on user to install the other dependent tool.

@Merith-TK
Copy link

Talk about a necrobumo lol. I originally popped over here to look for info on some joke malware (bootstrap downloads timer, timer downloads payload, runs payload. Payload is just an dlgs error dialog that says error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment