如何获取进程使用的所有内存地址空间?

2023-11-22

我需要知道进程使用的所有内存地址空间。稍后将扫描内存空间以定位进程内的值并识别它们的位置/地址。我当前的处理过程是通过其(基地址+内存大小)获取每个模块的基地址。

我正在一个已知地址处具有已知值的进程上对此进行测试。当我查找该特定地址时,我得到了我期望的值。但是,当我扫描(我认为是)进程使用的所有地址空间时,我在任何地方都找不到该值。

我知道数值“4143000”存在于0x0CF8DC38 and 0x0CF8DDDC。当我打电话时ReadMemoryBytes(模块,模块.BaseAddress,4,(IntPtr)(0x0CF8DC38))我取回字节 (152, 55, 63, 0)。当我调用 BitConverter.GetBytes(4143000) 时,我会返回相同的字节集。当我在该进程上使用不同的内存扫描器时,我在这些地址处找到了该值。

但是,当我扫描“已知地址”时,我在任何地方都找不到这个值。看起来我的代码甚至没有找到进程正在使用的这些地址。

因此,我的问题是双重的:

  • 我如何在此过程中找到这些地址?
  • 我担心我可能正在处理系统内存中的绝对地址与进程内的相对地址。我这样做对吗?

.

// (in the calling method)
foreach (ProcessModule module in process.Modules) {
    ParameterizedThreadStart pst = new ParameterizedThreadStart(p => SearchModule(module, value));
    Thread t = new Thread(pst);
    t.Start(); }

private unsafe void SearchModule(ProcessModule module, string value)
{
Process process = getProcess;
int iVal;
double dVal;
int.TryParse(value, out iVal);
double.TryParse(value, out dVal);
for (Int64 addr = (Int64)module.BaseAddress; addr + value.Length < (Int64)module.BaseAddress + module.ModuleMemorySize; addr++)
{
    // Compare ints
    if (iVal > 0)
    {
        byte[] ExpectedBytes = BitConverter.GetBytes(iVal);
        byte[] ActualBytes = ReadMemoryBytes(module, (IntPtr)addr, (uint)ExpectedBytes.Length, (IntPtr)addr);

        bool isMatch = true;
        for (int i = 0; i < ExpectedBytes.Length; i++)
            if (ExpectedBytes[i] != ActualBytes[i])
                isMatch = false;
        if (isMatch)
            PossibleAddresses.Add((IntPtr)addr);
    }
}

private byte[] ReadMemoryBytes(ProcessModule mod, IntPtr memAddress, uint size, IntPtr BaseAddress)
{
    byte[] buffer = new byte[size];
    IntPtr bytesRead;
    unsafe
    {
        ReadProcessMemory(processPointer, BaseAddress, buffer, size, out bytesRead);
        return buffer;
    }
}

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

您获得的地址是指向托管 (CLR) 堆的指针。它们通常不会映射到绝对内存地址,并且可以在 GC 决定运行时从一个调用移动到另一个调用。

如果您使用“不安全”代码,您可以获得相对指针并管理自己的内存空间。它仍然在堆上,但至少可以保证 GC 不会修改您的地址空间。

不要指望能够在没有大量包装的情况下从非 CLR 代码访问堆上的内容。有多种方法可以在 CLR 管理的进程之间执行 IPC,但如果您希望非 CLR 进程访问您的内存,则必须向“外部世界”写入访问代理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取进程使用的所有内存地址空间? 的相关文章

随机推荐