C# – Add resources to native executable file with UpdateResource

When I developed my tool YM Login BG for changing background of YM Login Dialog, I had a chance to work more with resource section of a compiled executable file. To make this tool, there are two steps I must pass.
- I must insert a bitmap image into Bitmap resource section of file.
- I must somehow insert a new control into login dialog. This control is just the background of the dialog.

1. Use ResHacker
To accomplish these two steps, we can use ResHacker http://angusj.com/resourcehacker/ to add bitmap and control. To add bitmap, use ResHacker to open executable file, browse to Bitmap branch, on the menu Action, choose “Add a new Resource”

Adding control to dialog is almost same, browse to Dialog branch, choose which dialog we want to edit, add control and press Compile Script to save all information

So it’s pretty simple when we have ResHacker in hand. But I would like to run this progress completely automatically. That means I just need to choose an image and click to finish the remaining steps. Therefore I should use some APIs which are relevant to resource of an executable file.

2. Programming
General, to add,edit,replace a resource to an assembly we must call 3 APIs functions: BeginUpdateResource, UpdateResource and EndUpdateResource. They must be called in order to get the handle of the target, edit it and save all changes. Their signatures in c# are below

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr BeginUpdateResource(string pFileName,
   [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool UpdateResource(IntPtr hUpdate, uint lpType, uint lpName, ushort wLanguage, byte[] lpData, uint cbData);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);

For example if we want to add a bitmap to resource of an executable file, we should write like this

IntPtr ipTarget = Win32API.BeginUpdateResource(strFileName, false);
if (Win32API.UpdateResource(ipTarget, Win32API.RT_BITMAP, 41713, 1033, baRes, (uint)baRes.Length))
{
	Win32API.EndUpdateResource(ipTarget, false);
	Console.WriteLine("Update successfully");
}

The strFileName is the path to target file which we want to add,replace or edit resource. baRes is the byte array of bitmap file. Please pay attention that this byte array is not the complete byte array of bitmap image. We must eliminate the first 14 bytes header of bitmap before adding it. Otherwise your bitmap will be not correctly handled. The baRes was constructed as below

byte[] baBMP = File.ReadAllBytes(strBMPPath);
byte[] baRes = new byte[baBMP.Length - 14];
Buffer.BlockCopy(baBMP, 14, baRes, 0, baRes.Length);

The argument wLanguage is the LangID of resource. In my example above, I used hard-code but if you want a variable way then you can get the LangID as below

CultureInfo ciInfo = new CultureInfo("en-US");
ushort uLcid = (ushort)ciInfo.LCID;

The main idea is unchanged when we want to read, replace information of a dialog. We just need to call some more APIs to load resource into memory and read it out.

byte[] baData = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x02, 0x54, 0xC8, 0xFF,
	0xFE, 0xFF, 0x3B, 0x01, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x82, 0x00, 0xFF, 0xFF,
	0xF1, 0xA2, 0x00, 0x00, 0x00, 0x00
};

// Load the DLL/EXE without executing its code
IntPtr ipModule = Win32API.LoadLibraryEx(strFileName, IntPtr.Zero, Win32API.LOAD_LIBRARY_AS_DATAFILE);
if (ipModule != IntPtr.Zero)
{
	// Find the group resource which lists its images
	IntPtr ipResInfo = Win32API.FindResource(ipModule, 929, Win32API.RT_DIALOG);
	if (ipResInfo != IntPtr.Zero)
	{
		uint nSizeOfResource = Win32API.SizeofResource(ipModule, ipResInfo);
		IntPtr ipResData = Win32API.LoadResource(ipModule, ipResInfo);
		if (ipResData != IntPtr.Zero)
		{
			byte[] baTemp = new byte[nSizeOfResource + baData.Length];
			IntPtr ipMemorySource = Win32API.LockResource(ipResData);
			Marshal.Copy(ipMemorySource, baTemp, 0, (int)nSizeOfResource);
			for (int nIndex = (int)nSizeOfResource; nIndex < baTemp.Length; nIndex++)
			{
				baTemp[nIndex] = baData[nIndex - nSizeOfResource];
			}
			baTemp[0x10] = (byte)(1 + baTemp[0x10]);
			IntPtr ipTarget = Win32API.BeginUpdateResource(strFileName, false);
			if (Win32API.UpdateResource(ipTarget, Win32API.RT_DIALOG, 929, 1033, baTemp, (uint)baTemp.Length))
			{
				Win32API.EndUpdateResource(ipTarget, false);
				Console.WriteLine("Update successfully");
			}
			else
			{
				Console.WriteLine("Update false");
			}

		}
		else
		{
			Console.WriteLine("Could not load login dialog");
		}
	}
	else
	{
		Console.WriteLine("Could not locate login dialog");
	}
}
else
{
	Console.WriteLine("Could not load dll");
}

I think it’s very simple to understand the code. For a sample project you can download at following link. “Add,Replace,Edit resource of an executable file with C#“.

5 thoughts on “C# – Add resources to native executable file with UpdateResource”

  1. Hi, nice post. I just wonder if you know or if you can point me in the right direction.
    I want to change the Icon programmatically to any file type. Like DropBox is doing when it finished sinchronizing, it put a check mark on the file.

    Thanks for the help.

  2. Hello its very urgent i am working on my project logon tweaker vista
    and i want to know how can we update resources in a .dll or .exe file . The file i want to edit resource is imageres.dll

  3. Hello,

    thank you for this tutorial. I’ve got a problem. If I add a resource, which not exists in the .dll all works fine. If I use a lpType / ResourceType which already exists in the .dll nothing happens. BeginUpdateResource works, but at UpdateResource it hangs up. No exception. Nothing. It hangs at this point. Does anybody know, what the problem could be?

    Greets from Germany,
    Raffael

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>