【问题标题】:How to read process memory with Base adress and Pointers如何使用基地址和指针读取进程内存
【发布时间】: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


【解决方案1】:

我的原始评论作为答案:

你的问题是你调用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 应该是你添加到最后一个值的数量。

【讨论】:

    猜你喜欢
    • 2020-04-30
    • 2015-07-09
    • 1970-01-01
    • 2016-12-30
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多