Ejemplo n.º 1
0
        /// <summary>
        /// Gets the given object reference field from this ClrObject.  Throws ArgumentException if the given field does
        /// not exist in the object.  Throws NullReferenceException if IsNull is true.
        /// </summary>
        /// <param name="fieldName">The name of the field to retrieve.</param>
        /// <returns>A ClrObject of the given field.</returns>
        public ClrObject GetObjectField(string fieldName)
        {
            ClrInstanceField field = _type.GetFieldByName(fieldName);

            if (field == null)
            {
                throw new ArgumentException(String.Format("Type '{0}' does not contain a field named '{1}'", _type.Name, fieldName));
            }

            if (!field.IsObjectReference)
            {
                throw new ArgumentException(String.Format("Field '{0}.{1}' is not an object reference.", _type.Name, fieldName));
            }

            ClrHeap heap = _type.Heap;

            ulong addr = field.GetAddress(_address, _interior);
            ulong obj;

            if (!heap.ReadPointer(addr, out obj))
            {
                throw new MemoryReadException(addr);
            }

            ClrType type = heap.GetObjectType(obj);

            return(new ClrObject(obj, type));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the given object reference field from this ClrObject.  Throws ArgumentException if the given field does
        /// not exist in the object.  Throws NullReferenceException if IsNull is true.
        /// </summary>
        /// <param name="fieldName">The name of the field to retrieve.</param>
        /// <returns>A ClrObject of the given field.</returns>
        public ClrObject GetObject(string fieldName)
        {
            if (IsNull)
            {
                throw new NullReferenceException();
            }

            ClrInstanceField field = _type.GetFieldByName(fieldName);

            if (field == null)
            {
                throw new ArgumentException($"Type '{_type.Name}' does not contain a field named '{fieldName}'");
            }

            if (!field.IsObjectReference)
            {
                throw new ArgumentException($"Field '{_type.Name}.{fieldName}' is not an object reference.");
            }

            ClrHeap heap = _type.Heap;

            ulong addr = field.GetAddress(_address);
            ulong obj;

            if (!heap.ReadPointer(addr, out obj))
            {
                throw new MemoryReadException(addr);
            }

            ClrType type = heap.GetObjectType(obj);

            return(new ClrObject(obj, type));
        }
Ejemplo n.º 3
0
        private ulong GetFieldAddress(string fieldName, ClrElementType element, string typeName, out ClrType type)
        {
            if (IsNull)
            {
                throw new NullReferenceException();
            }

            type = Type;
            ClrInstanceField field = type.GetFieldByName(fieldName);

            if (field == null)
            {
                throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'");
            }

            if (field.ElementType != element)
            {
                throw new InvalidOperationException($"Field '{type.Name}.{fieldName}' is not of type '{typeName}'.");
            }

            ulong address = ClrRuntime.IsObjectReference(ElementType) ? Object : Address;

            address = field.GetAddress(address, Interior);
            return(address);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets an unsigned pointer field from the object.  Note that the type must match exactly, as this method
        /// will not do type coercion.  This method will throw an ArgumentException if no field matches
        /// the given name.  It will throw a NullReferenceException if the target object is null (that is,
        /// if (IsNull returns true).  It will throw an InvalidOperationException if the field is not
        /// of the correct type.  Lastly, it will throw a MemoryReadException if there was an error reading
        /// the value of this field out of the data target.
        /// </summary>
        /// <param name="fieldName">The name of the field to get the value for.</param>
        /// <returns>The value of the given field.</returns>
        public UIntPtr GetUIntPtr(string fieldName)
        {
            ClrType          type  = Type;
            ClrInstanceField field = type.GetFieldByName(fieldName);

            if (field == null)
            {
                throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'");
            }

            if (field.ElementType != ClrElementType.NativeUInt && field.ElementType != ClrElementType.Pointer && field.ElementType != ClrElementType.FunctionPointer)
            {
                throw new InvalidOperationException($"Field '{type.Name}.{fieldName}' is not a pointer.");
            }

            if (IsNull)
            {
                throw new NullReferenceException();
            }

            ulong address = field.GetAddress(Address);
            ulong value;

            if (!((RuntimeBase)type.Heap.Runtime).ReadPointer(address, out value))
            {
                throw new MemoryReadException(address);
            }

            return(new UIntPtr((ulong)value));
        }
        /// <summary>
        /// Gets the field value from <see cref="IAddressableTypedEntity"/> with respect to field nature (either reference, or value type).
        /// </summary>
        /// <param name="entity">The entity to read field value from.</param>
        /// <param name="fieldName">The name of the field to get value.</param>
        /// <exception cref="ArgumentNullException">if entity has no type.</exception>
        /// <exception cref="ArgumentException">Thrown when field with matching name was not found.</exception>
        /// <returns></returns>
        public static IAddressableTypedEntity GetFieldFrom(this IAddressableTypedEntity entity, string fieldName)
        {
            ClrType entityType = entity?.Type ?? throw new ArgumentNullException(nameof(entity), "No associated type");

            ClrInstanceField field = entityType.GetFieldByName(fieldName) ?? throw new ArgumentException($"Type '{entityType}' does not contain a field named '{fieldName}'");

            return(field.IsObjectReference ? (IAddressableTypedEntity)entity.GetObjectField(fieldName) : entity.GetValueClassField(fieldName));
        }
Ejemplo n.º 6
0
        private static string ReadString(ClrType stringType, ulong stringAddress)
        {
            ClrInstanceField lengthField = stringType.GetFieldByName("m_stringLength");
            if (lengthField == null)
                return String.Empty;

            var stringLength = (int)lengthField.GetFieldValue(stringAddress);
            if (stringLength <= 0)
                return String.Empty;

            var content = new byte[stringLength * 2];
            int bytesRead;
            stringType.Heap.GetRuntime().ReadVirtual(stringAddress + 12, content, stringLength * 2, out bytesRead);
            return System.Text.Encoding.Unicode.GetString(content);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Retrieves a field from this value.
        /// </summary>
        /// <param name="name">The name of the field.</param>
        /// <returns>A ClrValue representing this field.</returns>
        public virtual ClrValue GetField(string name)
        {
            ClrElementType el = ElementType;

            if (ClrRuntime.IsPrimitive(el))
            {
                // Primitives only have one field, named m_value.
                if (name != "m_value")
                {
                    throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name));
                }

                // Getting m_value is the same as this ClrValue...
                return(this);
            }

            if (ClrRuntime.IsObjectReference(el) || !Interior)
            {
                return(AsObject().GetField(name));
            }

            Debug.Assert(ClrRuntime.IsValueClass(el));

            ulong address = Address;

            if (address == 0)
            {
                throw new NullReferenceException();
            }

            ClrType          type  = Type;
            ClrInstanceField field = type.GetFieldByName(name);

            if (field == null)
            {
                throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name));
            }

            ulong result = field.GetAddress(address, Interior);

            return(new ClrValueImpl(_runtime, result, field));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gets the given object reference field from this ClrObject.
        /// </summary>
        /// <param name="fieldName">The name of the field to retrieve.</param>
        /// <returns>A ClrObject of the given field.</returns>
        /// <exception cref="ArgumentException">
        /// The given field does not exist in the object.
        /// -or-
        /// The given field was not an object reference.
        /// </exception>
        public ClrObject ReadObjectField(string fieldName)
        {
            ClrType          type  = GetTypeOrThrow();
            ClrInstanceField?field = type.GetFieldByName(fieldName);

            if (field is null)
            {
                throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'");
            }

            if (!field.IsObjectReference)
            {
                throw new ArgumentException($"Field '{type.Name}.{fieldName}' is not an object reference.");
            }

            ClrHeap heap = type.Heap;

            ulong addr = field.GetAddress(Address, _interior);

            if (!DataReader.ReadPointer(addr, out ulong obj))
            {
                return(default);
Ejemplo n.º 9
0
        public static long CountTargets(ClrDump clrDump, ClrType clrType)
        {
            long count = 0;
            var targetField = clrType.GetFieldByName(TargetFieldName);
            var invocCountField = clrType.GetFieldByName(InvocationCountFieldName);

            foreach (ulong address in clrDump.EnumerateInstances(clrType))
            {
                count += CountTargets(address, clrType, targetField, invocCountField);
            }
            return count;
        }
Ejemplo n.º 10
0
        private static void VerifyStringObjectSize(ClrRuntime runtime, ClrType type, ulong obj, string text)
        {
            var objSize = type.GetSize(obj);
            var objAsHex = obj.ToString("x");
            var rawBytes = Encoding.Unicode.GetBytes(text);

            if (runtime.ClrInfo.Version.Major == 2)
            {
                // This only works in .NET 2.0, the "m_array_Length" field was removed in .NET 4.0
                var arrayLength = (int)type.GetFieldByName("m_arrayLength").GetValue(obj);
                var stringLength = (int)type.GetFieldByName("m_stringLength").GetValue(obj);
                
                var calculatedSize = (((ulong)arrayLength - 1) * 2) + HeaderSize;
                if (objSize != calculatedSize)
                {
                    Console.WriteLine("Object Size Mismatch: arrayLength: {0,4}, stringLength: {1,4}, Object Size: {2,4}, Object: {3} -> \n\"{4}\"",
                                      arrayLength, stringLength, objSize, objAsHex, text);
                }
            }
            else
            {
                // In .NET 4.0 we can do a more normal check, i.e. ("object size" - "raw byte array length") should equal the expected header size
                var theRest = objSize - (ulong)rawBytes.Length;
                if (theRest != HeaderSize)
                {
                    Console.WriteLine("Object Size Mismatch: Raw Bytes Length: {0,4}, Object Size: {1,4}, Object: {2} -> \n\"{3}\"",
                                      rawBytes.Length, objSize, objAsHex, text);
                }
            }
        }
Ejemplo n.º 11
0
        private bool GetStackTraceFromField(ClrType type, ulong obj, out ulong stackTrace)
        {
            stackTrace = 0;
            var field = type.GetFieldByName("_stackTrace");
            if (field == null)
                return false;

            object tmp = field.GetValue(obj);
            if (tmp == null || !(tmp is ulong))
                return false;

            stackTrace = (ulong)tmp;
            return true;
        }
Ejemplo n.º 12
0
        public static KcpUserAccount GetKcpUserAccountInfo(ulong KcpUserAccountAddr, ClrType KcpUserAccountType, ClrHeap Heap, string databaseLocation)
        {
            KcpUserAccount UserAccountInfo = new KcpUserAccount();

            // Get the embedded ProtectedBinary
            ClrInstanceField KcpProtectedBinaryField = KcpUserAccountType.GetFieldByName("m_pbKeyData");
            ulong KcpProtectedBinaryAddr = KcpProtectedBinaryField.GetAddress(KcpUserAccountAddr);
            ulong KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpUserAccountAddr);

            ClrInstanceField EncDataField = KcpProtectedBinaryField.Type.GetFieldByName("m_pbData");
            ulong EncDataAddr = EncDataField.GetAddress(KcpProtectedBinaryObjAddr);
            ulong EncDataArrayAddr = (ulong)EncDataField.GetValue(KcpProtectedBinaryObjAddr);

            ClrType EncDataArrayType = Heap.GetObjectType(EncDataArrayAddr);
            int len = EncDataField.Type.GetArrayLength(EncDataArrayAddr);

            if (len <= 0 || len % 16 != 0) // Small sanity check to make sure everything's ok
                return null;

            byte[] EncData = new byte[len];
            for (int i = 0; i < len; i++)
            {
                EncData[i] = (byte)EncDataArrayType.GetArrayElementValue(EncDataArrayAddr, i);
            }

            UserAccountInfo.databaseLocation = databaseLocation;
            UserAccountInfo.encryptedBlob = EncData;
            UserAccountInfo.encryptedBlobAddress = (IntPtr)KcpUserAccountType.GetArrayElementAddress(EncDataArrayAddr, 0);
            UserAccountInfo.encryptedBlobLen = len;

            return UserAccountInfo;
        }