C# Remote GetModuleHandle Implementation
This implementation was modified/referenced from a source I no longer remember, so the credit is not entirely mine.
To use the implementation below, you first need to make sure you have a valid handle to a process using
OpenProcess
. Also make sure that your handle has the necessary privilege/rights (use
PROCESS_ALL_ACCESS
to ensure necessary rights). After which, you simply have to call the method using
RemoteGetModuleHandleA(processHandle, "moduleName.dll");
public enum DwFilterFlag : uint
{
LIST_MODULES_DEFAULT = 0x0, // This is the default one app would get without any flag.
LIST_MODULES_32BIT = 0x01, // list 32bit modules in the target process.
LIST_MODULES_64BIT = 0x02, // list all 64bit modules. 32bit exe will be stripped off.
LIST_MODULES_ALL = (LIST_MODULES_32BIT | LIST_MODULES_64BIT) // list all the modules
}
[DllImport("psapi.dll", SetLastError = true)]
public static extern bool EnumProcessModulesEx(
IntPtr hProcess,
[Out] IntPtr lphModule,
UInt32 cb,
[MarshalAs(UnmanagedType.U4)] out UInt32 lpcbNeeded,
DwFilterFlag dwff);
[DllImport("psapi.dll")]
static extern uint GetModuleFileNameEx(
IntPtr hProcess,
IntPtr hModule,
[Out] StringBuilder lpBaseName,
[In] [MarshalAs(UnmanagedType.U4)] int nSize);
private static String CutPath(String path)
{
int last = path.LastIndexOf("\\");
return path.Substring(last + 1, path.Length - last - 1);
}
/// <summary>
/// Returns the HMODULE, or module base address
/// </summary>
/// <param name="pid">IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, pid);</param>
/// <param name="moduleName"></param>
public static IntPtr RemoteGetModuleHandleA(IntPtr hProcess, string moduleName)
{
IntPtr moduleBase = IntPtr.Zero;
uint[] modsInt = new uint[1024];
// Setting up the variable for the second argument for EnumProcessModules
IntPtr[] hMods = new IntPtr[1024];
GCHandle gch = GCHandle.Alloc(hMods, GCHandleType.Pinned); // Don't forget to free this later
IntPtr pModules = gch.AddrOfPinnedObject();
// Setting up the rest of the parameters for EnumProcessModules
uint uiSize = (uint)(Marshal.SizeOf(typeof(IntPtr)) * (hMods.Length));
uint cbNeeded = 0;
if (EnumProcessModulesEx(hProcess, pModules, uiSize, out cbNeeded, DwFilterFlag.LIST_MODULES_ALL) == true)
{
Int32 uiTotalNumberofModules = (Int32)(cbNeeded / (Marshal.SizeOf(typeof(IntPtr))));
for (int i = 0; i < (int)uiTotalNumberofModules; i++)
{
StringBuilder strbld = new StringBuilder(1024);
GetModuleFileNameEx(hProcess, hMods[i], strbld, (int)(strbld.Capacity));
String module = strbld.ToString();
String processModuleName = CutPath(module);
Console.WriteLine("Comparing {0} {1}", processModuleName, moduleName);
if (stricmp(processModuleName, moduleName) == 0)
{
moduleBase = hMods[i];
break;
}
}
}
// Must free the GCHandle object
gch.Free();
return moduleBase;
}
Be First to Comment