2016-09-04 79 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);