【发布时间】:2017-05-16 03:01:30
【问题描述】:
我一直在做一个小项目 - 我正在尝试创建一个 C# 程序,该程序将从“英雄联盟”游戏中读取角色的 HP。
我做了一些研究,在使用cheatengine一段时间后,我得到了即使在重新启动PC后也会指向HP地址的偏移量,并且每次都能成功读取。
现在我想制作一个可以做同样事情的程序。我找到了一个可以从内存中读取浮点数的类,称为VAMemory。我将 Cheatengine 中的静态地址复制粘贴到我的程序中,并得到了我想要的 HP 值。
VAMemory vam = new VAMemory("League Of Legends");
vam.ReadFloat((IntPtr)adress);
但是重启游戏后就不行了,我得重新从Cheatengine获取地址。
我找到了一个类似的question,答案是:
对于每个级别,您都必须读取内存并查看地址中存储的内容。您找到的值将是您的下一个地址,您将在该地址上应用您的下一个偏移量,依此类推。
在这个问题中,提问者有 2 个偏移量,但我有 5 个?
用这个来获取基地址:
Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
IntPtr BaseAddress = GameProcess.MainModule.BaseAddress;
然后我创造了这个怪物:
try
{
Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
VAMemory vam = new VAMemory("League Of Legends");
IntPtr BaseAddress = GameProcess.MainModule.BaseAddress;
float Basevalue = vam.ReadFloat((IntPtr)BaseAddress);
abase.Text = BaseAddress.ToString();
vbase.Text = Basevalue.ToString();
IntPtr Basefirst = IntPtr.Add(BaseAddress, 0x658);
float Basefirstvalue = vam.ReadFloat((IntPtr)Basefirst);
a1.Text = Basefirst.ToString();
v1.Text = Basefirstvalue.ToString();
IntPtr Basesecond = IntPtr.Add(IntPtrFromFloat(Basefirstvalue), 0x150);
float Basesecondvalue = vam.ReadFloat((IntPtr)Basefirstvalue);
a2.Text = Basesecond.ToString();
v2.Text = Basesecondvalue.ToString();
IntPtr Basethird = IntPtr.Add(IntPtrFromFloat(Basesecondvalue), 0x0);
float Basethirdvalue = vam.ReadFloat((IntPtr)Basethird);
a3.Text = Basethird.ToString();
v3.Text = Basethirdvalue.ToString();
IntPtr Basefourth = IntPtr.Add(IntPtrFromFloat(Basethirdvalue), 0x44);
float Basefourthvalue = vam.ReadFloat((IntPtr)Basefourth);
a4.Text = Basefourth.ToString();
v4.Text = Basefourthvalue.ToString();
IntPtr Basefifth = IntPtr.Add(IntPtrFromFloat(Basefourthvalue), 0x36c);
float Basefifthvalue = vam.ReadFloat((IntPtr)Basefirst);
a5.Text = Basefifth.ToString();
v5.Text = Basefifthvalue.ToString();
}
catch (Exception ex)
{ MessageBox.Show(ex.ToString()); }
}
static IntPtr IntPtrFromFloat(float f)
{
unsafe
{
return (*(IntPtr*)&f);
}
}
- 它取基地址,加上第一个偏移量,[读取值,加上下一个]x5然后读取最后一个地址,可惜它的值是0。
我得到的不是 Cheatengine 中漂亮的数字: 搞了这个东西好久了,还是不明白自己做错了什么?
如何从基地址和Pointers获取动态地址?
更新:
而且我根据cmets改了代码, 它使用 Readint32() 而不是 readfloat() 并且看起来更干净:
Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
VAMemory vam = new VAMemory("League Of Legends");
IntPtr BaseAddress = GameProcess.MainModule.BaseAddress;
IntPtr Base1 = IntPtr.Add((IntPtr)vam.ReadInt32(BaseAddress), 0x58);
IntPtr Base2 = IntPtr.Add((IntPtr)vam.ReadInt32(Base1), 0xC0);
IntPtr Base3 = IntPtr.Add((IntPtr)vam.ReadInt32(Base2), 0x118);
IntPtr Base4 = IntPtr.Add((IntPtr)vam.ReadInt32(Base3), 0x39C);
IntPtr Base5 = IntPtr.Add((IntPtr)vam.ReadInt32(Base4), 0xBC);
float value = vam.ReadFloat(Base4);
Lvalue.Text = value.ToString();
但是,它仍然不起作用。我同时运行了 Cheatengine,它得到了正确的地址和值,但我的程序得到了这些: 最终值为0,应该是528。
【问题讨论】:
-
不要将代码作为指向 Pastebin 的链接,将其放在问题本身中。人们无需点击外部链接即可完全理解您的问题。
-
话虽如此,您的问题是您调用
vam.ReadFloat,在每个级别上,您应该只在最后调用一次ReadFloat,中间级别需要使用vam.ReadInt32(才能获得下一个下层。每个级别应该看起来像IntPtr Basesecond = IntPtr.Add((IntPtr)vam.ReadInt32(Basefirst), 0x150); -
IntPtr Basethird = IntPtr.Add((IntPtr)vam.ReadInt32(Basesecond), 0x0);,IntPtr Basefourth = IntPtr.Add((IntPtr)vam.ReadInt32(Basethird), 0x44);,IntPtr Basefifth = IntPtr.Add((IntPtr)vam.ReadInt32(Basefourth), 0x36c);,float Basefifthvalue = vam.ReadFloat(Basefifth);
标签: c# memory memory-address