Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a list of DLLs currently loaded in a process C#

Tags:

c#

dll

In Process Explorer I can view all the dlls (and dll details) loaded by a process selected. How can do this programmatically?

I can get a specific process details like this. But unsure where to go from here?

Process[] processlist = Process.GetProcesses();

foreach(Process theprocess in processlist){
Console.WriteLine(“Process: {0} ID: {1}”, theprocess.ProcessName, theprocess.Id);
}

enter image description here

like image 538
nlstack01 Avatar asked Apr 05 '16 15:04

nlstack01


People also ask

How do you see what DLLs are loaded in a process?

Unzip it and run the executable (procexp.exe) on the target machine as an administrator. Once running, enable viewing of loaded DLLs by either pressing CTRL+D or using the View > Lower Pane View > DLLs entry from the menu bar. Select the target process in the upper pane. The lower pane should now show loaded modules.

How can I get a list of registered DLLs?

To view all the registered DLLs you can use the following free utilities: RegDllView is a tool to view registered dll/ocx/exe files on your system and can also Register dll files from Explorer. ListDLLs is another tool that reports the DLLs loaded into processes.

What tool shows all the files and DLLs being used by a process?

ListDLLs v3. ListDLLs is a utility that reports the DLLs loaded into processes. You can use it to list all DLLs loaded into all processes, into a specific process, or to list the processes that have a particular DLL loaded.

How are DLL files loaded?

DLL files may be explicitly loaded at run-time, a process referred to simply as run-time dynamic linking by Microsoft, by using the LoadLibrary (or LoadLibraryEx ) API function. The GetProcAddress API function is used to look up exported symbols by name, and FreeLibrary – to unload the DLL.


2 Answers

After CLR v4, the accepted answer will show only unmanaged assemblies. If you want to get managed assemblies of external process you can refer to: Microsoft.Diagnostics.Runtime

Using the following code you can iterate app domains of external process and get loaded assemblies:

using var dt = DataTarget.AttachToProcess(clientProcess.Id, false);
assemblies = dt
      .ClrVersions
      .Select(dtClrVersion => dtClrVersion.CreateRuntime())
      .SelectMany(runtime => runtime.AppDomains.SelectMany(runtimeAppDomain => runtimeAppDomain.Modules))
      .Select(clrModule => clrModule.AssemblyName)
      .Distinct()
      .ToList();

Refer to their github for more details.

like image 167
Roman Badiornyi Avatar answered Oct 19 '22 23:10

Roman Badiornyi


The Process.Modules solution is NOT sufficient when running a 64-bit program and trying to collect all modules from a 32-bit process. By default, a 64-bit program will only work on a 64-bit process, and a 32-bit program will only work on a 32-bit processes.

For a solution that works for "AnyCPU", "x86", and "x64", see below. Simply call the CollectModules function with the target process. Note: A 32-bit program cannot collect modules from a 64-bit process.

public List<Module> CollectModules(Process process)
{
        List<Module> collectedModules = new List<Module>();

        IntPtr[] modulePointers = new IntPtr[0];
        int bytesNeeded = 0;

        // Determine number of modules
        if (!Native.EnumProcessModulesEx(process.Handle, modulePointers, 0, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll))
        {
            return collectedModules;
        }

        int totalNumberofModules = bytesNeeded / IntPtr.Size;
        modulePointers = new IntPtr[totalNumberofModules];

        // Collect modules from the process
        if (Native.EnumProcessModulesEx(process.Handle, modulePointers, bytesNeeded, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll))
        {
            for (int index = 0; index < totalNumberofModules; index++)
            {
                StringBuilder moduleFilePath = new StringBuilder(1024);
                Native.GetModuleFileNameEx(process.Handle, modulePointers[index], moduleFilePath, (uint)(moduleFilePath.Capacity));

                string moduleName = Path.GetFileName(moduleFilePath.ToString());
                Native.ModuleInformation moduleInformation = new Native.ModuleInformation();
                Native.GetModuleInformation(process.Handle, modulePointers[index], out moduleInformation, (uint)(IntPtr.Size * (modulePointers.Length)));

                // Convert to a normalized module and add it to our list
                Module module = new Module(moduleName, moduleInformation.lpBaseOfDll, moduleInformation.SizeOfImage);
                collectedModules.Add(module);
            }
        }

        return collectedModules;
    }
}

public class Native
{
    [StructLayout(LayoutKind.Sequential)]
    public struct ModuleInformation
    {
        public IntPtr lpBaseOfDll;
        public uint SizeOfImage;
        public IntPtr EntryPoint;
    }

    internal enum ModuleFilter
    {
        ListModulesDefault = 0x0,
        ListModules32Bit = 0x01,
        ListModules64Bit = 0x02,
        ListModulesAll = 0x03,
    }

    [DllImport("psapi.dll")]
    public static extern bool EnumProcessModulesEx(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded, uint dwFilterFlag);

    [DllImport("psapi.dll")]
    public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] uint nSize);

    [DllImport("psapi.dll", SetLastError = true)]
    public static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out ModuleInformation lpmodinfo, uint cb);
}

public class Module
{
    public Module(string moduleName, IntPtr baseAddress, uint size)
    {
        this.ModuleName = moduleName;
        this.BaseAddress = baseAddress;
        this.Size = size;
    }

    public string ModuleName { get; set; }
    public IntPtr BaseAddress { get; set; }
    public uint Size { get; set; }
}
like image 35
Zachary Canann Avatar answered Oct 19 '22 23:10

Zachary Canann