How can I retrieve the memory address of a 64-bit pointer?
<p>I'm developing a trainer for a flash game which will support 32-bit and 64-bit systems.</p>
<p>I trying to return the memory address of a pointer so that I can use the memory address to change the value. I am able to do this perfectly fine in the 32-bit version. But, in the 64-bit version it returns an incorrect memory address.</p>
<p>The trainer currently only supports Google Chrome. If you're using the 32-bit trainer, Chrome needs to be 32-bit. If you're using the 64-bit trainer, Chrome needs to be 64-bit.</p>
<p><strong>This is the 32-bit pointer's information from Cheat Engine:</strong></p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;CheatTable&gt;
  &lt;CheatEntries&gt;
    &lt;CheatEntry&gt;
      &lt;ID&gt;0&lt;/ID&gt;
      &lt;Description&gt;&quot;pointerscan result&quot;&lt;/Description&gt;
      &lt;LastState Value=&quot;10000&quot; RealAddress=&quot;071DCAA8&quot;/&gt;
      &lt;VariableType&gt;4 Bytes&lt;/VariableType&gt;
      &lt;Address&gt;&quot;pepflashplayer.dll&quot;+01035A80&lt;/Address&gt;
      &lt;Offsets&gt;
        &lt;Offset&gt;28&lt;/Offset&gt;
        &lt;Offset&gt;28&lt;/Offset&gt;
        &lt;Offset&gt;464&lt;/Offset&gt;
        &lt;Offset&gt;B8&lt;/Offset&gt;
        &lt;Offset&gt;80&lt;/Offset&gt;
      &lt;/Offsets&gt;
    &lt;/CheatEntry&gt;
  &lt;/CheatEntries&gt;
&lt;/CheatTable&gt;
</code></pre>
<p><strong>The code below will successfully retrieve the memory address of the 32-bit pointer:</strong></p>
<pre><code>using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

namespace Trainer
{
    internal class Program
    {
        [DllImport(&quot;kernel32.dll&quot;, 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 &quot;pepflashplayer.dll&quot;.
            var chromeProcess =
                Process.GetProcessesByName(&quot;chrome&quot;)
                    .FirstOrDefault(
                        process =&gt;
                            process.Modules.Cast&lt;ProcessModule&gt;()
                                .Any(module =&gt; module.ModuleName == &quot;pepflashplayer.dll&quot;));

            if (chromeProcess != null)
            {
                var flashPlayerModule = GetProcessModule(chromeProcess, &quot;pepflashplayer.dll&quot;);
                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(&quot;X&quot;));
                Console.ReadLine();
            }
        }
    }
}
</code></pre>
<p><strong>Output:</strong></p>
<blockquote>
<p>False</p>
<p>83CAAA8</p>
</blockquote>
<p><strong>This is the 64-bit pointer's information from Cheat Engine:</strong></p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;CheatTable&gt;
  &lt;CheatEntries&gt;
    &lt;CheatEntry&gt;
      &lt;ID&gt;0&lt;/ID&gt;
      &lt;Description&gt;&quot;pointerscan result&quot;&lt;/Description&gt;
      &lt;LastState Value=&quot;10000&quot; RealAddress=&quot;2A0C3492B38&quot;/&gt;
      &lt;VariableType&gt;4 Bytes&lt;/VariableType&gt;
      &lt;Address&gt;&quot;pepflashplayer.dll&quot;+01CB16E8&lt;/Address&gt;
      &lt;Offsets&gt;
        &lt;Offset&gt;48&lt;/Offset&gt;
        &lt;Offset&gt;3D8&lt;/Offset&gt;
        &lt;Offset&gt;370&lt;/Offset&gt;
        &lt;Offset&gt;7A8&lt;/Offset&gt;
        &lt;Offset&gt;360&lt;/Offset&gt;
      &lt;/Offsets&gt;
    &lt;/CheatEntry&gt;
  &lt;/CheatEntries&gt;
&lt;/CheatTable&gt;
</code></pre>
<p><strong>The code below is my attempt to retrieve the memory address of the 64-bit pointer:</strong></p>
<pre><code>using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

namespace Trainer
{
    internal class Program
    {
        [DllImport(&quot;kernel32.dll&quot;, 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 &quot;pepflashplayer.dll&quot;.
            var chromeProcess =
                Process.GetProcessesByName(&quot;chrome&quot;)
                    .FirstOrDefault(
                        process =&gt;
                            process.Modules.Cast&lt;ProcessModule&gt;()
                                .Any(module =&gt; module.ModuleName == &quot;pepflashplayer.dll&quot;));

            if (chromeProcess != null)
            {
                var flashPlayerModule = GetProcessModule(chromeProcess, &quot;pepflashplayer.dll&quot;);
                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(&quot;X&quot;));
                Console.ReadLine();
            }
        }
    }
}
</code></pre>
<p><strong>Output:</strong></p>
<blockquote>
<p>True</p>
<p>48</p>
</blockquote>
<p>How can I retrieve the memory address of a 64-bit pointer?</p>