Click here to Skip to main content
Click here to Skip to main content

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

, 16 Dec 2009
Rate this:
Please Sign up or sign in to vote.
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.

//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.

// 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.

// 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.

// 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.

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)

About the Author

Kundan Kr
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 Pinmembersswater shi18-Oct-13 14:55 
Questionmy vote of 5 Pinmemberfenving14-Aug-12 21:25 
GeneralMy vote of 1 Pinmemberlusores19-Dec-09 3:28 
Questionany downloadable code?? PinmemberTanmay Broachwala17-Dec-09 21:12 
GeneralMy vote of 2 PinmemberIronXAres16-Dec-09 5:25 
AnswerRe: My vote of 2 PinmemberKundan Kr17-Dec-09 4:43 
GeneralReplacing data - What going to happen when you run out of space PinmemberCorey Fournier16-Dec-09 3:33 
AnswerRe: Replacing data - What going to happen when you run out of space PinmemberKundan Kr17-Dec-09 4:07 
GeneralFix the formatting PinmvpDave Kreskowiak16-Dec-09 1:49 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 16 Dec 2009
Article Copyright 2009 by Kundan Kr
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid