2

Ok so I am using the MemorySharp library to read/write the memory of a game. My problem is when I try to add the offsets to the base pointer address Visual Studio throws an error during runtime. Here is the base code

using (var m = new MemorySharp(ApplicationFinder.FromProcessName("Cube").First()))
{
    IntPtr healthPtr = GetBaseAddress("Cube") + 0x0036B1C8;
    int[] offsets = {0x39c, 0x16c};

foreach(var offset in offsets)
{
    healthPtr = m[healthPtr + offset].Read<IntPtr>(); //I'm getting the error on this line
}

var healthLocation = m[m[healthPtr].Read<IntPtr>()];
float health = healthLocation.Read<float>();
MessageBox.Show(health.ToString());
}

And here is my GetBaseAddress method

internal static IntPtr GetBaseAddress(string ProcessName)
{
    try
    {
        Process[] L2Process = Process.GetProcessesByName(ProcessName);
        return L2Process[0].MainModule.BaseAddress;
    }
    catch { return IntPtr.Zero; }
}

But when I run this Visual Studios throws me this error

"An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in MemorySharp.dll Additional information: The relative address cannot be greater than the main module size."

And it points to this line of code healthPtr = m[healthPtr + offset].Read<IntPtr>(); Not quite sure what I'm doing wrong here.

EDIT
Here is my updated code that's still not working

using (var m = new MemorySharp(ApplicationFinder.FromProcessName("Cube").First()))
{
    var healthPtr = new IntPtr(0x0036B1C8);
    int[] offsets = { 0x39c, 0x16c };
    healthPtr = m[healthPtr].Read<IntPtr>();

    foreach (var offset in offsets)
    {
        healthPtr = m[healthPtr + offset, false].Read<IntPtr>(); // false is here to avoid rebasing
    }

    float Health = m[healthPtr, false].Read<float>(); // false is here to avoid rebasing
    MessageBox.Show(Health.ToString());
}

EDIT ANSWER FOUND
I have to read the final pointer as the type I want. so with only 2 pointer I read pointer the 1st one then on the last one read it as the value like so

using (var m = new MemorySharp(ApplicationFinder.FromProcessName("Cube").First()))
{
    var healthPtr = new IntPtr(0x0036B1C8);
    int[] offsets = { 0x39C, 0x16C };
    healthPtr = m[healthPtr].Read<IntPtr>();

    healthPtr = m[healthPtr + offsets[0], false].Read<IntPtr>(); // false is here to avoid rebasing

    float Health = m[healthPtr + offsets[1],false].Read<float>();
    MessageBox.Show(Health.ToString());
}
Jämes
  • 6,945
  • 4
  • 40
  • 56
Bender Guy
  • 33
  • 1
  • 6

1 Answers1

1

First at all, using the indexer of the MemorySharp object already rebases the pointer to the base address of the main module of the process. So, you don't need to use your function GetBaseAddress and you can declare your pointer/offsets like this:

var healthPtr = new IntPtr(0x0036B1C8);
int[] offsets = { 0x39c, 0x16c };

Now read the value of the pointer

healthPtr = m[healthPtr].Read<IntPtr>(); // The pointer is automatically rebased

Browse the pointer chain using the offsets

foreach (var offset in offsets)
{
    healthPtr = m[healthPtr + offset, false].Read<IntPtr>(); // false is here to avoid rebasing
}

Note the second parameter set to false. It states that the address must not be rebased to the main module of the process.

Also, it's important to use the offsets after a first reading, else what is the purpose to declare an offset instead of directly add the value to the address. :)

I think the line setting the var healthLocation is not needed and will read unknown memory address. Are you sure you want to do that ?

This error:

"An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in MemorySharp.dll Additional information: The relative address cannot be greater than the main module size."

is thrown because MemorySharp already rebases the the pointer if you do not set the second parameter to false (as explained above).

Let me know if it's all right for you.

Jämes
  • 6,945
  • 4
  • 40
  • 56
  • Ok now it gets passed the loop but now when I try to read the float it throws the same error as before, I edited my question to show my current code – Bender Guy Sep 19 '13 at 01:16
  • Same as before, set the second parameter to false (you don't need to rebase the pointer) `float Health = m[healthPtr, false].Read();`. – Jämes Sep 19 '13 at 05:58
  • Ok after setting the 2nd param to false and tried it again I got "An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in MemorySharp.dll Additional information: Couldn't read 4 byte(s) from 0x3F800000." Now I'm really confused haha, thought that would have been the last error, and yes it's happening on the same line – Bender Guy Sep 19 '13 at 07:30
  • Check that all the pointer levels are correct and also check if there is something at the location `0x3F800000` using a tool like CheatEngine. – Jämes Sep 19 '13 at 07:44
  • Ok So I found the issue but don't know how to fix it, I added the address stuff into cheat engine to track the addresses and used a message box in visual studio to relay the changed addresses. After it adds 0x39C and points to the correct address (16ECD168) and then when it adds 0x16C it's supposed to go to (16ECD2D4) but instead it goes to (3F800000) it screws up when adding 16C to the pointer. Why's that? – Bender Guy Sep 19 '13 at 07:45
  • This is because I suspect the value `0x3F800000` is located at `0x16ECD2D4`, right ? If the pointer `0x16ECD2D4` is your "end-pointer", you can directly read its value as float. – Jämes Sep 19 '13 at 07:55
  • Great! Really happy you could finally read your value from another process. :) – Jämes Sep 19 '13 at 08:10
  • One laaaast question if you don't mind :), using my current code how would I write to the value? I tried `HealthPtr.Write(Health)` but HealthPtr is of type `IntPtr` – Bender Guy Sep 19 '13 at 08:13
  • Simply by using the `IntPtr` in the indexer of your object : `m[HealthPtr, false].Write(Health);`. – Jämes Sep 19 '13 at 08:18
  • In the above code where I defined `float Health` I added `m[healthPtr, false].Write(Health);` but it didn't work /: I'm so confused. Do I need to add the last offset and then write the value? – Bender Guy Sep 19 '13 at 08:23