Skip to content

C# Remote GetModuleHandle Implementation

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;
}

 

Enjoyed the content ? Share it with your friends !
Published inDevelopmentProgramming

Be First to Comment

Leave a Reply

Your email address will not be published.