为何C#调用Mem类写FIFA22内存byte值不生效,Cheat Engine却可修改?
C#读写FIFA22内存失败问题排查方案
问题代码
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 Memory; namespace xFUT22 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public Mem m = new Mem(); private void form1_load(object sender, EventArgs e) { if (!backgroundWorker1.IsBusy) backgroundWorker1.RunWorkerAsync(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while (true) { int pID = m.GetProcIdFromName("FIFA22"); bool openProc = false; if (pID > 0) openProc = m.OpenProcess(pID); if (openProc) { if (TF.Checked) m.WriteMemory("0x143DD9FF9", "byte", "0x45"); else m.WriteMemory("0x143DD9FF9", "byte", "0x41"); } } } } }
故障原因及解决方法
- 跨线程访问UI控件异常
BackgroundWorker的DoWork事件运行在后台非UI线程,直接访问窗体上TF复选框的Checked属性会触发跨线程非法操作异常,该异常默认会被后台线程静默吞掉,导致后续写内存逻辑完全不执行。
解决方法:可以在Form构造函数中加入CheckForIllegalCrossThreadCalls = false;临时关闭跨线程检查,也可以通过Invoke委托的方式安全读取控件状态。 - 未修改只读内存页的保护属性
你要修改的内存页属性为只读+可执行,普通写入权限无法修改这类内存页。Cheat Engine写入前会自动调用VirtualProtectEx先将页保护修改为可读写,写入完成后再还原属性,你的当前代码缺少这步操作。
解决方法:调用Memory.dll自带的ChangeProtection方法先修改目标地址的页保护权限,再执行写入操作。 - 程序编译架构不匹配
FIFA22是64位程序,你要写入的地址0x143DD9FF9属于64位地址空间,如果你的C#程序编译时目标平台设置为x86(32位),就无法正常读写64位进程的高位内存地址。
解决方法:打开项目属性-生成页,将目标平台修改为x64,不要使用Any CPU选项。 - 程序未获取管理员权限
读写其他进程内存需要程序拥有管理员权限,如果你没有以管理员身份运行程序,OpenProcess即使返回成功,也没有实际的内存写入权限。
解决方法:右键程序选择「以管理员身份运行」,也可以在项目中添加app.manifest配置文件,将requestedExecutionLevel的level属性设置为requireAdministrator,让程序每次运行都自动请求管理员权限。
内容的提问来源于stack exchange,提问作者Lepis
相关产品推荐
相关产品推荐

