Hi Guys!
In the windows operating system. There might be times where we need to call other executable in our own program. This works well probably on the first time. But when the executable file being called is renamed or path has been change.....BOOM! that's when the problem comes. You need to change your program code then point to the new path or filename of the executable.
The solution can be........what if we can add the executable being call together with our program code so that when we need to call the executable just ripped its code from its location on our program code, saved it to a temporary folder then run it from there. This eliminate entirely the problem on rename and change directory. ................Well, This is basically what I will discuss in this post on how to add a .exe resource on own program. In here, I will be using the free Dev-C++. The version I'm using is still the 4.9.9.2 which is I think 2011 when this was released.
For demonstration, I will follow below steps:
1.) We will create a child program that will be called by the mother program. It will be a simple window based program that will display a message box "hello".
2.) We will create a simple console program which we will call the mother program. The child program binary code will be added to the mother program as a resource file. This is basically the main focus of this post.
3.) We will create a code on the mother program to extract the child binary code and saved it to temporary folder.
4.) The mother program will run the child program from the temporary folder.
We have now the steps....so...let's start!
Creating the Child program(Step1)
1.) of coarse launch Dev C++. It will show with blank workspace.
2.) Click File, new, project then click "Windows application". Project name say 'Child". Then click OK.
3.) Navigate to the folder where you want to save the project. Then click "save".
4.) A windows skeleton project will show.
5.) Add the highlighted in yellow text below for our "hello" message box.
/*==================================================*/
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
case WM_CREATE:
MessageBox(hwnd,"hello","hello",MB_OK); /* Say Helloooo*/
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
/*==================================================*/
6.) Compile the project by clicking "Execute", Compile.
7.) To Run click "Execute", "Run":
So at this point we have now a child program. This program will be embedded inside the mother program as a resource and will be extracted thru a function.
Creating the Mother Program(Step 2)
1.) Click File, Close Project to close the child program and start a new blank workspace.
2.) Click File, New Project, then click "Console Window". Project name say "Mother". Then click OK.
4.) Navigate to the folder where you want to save the project. Then click "save".
5.) A console skeleton project will show.
6.) Compile the project by clicking "Execute", Compile.
Adding .exe file as resource (Step 3)
ops!!! just some explanation.........
.exe file can be added as a resource file to a program being compiled. Resource file are mostly used to store icons. Aside from exe or icons, anything can be added as resource. What the compiler will just do is add the binary of the resource to the compiled program. This in effect will do our exe within an exe.
to continue........
6.) Copy "Child.exe" from the child folder to the mother folder.
7.) Create a text file on the mother folder. Named it as....say "Mother.rc". This will be a resource file.
8.) Type the content of the "Mother.rc" as:
129 EXEBIN DISCARDABLE "Child.exe"
This means we are creating an discardable "EXEBIN" (named it in the way you want) resource with ID "129" (should not be duplicate to any constant value on your program) and the binary image is "Child.exe" -which is the exe file you created on step 1 and copied to mother directory on step6 above.
9.) Since, our mother program is a Console Window we need to manually compile "Mother.rc" to become a binary resource file "Mother.res". To do this, you need to call in "windres.exe" located on bin folder of the Dev C++ directory:
on Command prompt or bat file:
\Path_directory_of_DevC++_Bin_folder\windres.exe -i Mother.rc --input-format=rc -o Mother.res -O coff
This creates "Mother.res". A Binary resource file we can add to the Mother.exe.
10.) In the folder where mother was saved there is a file called "Makefile.win". This is the file used by the compiler to create "Mother.exe". Edit it by adding below yellow highlighted text:
RES = Mother.res
OBJ = main.o $(RES)
LINKOBJ = main.o $(RES)
This is to add the binary we just created on step 9.
10.) CLick Project, Project options. In the "Makefile" tab check "Use custom makefile" and browse to the "Makefile.win" you edited on step 10.
Adding the code to extract the child exe added as resource(Step 3)
11.) Add the following code to Mother.exe:
/*======================================================*/
#include <windows.h>
#define IDR_EXECHILD 129
BOOL Extract_Res_Exe(DWORD ResID, LPCTSTR File)
{
HRSRC hResource=FindResource(NULL,MAKEINTRESOURCE(ResID),"EXEBIN");
if (hResource)
{
HGLOBAL binGlob=LoadResource(NULL,hResource);
if (binGlob)
{
void* binData=LockResource(binGlob);
HANDLE FileName;
FileName=CreateFile(File,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL);
if (FileName!=INVALID_HANDLE_VALUE)
{
DWORD size, written;
size = SizeofResource(NULL, hResource);
WriteFile(FileName, binData, size, &written, NULL);
CloseHandle(FileName);
return true;
}
return false;
}
return false;
}
return false;
}
/*==========================================*/
The code above declares a constant " IDR_EXECHILD" with value 129 same as the one on Mother.res file for the "EXEBIN" . The function "Extract_Res_Exe"will extract a resource called "EXEBIN" and saved it to a file.
Adding code on the mother program to extract and run the child program(Step3 and 4)
12.) On the main function add below code in yellow:
/*============================================*/
int main(int argc, char *argv[])
{
char TempPath[255];
GetTempPath(255,TempPath);
printf("\n%s\n",TempPath);
strcat(TempPath,"Child_extracted.exe");
if (Extract_Res_Exe(IDR_EXECHILD,TempPath))
{
printf("Successfully extracted!!!!....");
/*========EXECUTE the EXE============*/
WinExec(TempPath,10);
}
system("PAUSE");
return EXIT_SUCCESS;
}
/*============================================*/
13.) Compile and run the project by clicking "Execute", Compile and run.
The code gets the temporary folder thru the windows api GetTempPath function. Then, it extracts an EXEBIN resource with ID 129 and saved it to the temporary folder under the name "Child_extracted.exe" then run it with the "WinExec" function.
Anyway, this post looks like boring :-) but hope I did show you the idea of exe within an exe.................till next time guys....thanks! for reading.
No comments:
Post a Comment