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 its 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"
5) And voila!
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, then you can read it from the registry or a file or something.
Once you get the pointer, just copy all the bytes into another file, using WriteFile() API.
And finally do a CreateProcess() on the file you just created.
If you happen to know any alternate ways of doing this, please leave a message.
And coming to the important question of "
Why would any sane person want to embed an exe within an exe?" Well, you will have to wait till the
next post to find out (;
Aloha!
Update:
I have changed the code above to copy all the 7168 bytes into "Voila.exe" in one go, instead of copying byte after byte. And just to be clear this is not a production code, it is just to demonstrate what can be done. Of course, creating the file "Voila.exe" in the root folder is not ideal and it may fail on many devices, and you also need to clean up by deleting the exe file, which can be done using the
DeleteFile() API. Ideally, "voila.exe" should be created not in the root folder but instead using
SHGetSpecialFolderPath() API passing for e.g.
CSIDL_APPDATA. I left out all these details because I thought they were trivial for this post.