ReadProcessMemory Returning False After Many Calls

243 views Asked by At

I have created a function to allow me to ask for a generic type in return from a pointer in memory with the currently opened process.

public static T ReadValue<T>(this IntPtr ptr, int length = 0)
    {
        Type valT = typeof(T);
        byte[] buffer = length > 0 ? new byte[length] : new byte[Marshal.SizeOf(valT)];
        IntPtr retBytes;
        object result;

        if (!ReadProcessMemory(CurrentProcessHandle, ptr, buffer, buffer.Length, out retBytes))
            return default(T);

        Console.WriteLine(ptr);

        if (valT == typeof(byte))
            result = buffer[0];
        else if (valT == typeof(bool))
            result = buffer[0] > 0;
        else if (valT == typeof(char))
            result = BitConverter.ToChar(buffer, 0);
        else if (valT == typeof(double))
            result = BitConverter.ToDouble(buffer, 0);
        else if (valT == typeof(float))
            result = BitConverter.ToSingle(buffer, 0);
        else if (valT == typeof(int))
            result = BitConverter.ToInt32(buffer, 0);
        else if (valT == typeof(long))
            result = BitConverter.ToInt64(buffer, 0);
        else if (valT == typeof(object))
            result = buffer;
        else if (valT == typeof(short))
            result = BitConverter.ToInt16(buffer, 0);
        else if (valT == typeof(string))
            result = Encoding.Default.GetString(buffer);
        else if (valT == typeof(uint))
            result = BitConverter.ToUInt32(buffer, 0);
        else if (valT == typeof(ulong))
            result = BitConverter.ToUInt64(buffer, 0);
        else if (valT == typeof(ushort))
            result = BitConverter.ToUInt16(buffer, 0);
        else
        {
            IntPtr newVal = Marshal.AllocHGlobal(buffer.Length);
            Marshal.Copy(buffer, 0, newVal, buffer.Length);
            result = newVal;
            Marshal.FreeHGlobal(newVal);
        }

        return (T) result;
    }

What is happening is that after ~39600 calls, ReadProcessMemory begins to return false in 100% of calls following. At first I assumed that this was IntPtr being allocated improperly before being copied and free'd; however, after removing the IntPtr default, the issue still persisted. What is causing this to return false after being called so many times?

Additional Coding Information:

The object that's calling the ReadValue.

public GameObject(IntPtr baseAddress) : this()
{
    BaseAddress = baseAddress;
    Update();
}

public void Update()
{
    Index = (BaseAddress + 0x8).ReadValue<ushort>();
}

public GameObject GetObjectFromIndex(int index)
{
    //GetPointer will return a pointer at the specified address (objectManagerStart + (index * 4))
    IntPtr pointer = HelperProcess.GetPointer(objectManagerStart + (index * 4), 4);
    return pointer == IntPtr.Zero ? new GameObject().Default() : new GameObject(pointer);
}

And the code where I am assigning the IntPtr:

GameObject player = new GameObject().GetObjectFromIndex(1805);
1

There are 1 answers

0
Approved On

The function was throwing Error Code (0x6) which was Invalid Handle. Apparently the module's handle was changing, so my pointers were no longer correct. I fixed this by wrapping the function in a while loop with a timeout. If the current itteration of the function is less than the timeout, then try and get the handle again, before proceeding to read from memory.