2016-12-06 1894 views
1

我正在尝试为游戏创建教练。这导致了错误(我认为),因为我试图用32位命令访问64位游戏的游戏内存。32位进程无法访问64位进程中的模块

的源代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Diagnostics; 

namespace Infinite_Trainer___Cod_IW 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void bunifuImageButton1_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 

     private void bunifuFlatButton1_Click(object sender, EventArgs e) 
     { 
      string prestigeLevel = bunifuDropdown1.selectedValue; 
      string xp = bunifuSlider1.Value.ToString(); 
      string winrate = bunifuMaterialTextbox1.Text; 
      string loserate = bunifuMaterialTextbox2.Text; 

      Process[] process = Process.GetProcessesByName("iw7_ship"); 
      if (process.Length > 0) 
      { 
       using (CheatEngine.Memory memory = new CheatEngine.Memory(process[0])) 
       { 
        IntPtr prestigeAddress = memory.GetAddress("\"iw7_ship.exe\"+04105320+6E4"); 
        memory.WriteUInt32(prestigeAddress, 1); 
       } 
      } 
      else 
      { 
       MessageBox.Show("Game isn't running"); 
      } 
     } 
    } 
} 

而且memory.cs类:

using System; 
using System.Diagnostics; 
using System.Text.RegularExpressions; 

namespace Infinite_Trainer___Cod_IW.CheatEngine 
{ 
    /// <summary> 
    /// Represents an access to a remote process memory 
    /// </summary> 
    public class Memory : IDisposable 
    { 
     private Process process; 
     private IntPtr processHandle; 
     private bool isDisposed; 

     public const string OffsetPattern = "(\\+|\\-){0,1}(0x){0,1}[a-fA-F0-9]{1,}"; 

     /// <summary> 
     /// Initializes a new instance of the Memory 
     /// </summary> 
     /// <param name="process">Remote process</param> 
     public Memory(Process process) 
     { 
      if (process == null) 
       throw new ArgumentNullException("process"); 

      this.process = process; 
      processHandle = Win32.OpenProcess(
       Win32.ProcessAccessType.PROCESS_VM_READ | Win32.ProcessAccessType.PROCESS_VM_WRITE | 
       Win32.ProcessAccessType.PROCESS_VM_OPERATION, true, (uint)process.Id); 
      if (processHandle == IntPtr.Zero) 
       throw new InvalidOperationException("Could not open the process"); 
     } 

     #region IDisposable 

