Как я могу получить ВСЕ модули процесса в C#? - PullRequest
1 голос
/ 07 апреля 2020

Я знаю, что есть процесс. Список модулей в System.Diagnostics, который содержит некоторые модули процесса, но у меня возникли некоторые проблемы с ним, потому что я не могу найти здесь некоторые библиотеки:

Process process = Memory.GetProcessByName("csgo");

foreach (ProcessModule pm in process.Modules) 
    Console.WriteLine(pm.ModuleName);

enter image description here

Поэтому я искал решение, чтобы оно заработало, и я нашел кое-что интересное в pinvoke. net, но оно также не работало:

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

enter image description here

Затем я искал реализацию того же кода в C ++, и он работал

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

enter image description here

Итак, мои вопросы: в чем разница между вторым и третьим вариантами и как я могу заставить его работать в C #? Я также пытался использовать OpenProcess () из user32.dll и GetModuleHandle () из kernel32.dll, но это не сработало.

1 Ответ

0 голосов
/ 19 апреля 2020

Вы должны скомпилировать свой код как x64 и запустить от имени администратора, чтобы получить все модули.

В качестве альтернативы используйте это как тип снимка:

TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32

и Вот как выглядит цикл CreateToolHelp32Snapshot () в 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...