2016-09-04 47 views
-3

我正在开发一款支持32位和64位系统的Flash游戏教练。如何检索64位指针的内存地址?

我试图返回一个指针的内存地址,以便我可以使用内存地址来更改该值。我能够在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(); 
      } 
     } 
    } 
} 

输出:

我怎么能检索64位指针的内存地址?

回答

1

在这里,你分配8个字节:

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

,在这里你阅读仅有4

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