     ~Memory() 
     { 
      Dispose(false); 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     private void Dispose(bool disposing) 
     { 
      if (isDisposed) 
       return; 
      Win32.CloseHandle(processHandle); 
      process = null; 
      processHandle = IntPtr.Zero; 
      isDisposed = true; 
     } 

     #endregion 

     #region Properties 

     /// <summary> 
     /// Gets the process to which this memory is attached to 
     /// </summary> 
     public Process Process 
     { 
      get 
      { 
       return process; 
      } 
     } 

     #endregion 

     /// <summary> 
     /// Finds module with the given name 
     /// </summary> 
     /// <param name="name">Module name</param> 
     /// <returns></returns> 
     protected ProcessModule FindModule(string name) 
     { 
      if (string.IsNullOrEmpty(name)) 
       throw new ArgumentNullException("name"); 
      foreach (ProcessModule module in process.Modules) 
      { 
       if (module.ModuleName.ToLower() == name.ToLower()) 
        return module; 
      } 
      return null; 
     } 

     /// <summary> 
     /// Gets module based address 
     /// </summary> 
     /// <param name="moduleName">Module name</param> 
     /// <param name="baseAddress">Base address</param> 
     /// <param name="offsets">Collection of offsets</param> 
     /// <returns></returns> 
     public IntPtr GetAddress(string moduleName, IntPtr baseAddress, int[] offsets) 
     { 
      if (string.IsNullOrEmpty(moduleName)) 
       throw new ArgumentNullException("moduleName"); 

      ProcessModule module = FindModule(moduleName); 
      if (module == null) 
       return IntPtr.Zero; 
      else 
      { 
       int address = module.BaseAddress.ToInt32() + baseAddress.ToInt32(); 
       return GetAddress((IntPtr)address, offsets); 
      } 
     } 

     /// <summary> 
     /// Gets address 
     /// </summary> 
     /// <param name="baseAddress">Base address</param> 
     /// <param name="offsets">Collection of offsets</param> 
     /// <returns></returns> 
     public IntPtr GetAddress(IntPtr baseAddress, int[] offsets) 
     { 
      if (baseAddress == IntPtr.Zero) 
       throw new ArgumentException("Invalid base address"); 

      int address = baseAddress.ToInt32(); 

      if (offsets != null && offsets.Length > 0) 
      { 
       byte[] buffer = new byte[4]; 
       foreach (int offset in offsets) 
        address = ReadInt32((IntPtr)address) + offset; 
      } 

      return (IntPtr)address; 
     } 

     /// <summary> 
     /// Gets address pointer 
     /// </summary> 
     /// <param name="address">Address</param> 
     /// <returns></returns> 
     public IntPtr GetAddress(string address) 
     { 
      if (string.IsNullOrEmpty(address)) 
       throw new ArgumentNullException("address"); 

      string moduleName = null; 
      int index = address.IndexOf('"'); 
      if (index != -1) 
      { 
       // Module name at the beginning 
       int endIndex = address.IndexOf('"', index + 1); 
       if (endIndex == -1) 
        throw new ArgumentException("Invalid module name. Could not find matching \""); 
       moduleName = address.Substring(index + 1, endIndex - 1); 
       address = address.Substring(endIndex + 1); 
      } 

      int[] offsets = GetAddressOffsets(address); 
      int[] _offsets = null; 
      IntPtr baseAddress = offsets != null && offsets.Length > 0 ? 
       (IntPtr)offsets[0] : IntPtr.Zero; 
      if (offsets != null && offsets.Length > 1) 
      { 
       _offsets = new int[offsets.Length - 1]; 
       for (int i = 0; i < offsets.Length - 1; i++) 
        _offsets[i] = offsets[i + 1]; 
      } 

      if (moduleName != null) 
       return GetAddress(moduleName, baseAddress, _offsets); 
      else 
       return GetAddress(baseAddress, _offsets); 
     } 

     /// <summary> 
     /// Gets address offsets 
     /// </summary> 
     /// <param name="address">Address</param> 
     /// <returns></returns> 
     protected static int[] GetAddressOffsets(string address) 
     { 
      if (string.IsNullOrEmpty(address)) 
       return new int[0]; 
      else 
      { 
       MatchCollection matches = Regex.Matches(address, OffsetPattern); 
       int[] offsets = new int[matches.Count]; 
       string value; 
       char ch; 
       for (int i = 0; i < matches.Count; i++) 
       { 
        ch = matches[i].Value[0]; 
        if (ch == '+' || ch == '-') 
         value = matches[i].Value.Substring(1); 
        else 
         value = matches[i].Value; 
        offsets[i] = Convert.ToInt32(value, 16); 
        if (ch == '-') 
         offsets[i] = -offsets[i]; 
       } 
       return offsets; 
      } 
     } 

     /// <summary> 
     /// Reads memory at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="buffer">Buffer</param> 
     /// <param name="size">Size in bytes</param> 
     public void ReadMemory(IntPtr address, byte[] buffer, int size) 
     { 
      if (isDisposed) 
       throw new ObjectDisposedException("Memory"); 
      if (buffer == null) 
       throw new ArgumentNullException("buffer"); 
      if (size <= 0) 
       throw new ArgumentException("Size must be greater than zero"); 
      if (address == IntPtr.Zero) 
       throw new ArgumentException("Invalid address"); 

      uint read = 0; 
      if (!Win32.ReadProcessMemory(processHandle, address, buffer, (uint)size, ref read) || 
       read != size) 
       throw new AccessViolationException(); 
     } 

     /// <summary> 
     /// Writes memory at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="buffer">Buffer</param> 
     /// <param name="size">Size in bytes</param> 
     public void WriteMemory(IntPtr address, byte[] buffer, int size) 
     { 
      if (isDisposed) 
       throw new ObjectDisposedException("Memory"); 
      if (buffer == null) 
       throw new ArgumentNullException("buffer"); 
      if (size <= 0) 
       throw new ArgumentException("Size must be greater than zero"); 
      if (address == IntPtr.Zero) 
       throw new ArgumentException("Invalid address"); 

      uint write = 0; 
      if (!Win32.WriteProcessMemory(processHandle, address, buffer, (uint)size, ref write) || 
       write != size) 
       throw new AccessViolationException(); 
     } 

     /// <summary> 
     /// Reads 32 bit signed integer at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <returns></returns> 
     public int ReadInt32(IntPtr address) 
     { 
      byte[] buffer = new byte[4]; 
      ReadMemory(address, buffer, 4); 
      return BitConverter.ToInt32(buffer, 0); 
     } 

     /// <summary> 
     /// Reads 32 bit unsigned integer at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <returns></returns> 
     public uint ReadUInt32(IntPtr address) 
     { 
      byte[] buffer = new byte[4]; 
      ReadMemory(address, buffer, 4); 
      return BitConverter.ToUInt32(buffer, 0); 
     } 

     /// <summary> 
     /// Reads single precision value at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <returns></returns> 
     public float ReadFloat(IntPtr address) 
     { 
      byte[] buffer = new byte[4]; 
      ReadMemory(address, buffer, 4); 
      return BitConverter.ToSingle(buffer, 0); 
     } 

     /// <summary> 
     /// Reads double precision value at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <returns></returns> 
     public double ReadDouble(IntPtr address) 
     { 
      byte[] buffer = new byte[8]; 
      ReadMemory(address, buffer, 8); 
      return BitConverter.ToDouble(buffer, 0); 
     } 

     /// <summary> 
     /// Writes 32 bit unsigned integer at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="value">Value</param> 
     /// <returns></returns> 
     public void WriteUInt32(IntPtr address, uint value) 
     { 
      byte[] buffer = BitConverter.GetBytes(value); 
      WriteMemory(address, buffer, 4); 
     } 

     /// <summary> 
     /// Writes 32 bit signed integer at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="value">Value</param> 
     /// <returns></returns> 
     public void WriteInt32(IntPtr address, int value) 
     { 
      byte[] buffer = BitConverter.GetBytes(value); 
      WriteMemory(address, buffer, 4); 
     } 

     /// <summary> 
     /// Writes single precision value at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="value">Value</param> 
     /// <returns></returns> 
     public void WriteFloat(IntPtr address, float value) 
     { 
      byte[] buffer = BitConverter.GetBytes(value); 
      WriteMemory(address, buffer, 4); 
     } 

     /// <summary> 
     /// Writes double precision value at the address 
     /// </summary> 
     /// <param name="address">Memory address</param> 
     /// <param name="value">Value</param> 
     /// <returns></returns> 
     public void WriteDouble(IntPtr address, double value) 
     { 
      byte[] buffer = BitConverter.GetBytes(value); 
      WriteMemory(address, buffer, 8); 
     } 
    } 
} 

可悲的是我收到以下错误代码:

An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in System.dll 


Additional information: A 32-bit process can not access modules in a 64-bit process. 

这个错误应该引起通过以下行:memory.WriteUInt32(prestigeAddress, 1);

有谁知道我现在可以做什么,或者如果有这个问题的解决方案?或者我需要一个全新的内存处理类?

我希望任何形式的帮助

UPDATE

新的错误看起来像如下:

An unhandled exception of type 'System.OverflowException' occurred in mscorlib.dll 

Additional information: The arithmetic operation has caused an overflow. 

截图:https://gyazo.com/04107c28a4d7af0599f1dd59c72b6020

完整的日志:

System.OverflowException was unhandled 
    HResult=-2146233066 
    Message=The arithmetic operation caused an overflow. 
    Source=mscorlib 
    StackTrace: 
     at System.IntPtr.ToInt32() 
     at Infinite_Trainer___Cod_IW.CheatEngine.Memory.GetAddress(String moduleName, IntPtr baseAddress, Int32[] offsets) in C:\Users\d4ne\documents\visual studio 2015\Projects\Infinite Trainer - Cod IW\Infinite Trainer - Cod IW\CheatEngine\Memory.cs:Line 109. 
     at Infinite_Trainer___Cod_IW.Form1.bunifuFlatButton1_Click(Object sender, EventArgs e) in C:\Users\d4ne\documents\visual studio 2015\Projects\Infinite Trainer - Cod IW\Infinite Trainer - Cod IW\Form1.cs:Line 40. 
     at System.Windows.Forms.Control.OnClick(EventArgs e) 
     at System.Windows.Forms.Control.OnClick(EventArgs e) 
     at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.Label.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
     at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
     at Infinite_Trainer___Cod_IW.Program.Main() in C:\Users\d4ne\documents\visual studio 2015\Projects\Infinite Trainer - Cod IW\Infinite Trainer - Cod IW\Program.cs:Line 19. 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

回答

1

你可以看看这个32 bit process

可能是你的项目的目标是32而不是64位?

+0

'Memory'没有包含'WriteUInt64'的定义,也没有找到接受'Memory'类型的第一个参数的扩展方法'WriteUInt64'(你是否缺少using指令或程序集引用?)所以没有函数内部类似 – user2452165

+0

@ user2452165请查看更新后的答案。我认为这应该可以解决它 – peterpep

+0

https://gyazo.com/a444f47cf263e8c849435c6224c82e70检查其余 – user2452165