如何在C#中读取内存,知道.exe进程中dll的BaseAddress和指针的偏移量?

问题描述 投票:0回答:1

我试图使用通过Cheat Engine检索到的baseaddress和偏移量在C#中读取一个内存值。

问题是我必须使用exe内部的dll作为起点,因为我找到的指针都不是从exe的基地址开始的。

BaseAddress: "mono-2.0-bdwgc.dll "+00491DE8 偏移量1: 98 (hex) 偏移量2: 350 (hex)

Process[] process_search = Process.GetProcessesByName("ProcessName");

if (process_search.Length != 0)
{
    ProcessModuleCollection modules = process_search[0].Modules;
    ProcessModule dll = null;
    foreach (ProcessModule i in modules)
    {
        if (i.ModuleName == "mono-2.0-bdwgc.dll")
        {
            dll = i;
            break;
        }
}

我能够得到dll的设置,而且我可以通过dll.baseAddress得到它的基本地址。我想知道两件事。

1)我如何在基地址上加上偏移量,以获得完整的指针地址 2)我如何实际访问该地址的内存值?

我看到的所有其他解决方案都是从进程本身读取指针,而不是进程中的dll。我不知道该怎么办。感谢任何帮助。

c# pointers dll process memory-address
1个回答
0
投票

ProcessModule包含一个名为BaseAddress的变量,它包含了它在运行时的地址。

将其与FindDMAAddy结合起来,去掉每个指针的引用,并添加每个偏移量,有效地走指针链,它将返回多级指针指向的地址。

然后你创建一个正确大小的缓冲区,使用ReadProcessMemory()将字节读入其中,然后你使用BitConverter.ToInt32()或其他类似的函数将其转换为你需要的类型。

下面是一个例子,可以把你的指针当作一个int指针来读。

public static IntPtr GetModuleBaseAddress(Process proc, string modName)
{
    IntPtr addr = IntPtr.Zero;

    foreach (ProcessModule m in proc.Modules)
    {
        if (m.ModuleName == modName)
        {
            addr = m.BaseAddress;
            break;
        }
    }
    return addr;
}

public static IntPtr FindDMAAddy(IntPtr hProc, IntPtr ptr, int[] offsets)
{
    var buffer = new byte[IntPtr.Size];
    foreach (int i in offsets)
    {
        ReadProcessMemory(hProc, ptr, buffer, buffer.Length, out var read);

        ptr = (IntPtr.Size == 4)
        ? IntPtr.Add(new IntPtr(BitConverter.ToInt32(buffer, 0)), i)
        : ptr = IntPtr.Add(new IntPtr(BitConverter.ToInt64(buffer, 0)), i);
    }
    return ptr;
}

Process proc = Process.GetProcessesByName("whatever")[0];

var modBase = GetModuleBaseAddress(proc, "mono-2.0-bdwgc.dll"");

var addr = FindDMAAddy(proc.handle, (IntPtr)(modBase + 0x00491DE8), new int[] { 0x98, 0x350});

byte[] buffer = new byte[4];

ReadProcessMemory(proc.Handle, ammoAddr, buffer, 4, out _);

System.Console.WriteLine("Buffer int value:" + BitConverter.ToInt32(buffer, 0));
© www.soinside.com 2019 - 2024. All rights reserved.