Ingmar05 Ingmar05 - 4 years ago 216
C# Question

How to read process memory with Base adress and Pointers

I have been working on a small project - I am trying to create a C# program that will read the character's HP from a game "League Of Legends".

I did some research and after some time messing around with cheatengine, I got the offsets that will point to the HP's address even after restarting the PC, and I can successfully read it every time.

CE

Now I wanted to make a program that would do the same thing. I found a Class that I could read the float's from memory with, called VAMemory. I copypasted the static address from Cheatengine to my program and got the HP value, like I wanted.

VAMemory vam = new VAMemory("League Of Legends");
vam.ReadFloat((IntPtr)adress);


But this does not work after restarting the game, so I would have to get the address from Cheatengine again.

I found a similar question and the answer said:


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.


In this question, the asker had 2 offsets, but I have 5?

Used this to get the base address:

Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault();
IntPtr BaseAddress = GameProcess.MainModule.BaseAddress;


So then I created this monstrosity:

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);
}
}



  • It takes the base address, adds the first offset, [reads the value, adds next]x5 and then reads the last address, but unfortunately its value is 0.



Instead of the beautiful numbers in Cheatengine I got this:numbers
I have been messing with this thing for a long time, but I still don't understand what I am doing wrong?

How can I get the dynamic address from the base address and Pointers?

UPDATE:

I am now using new pointers:
new pointers

And I changed the code according to the comments,
It Uses Readint32() instead of readfloat() and looks much cleaner:

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();


BUT, it still does not work. I ran Cheatengine simultaneously and it got the right address and value, but my program got these:
debug
and the final value is 0, it should be 528.

Answer Source

My orginal comment as an answer:

Your problem is you call vam.ReadFloat, on every level, you should only be calling ReadFloat once at the end, the in between levels need to be using vam.ReadInt32( to get the next layer down.

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();

The problem with your updated answer is you have a typo.

float value = vam.ReadFloat(Base4);

should be

float value = vam.ReadFloat(Base5);

Also, I was not familiar with Cheat Engine's UI but it appears you are doing the things in reverse, 0xBC should be the offset of the first value and 0x58 should be the amount you add to the last value.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download