【问题标题】:How can I retrieve the memory address of a 64-bit pointer? [closed]如何检索 64 位指针的内存地址? [关闭]
【发布时间】:2016-09-04 18:40:19
【问题描述】:

我正在为支持 32 位和 64 位系统的 Flash 游戏开发培训师。

我试图返回指针的内存地址,以便我可以使用内存地址来更改值。我可以在 32 位版本中完美地做到这一点。但是,在 64 位版本中,它返回的内存地址不正确。

培训师目前仅支持谷歌浏览器。如果您使用的是 32 位训练器,Chrome 需要是 32 位的。如果您使用的是 64 位训练器,Chrome 需要是 64 位的。

这是来自作弊引擎的 32 位指针信息:

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"pointerscan result"</Description>
      <LastState Value="10000" RealAddress="071DCAA8"/>
      <VariableType>4 Bytes</VariableType>
      <Address>"pepflashplayer.dll"+01035A80</Address>
      <Offsets>
        <Offset>28</Offset>
        <Offset>28</Offset>
        <Offset>464</Offset>
        <Offset>B8</Offset>
        <Offset>80</Offset>
      </Offsets>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

下面的代码将成功获取32位指针的内存地址:

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

namespace Trainer
{
    internal class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadProcessMemory(IntPtr process, IntPtr baseAddress, [Out] byte[] buffer, int size,
            out IntPtr bytesRead);

        public static int ReadInt32(IntPtr process, IntPtr baseAddress)
        {
            var buffer = new byte[4];
            IntPtr bytesRead;
            ReadProcessMemory(process, baseAddress, buffer, 4, out bytesRead);
            return BitConverter.ToInt32(buffer, 0);
        }

        private static ProcessModule GetProcessModule(Process process, string moduleName)
        {
            foreach (ProcessModule module in process.Modules)
            {
                if (module.ModuleName == moduleName)
                {
                    return module;
                }
            }
            return null;
        }

        public static int GetRealAddress(IntPtr process, IntPtr baseAddress, int[] offsets)
        {
            var address = baseAddress.ToInt32();
            foreach (var offset in offsets)
            {
                address = ReadInt32(process, (IntPtr)address) + offset;
            }
            return address;
        }

        private static void Main()
        {
            Console.WriteLine(Environment.Is64BitProcess);

            // Get the first Chrome process that contains a module named "pepflashplayer.dll".
            var chromeProcess =
                Process.GetProcessesByName("chrome")
                    .FirstOrDefault(
                        process =>
                            process.Modules.Cast<ProcessModule>()
                                .Any(module => module.ModuleName == "pepflashplayer.dll"));

            if (chromeProcess != null)
            {
                var flashPlayerModule = GetProcessModule(chromeProcess, "pepflashplayer.dll");
                var baseAddress = flashPlayerModule.BaseAddress.ToInt32() + 0x01035A80;
                var offsets = new[] { 0x80, 0xB8, 0x464, 0x28, 0x28 };

                var realAddress = GetRealAddress(chromeProcess.Handle, (IntPtr)baseAddress, offsets);
                Console.WriteLine(realAddress.ToString("X"));
                Console.ReadLine();
            }
        }
    }
}

输出:

错误

83CAAA8

这是来自作弊引擎的 64 位指针信息:

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"pointerscan result"</Description>
      <LastState Value="10000" RealAddress="2A0C3492B38"/>
      <VariableType>4 Bytes</VariableType>
      <Address>"pepflashplayer.dll"+01CB16E8</Address>
      <Offsets>
        <Offset>48</Offset>
        <Offset>3D8</Offset>
        <Offset>370</Offset>
        <Offset>7A8</Offset>
        <Offset>360</Offset>
      </Offsets>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

下面的代码是我尝试检索 64 位指针的内存地址:

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

namespace Trainer
{
    internal class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadProcessMemory(IntPtr process, IntPtr baseAddress, [Out] byte[] buffer, int size,
            out IntPtr bytesRead);

        public static long ReadInt64(IntPtr process, IntPtr baseAddress)
        {
            var buffer = new byte[8];
            IntPtr bytesRead;
            ReadProcessMemory(process, baseAddress, buffer, 4, out bytesRead);
            return BitConverter.ToInt64(buffer, 0);
        }

        private static ProcessModule GetProcessModule(Process process, string moduleName)
        {
            foreach (ProcessModule module in process.Modules)
            {
                if (module.ModuleName == moduleName)
                {
                    return module;
                }
            }
            return null;
        }

        public static long GetRealAddress(IntPtr process, IntPtr baseAddress, int[] offsets)
        {
            var address = baseAddress.ToInt64();
            foreach (var offset in offsets)
            {
                address = ReadInt64(process, (IntPtr)address) + offset;
            }
            return address;
        }

        private static void Main()
        {
            Console.WriteLine(Environment.Is64BitProcess);

            // Get the first Chrome process that contains a module named "pepflashplayer.dll".
            var chromeProcess =
                Process.GetProcessesByName("chrome")
                    .FirstOrDefault(
                        process =>
                            process.Modules.Cast<ProcessModule>()
                                .Any(module => module.ModuleName == "pepflashplayer.dll"));

            if (chromeProcess != null)
            {
                var flashPlayerModule = GetProcessModule(chromeProcess, "pepflashplayer.dll");
                var baseAddress = flashPlayerModule.BaseAddress.ToInt64() + 0x01CB16E8;
                var offsets = new[] { 0x360, 0x7A8, 0x370, 0x3D8, 0x48 };

                var realAddress = GetRealAddress(chromeProcess.Handle, (IntPtr)baseAddress, offsets);
                Console.WriteLine(realAddress.ToString("X"));
                Console.ReadLine();
            }
        }
    }
}

输出:

是的

48

如何获取 64 位指针的内存地址?

【问题讨论】:

    标签: c# pointers memory


    【解决方案1】:

    在这里你分配 8 个字节:

    var buffer = new byte[8];
    IntPtr bytesRead;
    

    你在这里看到 只有 4 个

    ReadProcessMemory(process, baseAddress, buffer, 4, out bytesRead);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 2013-12-22
      相关资源
      最近更新 更多