I know that there is a process.Modules list in System.Diagnostics that contains some process modules but I got some troubles with it because I can't find some dlls here:
Process process = Memory.GetProcessByName("csgo");
foreach (ProcessModule pm in process.Modules)
Console.WriteLine(pm.ModuleName);
So I was looking for a solution to make it work, and I found something interesting in pinvoke.net, but it also didn't work:
var snapshot = CreateToolhelp32Snapshot(SnapshotFlags.Module, (uint)process.Id);
MODULEENTRY32 mod = new MODULEENTRY32() {
dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32))
};
if (!Module32First((IntPtr)snapshot, ref mod))
return;
do { Console.WriteLine(mod.szModule); } while (Module32Next((IntPtr)snapshot, ref mod));
Then I searched for the implementation of the same code in C ++, and it worked
#include <windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <string>
#include <sstream>
using namespace std;
int main() {
int a;
cin >> a;
HANDLE snapshot = CreateToolhelp32Snapshot(0x00000008, a);
MODULEENTRY32 mod;
mod.dwSize = sizeof(mod);
if (!Module32First(snapshot, &mod))
return 0;
do { cout << mod.szModule << endl; } while (Module32Next(snapshot, &mod));
system("pause");
return 0;
}
So my questions are: what is the difference between the second and third variants and how can I make it work in C #? I also tried to use OpenProcess() from user32.dll and GetModuleHandle() from kernel32.dll but it did not work.
You must compile your code as x64 and run as administrator to get all the modules.
Alternatively use this as your snapshot type:
TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32
and here is what CreateToolHelp32Snapshot() module looping looks like in C#:
const Int64 INVALID_HANDLE_VALUE = -1;
[Flags]
private enum SnapshotFlags : uint
{
HeapList = 0x00000001,
Process = 0x00000002,
Thread = 0x00000004,
Module = 0x00000008,
Module32 = 0x00000010,
Inherit = 0x80000000,
All = 0x0000001F,
NoHeaps = 0x40000000
}
[StructLayout(LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct MODULEENTRY32
{
internal uint dwSize;
internal uint th32ModuleID;
internal uint th32ProcessID;
internal uint GlblcntUsage;
internal uint ProccntUsage;
internal IntPtr modBaseAddr;
internal uint modBaseSize;
internal IntPtr hModule;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
internal string szModule;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string szExePath;
}
[DllImport("kernel32.dll")]
static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
[DllImport("kernel32.dll")]
static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
[DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle([In] IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, IntPtr th32ProcessID);
public static IntPtr GetModuleBaseAddress(IntPtr procId, string modName)
{
IntPtr modBaseAddr = IntPtr.Zero;
IntPtr hSnap = CreateToolhelp32Snapshot(SnapshotFlags.Module | SnapshotFlags.Module32, procId);
if (hSnap.ToInt64() != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry = new MODULEENTRY32();
modEntry.dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32));
if (Module32First(hSnap, ref modEntry))
{
do
{
if (modEntry.szModule.Equals(modName))
{
modBaseAddr = modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, ref modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
User contributions licensed under CC BY-SA 3.0