如何使用基地址和指针读取进程内存
How to read process memory with Base adress and Pointers
我一直在做一个小项目 - 我正在尝试创建一个 C# 程序来读取游戏中角色的 HP "League Of Legends"。
我做了一些研究,在 cheatengine 上搞了一段时间后,即使在重新启动 PC 后,我也得到了指向 HP 地址的偏移量,而且我每次都能成功读取它。
现在我想制作一个可以做同样事情的程序。我找到了一个 Class,我可以用它从内存中读取浮点数,叫做 VAMemory。我将 Cheatengine 的静态地址复制粘贴到我的程序并获得了 HP 值,就像我想要的那样。
VAMemory vam = new VAMemory("League Of Legends");
vam.ReadFloat((IntPtr)adress);
但是重启游戏后就不行了,只能从Cheatengine重新获取地址了
我找到了一个类似的question,答案是:
For each level you have to read the memory and see what is stored at the address. The value you find will be your next address, to which you apply your next offset, and so on.
这道题提问者有2个offset,我有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得到动态地址?
更新:
我现在正在使用新指针:
然后我根据评论修改了代码,
它使用 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.
我的原始评论作为回答:
你的问题是你调用了vam.ReadFloat
,在每个级别上,你应该只在最后调用一次ReadFloat
,中间级别需要使用vam.ReadInt32(
来获得下一层。
Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
VAMemory vam = new VAMemory("League Of Legends");
IntPtr Base = GameProcess.MainModule.BaseAddress;
IntPtr BaseFirst = IntPtr.Add((IntPtr)vam.ReadInt32(Base), 0x658);
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);
Lvalue.Text = Basefifthvalue.ToString();
您更新后的答案的问题是您打错了字。
float value = vam.ReadFloat(Base4);
应该是
float value = vam.ReadFloat(Base5);
此外,我对 Cheat Engine 的 UI 不熟悉,但看起来你在做相反的事情,0xBC
应该是第一个值的偏移量,0x58
应该是您添加到最后一个值的金额。
我一直在做一个小项目 - 我正在尝试创建一个 C# 程序来读取游戏中角色的 HP "League Of Legends"。
我做了一些研究,在 cheatengine 上搞了一段时间后,即使在重新启动 PC 后,我也得到了指向 HP 地址的偏移量,而且我每次都能成功读取它。
现在我想制作一个可以做同样事情的程序。我找到了一个 Class,我可以用它从内存中读取浮点数,叫做 VAMemory。我将 Cheatengine 的静态地址复制粘贴到我的程序并获得了 HP 值,就像我想要的那样。
VAMemory vam = new VAMemory("League Of Legends");
vam.ReadFloat((IntPtr)adress);
但是重启游戏后就不行了,只能从Cheatengine重新获取地址了
我找到了一个类似的question,答案是:
For each level you have to read the memory and see what is stored at the address. The value you find will be your next address, to which you apply your next offset, and so on.
这道题提问者有2个offset,我有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得到动态地址?
更新:
我现在正在使用新指针:
然后我根据评论修改了代码, 它使用 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 它得到了正确的地址和值,但我的程序得到了这些:
我的原始评论作为回答:
你的问题是你调用了vam.ReadFloat
,在每个级别上,你应该只在最后调用一次ReadFloat
,中间级别需要使用vam.ReadInt32(
来获得下一层。
Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
VAMemory vam = new VAMemory("League Of Legends");
IntPtr Base = GameProcess.MainModule.BaseAddress;
IntPtr BaseFirst = IntPtr.Add((IntPtr)vam.ReadInt32(Base), 0x658);
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);
Lvalue.Text = Basefifthvalue.ToString();
您更新后的答案的问题是您打错了字。
float value = vam.ReadFloat(Base4);
应该是
float value = vam.ReadFloat(Base5);
此外,我对 Cheat Engine 的 UI 不熟悉,但看起来你在做相反的事情,0xBC
应该是第一个值的偏移量,0x58
应该是您添加到最后一个值的金额。