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