private static byte[] ReadBuffer(ClrHeap heap, ulong address, int length) { byte[] buffer = new byte[length]; int byteRead = heap.ReadMemory(address, buffer, 0, buffer.Length); return(byteRead != length ? throw new InvalidOperationException(string.Format("Expected to read {0} bytes and actually read {1}", length, byteRead)) : buffer); }
private object MarshalToStruct(ulong address, Type destinationType, ClrType destinationClrType) { var buffer = new byte[destinationClrType.BaseSize]; _heap.ReadMemory(address, buffer, 0, buffer.Length); var method = GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Static).First(m => m.Name == "Read").MakeGenericMethod(destinationType); return(method.Invoke(null, new object[] { buffer })); }
private bool ReadMemory(out string error) { error = null; try { _heap.ReadMemory(_currentAddr, _bytes, 0, _byteBufSize); return(true); } catch (Exception ex) { error = Utils.GetExceptionErrorString(ex); return(false); } }
/// <summary> /// Read 'count' bytes from the ClrHeap at 'address' placing it in 'buffer' starting at offset 'offset' /// </summary> /// <param name="address">The address.</param> /// <param name="buffer">The buffer.</param> /// <param name="offset">The offset.</param> /// <param name="count">The count.</param> /// <returns>System.Int32.</returns> /// <inheritdoc /> public int ReadMemory(ulong address, byte[] buffer, int offset, int count) => Heap.ReadMemory(address, buffer, offset, count);
public static string ReadStringSafe(ClrHeap heap, ulong strAddress, int maxCharLimit = 3000) { if (strAddress == 0) { return(TextConstants.NullReferenceString); } ulong ps = (ulong)heap.PointerSize; byte[] stringLengthBuffer = EnsureThreadStaticSufficientSize(sizeof(Int32), ref stringLenBuffer); var strLengAddress = strAddress + ps; // Get length of string var bytesReadTotal = heap.ReadMemory(strLengAddress, stringLengthBuffer, 0, sizeof(Int32)); int len = 0; for (int i = bytesReadTotal - 1; i >= 0; i--) { len = len << 8; len += stringLengthBuffer[i]; } if (len == 0) { return(string.Empty); } if (len < 0) { return("[CorruptedString] " + strAddress.ToString("x8")); } var maxBytesToRead = Math.Min(len, maxCharLimit) * 2; var readBatchSize = Math.Min(4096, maxBytesToRead); var dataStart = strLengAddress + sizeof(Int32); // Copy to local value var readCharBuffer = EnsureThreadStaticSufficientSize(maxBytesToRead, ref WholeStringByteBuffer); int lastReadAdded = 0; bytesReadTotal = 0; var readBuffer = EnsureThreadStaticSufficientSize(readBatchSize, ref StringReadBatchSizeBuffer); while (bytesReadTotal < maxBytesToRead) { var readBytes = heap.ReadMemory(dataStart, readBuffer, 0, readBatchSize); if (readBytes >= 2) { for (int i = 0; i < readBytes - 1; i += 2) { if ((readBuffer[i] | readBuffer[i + 1]) == 0) { // 'End of line is met' // We are not near the end, thus string length is different from actual one. // lets return return("[CorruptedString] " + strAddress.ToString("x8")); return(Encoding.Unicode.GetString(readCharBuffer.TakeWhile(t => t != 0).ToArray())); } readCharBuffer[lastReadAdded++] = readBuffer[i]; readCharBuffer[lastReadAdded++] = readBuffer[i + 1]; } } bytesReadTotal += readBytes; readBatchSize = Math.Min(4096, maxBytesToRead - bytesReadTotal); if (readBatchSize <= 0) { return(Encoding.Unicode.GetString(readCharBuffer, 0, maxBytesToRead)); } dataStart += (ulong)readBytes; } var str = Encoding.Unicode.GetString(readCharBuffer, 0, maxBytesToRead); return(str); }