Reading a pointer to a string
var result = new StringBuilder();
for (var i = 0; i &lt; length; i++)
{
    result.Append((char)Marshal.ReadByte(startStr, i));
}



You're working in a tight loop: a StringBuilder looks like a reasonable tool to use.

One thing I would change that could impact performance (depending on the length of the string involved), is the StringBuilder constructor being used:

var result = new StringBuilder(length);


There's no reason not to specify the length of the string you're building if you know it from the start; that will reduce the overhead, since the internals of the builder won't need to manage growth.



The loop is a one-liner. You have this one-liner just a few instructions above:


if (capacity &gt; 15)
    startStr = (IntPtr)Marshal.ReadInt32(address + 4);



Why does the loop have an explicit { } scope, but not the if block? It would be better to be consistent about scoping braces, and have them everywhere:

 if (capacity &gt; 15)
 {
     startStr = (IntPtr)Marshal.ReadInt32(address + 4);
 }




An alternative to the StringBuilder could be to write the bytes into a MemoryStream:

using (var stream = new MemoryStream(length))
{
    for (var i = 0; i &lt; length; i++)
    {
        stream.WriteByte(Marshal.ReadByte(startStr, i));
    }
    return new StreamReader(stream).ReadToEnd();
}


The nice thing with this approach is that you don't need to cast every single byte of the string into a char. On the other hand, you need 2 objects instead of one, and you need to cleanly Dispose of the stream, too - depending on the length of the string, the overhead might just not be worth it, although my guts tell me the stream could be faster... but I think you'd need to race your horses to find out.