Skip to content

Instantly share code, notes, and snippets.

@AlexRasch
Created November 6, 2023 21:37
Show Gist options
  • Save AlexRasch/ac2770d0b50657b7a474b77035bb940b to your computer and use it in GitHub Desktop.
Save AlexRasch/ac2770d0b50657b7a474b77035bb940b to your computer and use it in GitHub Desktop.
Read resource and dump to disk
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Net.Mail;
namespace Stub
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EnumResourceTypes(IntPtr hModule, EnumResourceTypesProc lpEnumFunc, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EnumResourceNames(IntPtr hModule, IntPtr lpszType, EnumResourceNamesProc lpEnumFunc, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
public delegate bool EnumResourceTypesProc(IntPtr hModule, IntPtr lpszType, IntPtr lParam);
public delegate bool EnumResourceNamesProc(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);
static bool EnumResourceTypesCallback(IntPtr hModule, IntPtr lpszType, IntPtr lParam)
{
int resourceTypeId = (int)lpszType;
if (resourceTypeId == 2) // BITMAP
{
Console.WriteLine("Resource Type: RT_BITMAP");
EnumResourceNames(hModule, lpszType, EnumResourceNamesCallback, IntPtr.Zero);
}
return true;
}
static bool EnumResourceNamesCallback(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam)
{
int resourceNameId = (int)lpszName;
// Find and load the resource based on the resource type and name.
IntPtr hResInfo = FindResource(hModule, lpszName, lpszType);
if (hResInfo != IntPtr.Zero)
{
// Calculate the size of the resource data
Console.WriteLine($"Size of resource:{SizeofResource(hModule, hResInfo)} ");
int resourceSize = (int)SizeofResource(hModule, hResInfo);
IntPtr hResData = LoadResource(hModule, hResInfo);
if (hResData != IntPtr.Zero)
{
// Initialize a buffer to store resource content
byte[] resourceContent = new byte[resourceSize];
IntPtr lockedResource = LockResource(hResData);
// Read the full resource content.
Marshal.Copy(lockedResource, resourceContent, 0, resourceSize);
// Write content of resource
WriteResource("resource.bmp", resourceContent);
// We don't need to unload? https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freeresource
}
else
{
Console.WriteLine($"Failed to load the resource.");
}
}
else
{
Console.WriteLine("Could not load FindResource.");
}
return true;
}
static void Main(string[] args)
{
IntPtr hModule = GetModuleHandle(null);
if (hModule != IntPtr.Zero)
{
EnumResourceTypes(hModule, EnumResourceTypesCallback, IntPtr.Zero);
}
else
{
Console.WriteLine("Failed to get a handle to the current executable.");
}
}
static void WriteResource(string filePath, byte[] resourceContent)
{
File.WriteAllBytes(filePath, resourceContent);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment