Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / C++

Modify/Update resources of an Exe/DLL on the fly

Rate me:
Please Sign up or sign in to vote.
3.29/5 (13 votes)
16 Dec 2009CPOL4 min read 60.2K   52   28   9
Sometimes it is useful to modify (add / remove / delete) resources in an exe and/or DLL file at run time.

Introduction

Sometimes, it is useful to modify (add / remove / delete) resources in an EXE and/or DLL file at run time. This is not the limit, we can also modify the icon and version information on the fly and give a new look to our EXE/DLL files and load them with new features.

What are the ways to do this? Obviously, writing a separate module that will modify the resources. Let's go through the details, but before that, we need to understand the background details of the key terms.

Background knowledge

DLL

A DLL (Dynamic Link Library) is a file that includes the source code or callable functions that provide a service to the application currently being executed.

EXE

EXE is a stand-alone application that could be executed on any platform. EXE is an independent application while a DLL is dependent on an application's call.

Window resource

A window resource (I am talking about Win32 resource) instance consists of the following attributes:

  • Type: cursors, dialogs, bitmaps etc.
  • Name: a Unicode string or a 2-byte numeric identifier.
  • Language: a 2-byte numeric value indicating the language of the resource instance; e.g., English (U.S.) = 1033, Chinese (Traditional) = 1028.
  • Data: the actual data of the resource (e.g., a bitmap image).

Logic details

Here, I am introducing the logic and code that replaces a BITMAP resource in an exe file by an externally provided bitmap image.

To modify an exe file, we need to do the following steps:

  1. get the handle of the exe file.
  2. find the resources (get handle) that replace the existing resources of the exe file.
  3. load the resource (which replaces the existing resource of the exe file) into global memory.
  4. lock the resource into global memory.
  5. update the resource in the exe file.
  6. end the resource update.
  7. close the handles.

Code snippets and explanations

// Get the bmp into memory
HANDLE hFile   = CreateFile(bmpPath, GENERIC_READ, 0, NULL, 
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD FileSize = GetFileSize(hFile, NULL);

In the above lines of code, I am taking the handle of my BITMAP file and calculating its size. Here, bmpPath(char array) stores the full path of my .bmp file, GENERIC_READ is the requested access to the file, the third parameter 0 specifies that if CreateFile succeeds, the file cannot be shared and cannot be opened again until the handle to the file is closed, OPEN_EXISTING specifies to open the file only if it exists, and FILE_ATTRIBUTE_NORMAL has the file attributes and flags, FILE_ATTRIBUTE_NORMAL being the most common default value for files. After execution of the above two lines, hFile contains a .bmp image handle, and FileSize contains its size in bytes.

C++
//reading image into global memory.
BYTE *pBuffer = new BYTE[FileSize];
ReadFile(hFile, pBuffer, FileSize, &dwBytesRead, NULL);

The second step (in the above two lines) is to read data in to memory. Here, dwBytesRead is the integer type variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work.

C++
// Write in the new resources
HANDLE hExeFile = BeginUpdateResource(exePath, FALSE);

After execution of the above line, hExeFile contains the handle that can be used by the UpdateResource function to modify (add, delete, or replace) resources in a binary module. exePath(char array) stores the full path of the exe file.

The next step is more important and needs extra care. The BITMAP resource in the exe file has an ID, and first, we need to retrieve it. We can get it easily using an API function. For the time being, I am using a hardcoded ID directly. The BITMAP image which replaces the exe's BITMAP resource must be in binary form and must not contain header information when it is passed as an argument to the UpdateResource function. The main reason behind this is, the exe file just replaces the raw BITMAP data, not its header information, which means, after the execution of the UpdateResource function, the new image contains the same header information as the old one, but new BITMAP data. To implement this, we have to explicitly skip the header information in the BITMAP file that replaces the exe resource.

C++
// just skipping the header information and  calculating modifying size.
BYTE *newBuffer      = pBuffer  + sizeof(BITMAPFILEHEADER);
DWORD NewFileSize = FileSize - sizeof(BITMAPFILEHEADER);

Now, after doing all the necessary work, UpdateResource will be executed.

C++
// update resouce.
UpdateResource(hExeFile, RT_BITMAP, MAKEINTRESOURCE(130), 
  MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 
  (LPVOID)newBuffer, NewFileSize);

In the above line, hExeFile is a module (exe file) handle returned by the BeginUpdateResource function, referencing the file to be updated. Also, we need to pass the resource's type, name, and language ID information. Here, RT_BITMAP is the resource type, MAKEINTRESOURCE(130) is its name (130 is the ID of the exe's BITMAP resource), and MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) is its language ID. newBuffer is the binary data of the .bmp file that does not have header information.

After execution of the UpdateResource function, it is necessary to call the EndUpdateResource function because it commits or discards the changes made prior to a call to UpdateResource.

C++
EndUpdateResource(hExeFile, FALSE);

// release handle and memory.
CloseHandle(hFile);
delete[] pBuffer;

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Amdocs
India India
M.sc(Mathematics) and MCA from Birla Institute of Technology, Mesra.

Comments and Discussions

 
QuestionHow to update a 64bits exe within a 32bits program Pin
sswater shi18-Oct-13 14:55
sswater shi18-Oct-13 14:55 
Questionmy vote of 5 Pin
fenving14-Aug-12 21:25
fenving14-Aug-12 21:25 
GeneralMy vote of 1 Pin
lusores19-Dec-09 3:28
lusores19-Dec-09 3:28 
Questionany downloadable code?? Pin
Tanmay Broachwala17-Dec-09 21:12
Tanmay Broachwala17-Dec-09 21:12 
GeneralMy vote of 2 Pin
RiddlerDev16-Dec-09 5:25
RiddlerDev16-Dec-09 5:25 
AnswerRe: My vote of 2 Pin
Kundan Kr17-Dec-09 4:43
Kundan Kr17-Dec-09 4:43 
GeneralReplacing data - What going to happen when you run out of space Pin
Corey Fournier16-Dec-09 3:33
Corey Fournier16-Dec-09 3:33 
AnswerRe: Replacing data - What going to happen when you run out of space Pin
Kundan Kr17-Dec-09 4:07
Kundan Kr17-Dec-09 4:07 
GeneralFix the formatting Pin
Dave Kreskowiak16-Dec-09 1:49
mveDave Kreskowiak16-Dec-09 1:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.