【问题标题】:Read memory with module base address使用模块基地址读取内存
【发布时间】:2016-02-17 20:08:29
【问题描述】:

如何读取带有模块基地址的内存? 例如如何读取这个内存:“winCap64.dll”+0x123456 + offsets。

我添加了一个示例代码,说明经过一些研究后我可以生成什么,但我仍然无法阅读 C# 中的任何内容。但是地址绝对没问题,因为当我将它们添加到 Cheat Engine 时,它​​们会返回正确的值。

编辑:添加示例代码

    [DllImport("kernel32.dll")]
    static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
    byte[] lpBuffer, UIntPtr nSize, uint lpNumberOfBytesWritten);

    static IntPtr Handle;

    static void Main(string[] args)
    {
        Process[] Processes = Process.GetProcessesByName("process");
        Process nProcess = Processes[0];
        Handle = OpenProcess(0x10, false, (uint)nProcess.Id);
        IntPtr pointer = IntPtr.Add(nProcess.Modules[125].BaseAddress, 0x020C5150);
        int curhp = ReadOffset(pointer, 0x4D8);
        int curhp2 = ReadOffset((IntPtr)curhp, 0x0);
        int curhp3 = ReadOffset((IntPtr)curhp2, 0x1c0);
        Console.WriteLine(curhp3.ToString());
        Console.ReadKey();
    }

    public static int ReadOffset(IntPtr pointer, uint offset)
    {
        byte[] bytes = new byte[24];

        uint adress = (uint)ReadPointer(pointer) + offset;
        ReadProcessMemory(Handle, (IntPtr)adress, bytes, (UIntPtr)sizeof(int), 0);
        return BitConverter.ToInt32(bytes, 0);
    }

    public static int ReadPointer(IntPtr pointer)
    {
        byte[] bytes = new byte[24];

        ReadProcessMemory(Handle, pointer, bytes, (UIntPtr)sizeof(int), 0);
        return BitConverter.ToInt32(bytes, 0);
    }

【问题讨论】:

  • 听起来你在 64 位世界中需要 nProcess.Modules[125].BaseAddress.ToInt64() + 0x02093458
  • @Ctx 也可以使用long 而不是int
  • 这确实可以解决算术异常,但为什么我仍然无法读取内存?
  • IIRC 目标架构设置为 Any CPU 的程序将无法读取专门在 x86x86_64 架构上运行的程序的内存,例如 C/C++ 程序和某些.NET 程序。尝试在Properties > Build中将项目的“平台目标”设置为x64
  • 在上面的示例中,我相信它只是缺少编码。如果编码正确,它应该可以工作。

标签: c# memory module memory-address


【解决方案1】:

这样的事情怎么样?

IntPtr pointer = IntPtr.Add(nProcess.Modules[125].BaseAddress, BaseAddress);
Console.WriteLine("Final: " + pointer.ToString("X"));

int hp = ReadInt32(pointer, Handle);
string hexPrefix = "80" + hp.ToString("X"); //because int32 will cut some digits. I sugget using int64. Even UInt64.
long hexToint = long.Parse(hexPrefix, NumberStyles.HexNumber);
hp = ReadInt32((IntPtr)hexToint + 0x00, Handle);
hexPrefix = "80" + hp.ToString("X");
hexToint = long.Parse(hexPrefix, NumberStyles.HexNumber);
hp = ReadInt32((IntPtr)hexToint + 0x1c0, Handle);
hexPrefix = "80" + hp.ToString("X");
hexToint = long.Parse(hexPrefix, NumberStyles.HexNumber);
hp = ReadInt32((IntPtr)hexToint + 0x0, Handle);

【讨论】:

  • 行得通!这是一个地狱般的调试。很好的解决方法。
【解决方案2】:

IntPtr 是一种与架构无关的方式来存储指针并将其传递给ReadProcessMemory

IntPtr pointer = IntPtr.Add(nProcess.Modules[125].BaseAddress, 0x02093458);

【讨论】:

  • 这将解决算术异常,但我仍然无法读取内存。用完整的示例代码更新了问题
  • 当我在引擎上添加内存并添加三个偏移量时,我可以读取它(例如作弊引擎或 Artmoney)。但是我不能以编程方式做到这一点
猜你喜欢
  • 2013-08-28
  • 2017-05-16
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多