如何在C#中知道dll的BaseAddress和指针的偏移量的情况下读取C#中的内存?

时间:2019-01-31 02:23:23

标签: c# pointers dll process memory-address

我正在尝试使用通过Cheat Engine检索的基址和偏移量从c#的内存中读取值。

问题是我必须在exe内使用一个dll作为起点,因为我发现的指针都没有从exe的基地址开始。

BaseAddress:“ mono-2.0-bdwgc.dll” + 00491DE8
偏移量1:98(十六进制)
偏移量2:350(十六进制)

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读取指针。我不知所措。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分: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));