Prabhu Kumar

a tech twaddler..
posts - 125, comments - 97, trackbacks - 0

My Links

News

Archives

Post Categories

Blogs I follow

CSS Templates

Twitter

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 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. (Update: Actually you can use the SizeOfResource() api to get the size)

 

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.
 
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Print | posted on Friday, October 16, 2009 7:33 AM | Filed Under [ General ]

Feedback

Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

That is so hackish it makes me cry.
11/22/2009 11:25 AM | Sensible Programmer
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Fabio Says:

Good Evening. I just saw your tutorial to embed an EXE inside another and found it really brilliant. Although I wasn't able to compile the code in Dev C++. Is there anything "tricky" to be done ? Is this even C++ or am I just assuming wrongly ?
Thank you a lot.
1/22/2010 7:38 AM | Prabhu
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Fabio, there are no more "tricks" that are required. Everything needed to run the program is mentioned in the code above.

I created a Win32 C++ application for PC, using Visual Studio 2005, and the above code works. And I am sure it will work on Windows Mobile platform as well. Though I haven't tested this on it.

If you could let us know what compile errors you are facing then maybe we could help.
1/22/2010 7:47 AM | Prabhu
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

In general, "\" (root drive of current working directory) is not writeable. And you forgot to clean it up.
2/15/2010 6:17 AM | Michiel
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Michiel, yes you are right. This post was meant to demo what could be done. Copying all the 7168bytes together, creating the file in the root folder and cleaning up are trivial details. Anyway, I have updated the post so its more clear. Thanks for your feedback.
2/15/2010 8:06 AM | Prabhu
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

In a window32 form application do i add the

#define IDR_FOO

IDR_FOO RCDATA "blablabla.txt"

to my app.rc?
or my resource.h?
2/26/2010 9:29 PM | Zachary
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

#define IDR_FOO 1234 goes in resource.h
and IDR_FOO RCDATA "blablabla.txt" goes in app.rc
2/27/2010 12:31 AM | Prabhu
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

And i request this is if you do not mind. You made a process viewer but can you make a tut on how to suspend a certain thread of a program if i have the programs handle. And the program has 4 threads and i need to suspend thread number 4
2/27/2010 2:03 PM | Zachary
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Hello, i like you tip, but i want to bind two exe files into one exe file, and when executed it should only create 1 process.

For example you can try to bind windows calc.exe and notepad.exe to binded.exe and when executed it should just see binded.exe in process list and both calc.exe and notepad.exe should start.
6/16/2010 3:36 AM | smith
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

I can't get this to work. FindResource returns null. When you say "IDR_FOO RCDATA "blablabla.txt" goes in app.rc", do you mean type it into the beginning of the text in that binary file?
8/5/2010 2:09 AM | Danny Crossley
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Yes, the line IDR_FOO RCDATA "blablabla.txt" goes in app.rc, you will have to manually edit this resource script. Just right click on app.rc in the solution explorer, select "View Code..", and enter the above line in the file. You will also have to #define IDR_FOO in resource.h
8/5/2010 10:53 AM | TechTwaddle
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

It's a text file, not a binary that opens up here. I meant do you add it before the MZ code in the PE file itself, not the header. Anyway, thanks for your advice. I've sorted that out now. It appears its been added automatically to the resource header by Visual Studio.

I ran it and it created the Voila.exe file but when it came to run the process, ( int ret = CreateProcess(L"\\Voila.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi), I get an error: "Access violation reading location 0x00000000." Voila.exe runs on its own, though.

I also noticed that pi was undeclared, so declared it as a PROCESS_INFORMATION type.

Why is there an access violation? It's here in mlock.c where the exception occurs:

/***
* _unlock - Release multi-thread lock
*
*Purpose:
* Note that it is legal for a thread to aquire _EXIT_LOCK1
* multiple times.
*
*Entry:
* locknum = number of the lock to release
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/

void __cdecl _unlock (
int locknum
)
{
/*
* leave the critical section.
*/
LeaveCriticalSection( _locktable[locknum].lock );
}

What is it trying to unlock and why can't it do it?
8/6/2010 4:02 AM | Danny Crossley
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Sorted it out:

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

not

int ret = CreateProcess(L"\\Voila.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
8/6/2010 5:14 AM | Danny Crossley
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Thanks for the info!
8/6/2010 2:11 PM | TechTwaddle
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Thanks a lot. Your tutorials are simple to understand. Great Article !
5/5/2011 8:08 PM | Searock
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

You could call SizeofResource (http://msdn.microsoft.com/en-us/library/ms648048%28v=VS.85%29.aspx) instead of hard coding the value of file size.
5/6/2011 8:18 PM | Searock
Gravatar

# re: How to embed an exe inside another exe as a resource and then launch it

Thanks Searock for the information! I have updated the post to mention this api...
5/6/2011 9:50 PM | Prabhu
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: