MemorySharp setting offset to an address not worki

2019-04-14 09:41发布

问题:

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

回答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.