示例#1
0
        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);
        }
示例#2
0
        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 }));
        }
示例#3
0
 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);
     }
 }
示例#4
0
 /// <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);
        }