Hrm, I'm not sure about the specifics of whatever language that is you're using (Delphi?) but it sounds like perhaps when you're reading 800 bytes, sometimes your program wanders into unallocated or protected address space.
I used to use a function which manually read a string in small chunks until it found a unicode termination (0x00, 0x00).
It's a bit slower, but I found it was a lot more reliable for some of the things I was reading in.
Here's a snippet - It actually had an option for double terminator (e.g., two bytes of 0x00) or triple (three bytes of 0x00) because it was actually possible to have two 0x00 bytes in the chat box text which wasn't actually a terminator!
You should be able to disregard that part though and just look for double termination.
This isn't a particularly elegant piece of code. There may well be a single line solution in your programming language. Maybe someone else here can help?
Code:
// This one will be a bit slower, but will hopefully eliminate returning empty strings where
// the address + size is not in accessible memory, resulting in a failure from ReadProcessMemory.
// Bytes are read in chunks of [chunkSize] size and chunks are scanned for 0x00, 0x00 (i.e.,
// end of string). If this is not found, we read another chunk, repeating until the string
// terminator is found.
// This might also help with reading enormous strings (e.g., complete chat listing) until I find
// a better solution for working around the maximum memory size that can be read
public static string MemReadUnicodeToEnd(IntPtr processHandle, uint address, uint maxSize, uint chunkSize, ref uint _bytesRead, bool doubleTerminator = false)
{
bool success;
byte[] buffer = new byte[chunkSize];
byte[] bigString = new byte[maxSize];
UInt32 nBytesRead = 0;
bool exit = false;
uint i, j, currLength = 0;
do
{
success = ReadProcessMemory(processHandle, (IntPtr)(address + currLength), buffer, chunkSize, ref nBytesRead);
_bytesRead = nBytesRead;
System.Buffer.BlockCopy(buffer, 0, bigString, (int)currLength, (int)chunkSize);
currLength += chunkSize;
if (!doubleTerminator)
{
for (i = 0, j = chunkSize - 2; i < j; i++)
{
if (buffer[i] == 0 && buffer[i + 1] == 0)
{
// We found the string terminator
exit = true;
break;
}
}
}
else // Full chat listing can contain more than two consecutive 0x00 bytes because of item links.
{
for (i = 0, j = chunkSize - 3; i < j; i++)
{
if (buffer[i] == 0 && buffer[i + 1] == 0 && buffer[i + 2] == 0)
{
// We found the string terminator
exit = true;
break;
}
}
}
} while (!exit && currLength < maxSize);
_bytesRead = currLength - chunkSize + i;
return ByteArrayToString(bigString, EncodingType.Unicode);
}