Esempio n. 1
0
        private static KeyValuePair <ClrInstanceField, string> GetField(string fieldName, string typeName, ClrHeap Heap)
        {
            //helper function to get an instance field
            if (!Heap.CanWalkHeap)
            {
                return(new KeyValuePair <ClrInstanceField, string>(null, "[!] Unable to walk the heap"));
            }

            Console.WriteLine("[+] Walking the heap....");
            foreach (ulong obj in Heap.EnumerateObjectAddresses())
            {
                ClrType type = Heap.GetObjectType(obj);

                if (type == null || type.Name != typeName)
                {
                    continue;
                }

                try
                {
                    ClrInstanceField field = type.GetFieldByName(fieldName);
#if DEBUG
                    Console.WriteLine("[+] Found desired field: " + fieldName);
#endif
                    ulong a = field.GetAddress(obj);
                    if (field.HasSimpleValue)
                    {
                        fieldValue = field.GetValue(obj);
                    }

                    fieldAddr = new IntPtr(long.Parse(a.ToString()));
                    return(new KeyValuePair <ClrInstanceField, string>(field, "[+] Found field " + fieldName));
                }
                catch (Exception e)
                {
                    return(new KeyValuePair <ClrInstanceField, string>(null, e.ToString()));
                }
            }

            return(new KeyValuePair <ClrInstanceField, string>(null, "Unable to locate field: " + fieldName));
        }
        public void GetFieldFrom_WhenStructureHasReferenceField_ReturnsField([Frozen] ClrHeap heap, ClrObject target, [Frozen] ClrType structType, ClrValueClass rawStruct, ClrInstanceField structReferenceField, ulong fieldAddress)
        {
            // Arrange
            IAddressableTypedEntity entity = rawStruct;

            structReferenceField.IsObjectReference.Returns(true);
            structReferenceField.GetAddress(entity.Address, Arg.Any <bool>()).Returns(fieldAddress);

            heap.ReadPointer(fieldAddress, out var whatever)
            .Returns(call =>
            {
                call[1] = target.Address;
                return(true);
            });

            // Act
            var fieldByName = entity.GetFieldFrom(structReferenceField.Name);

            // Assert
            fieldByName.Address.Should().Be(target.Address);
        }
        public void GetFieldFrom_WhenClrObjectHasReferenceField_ReturnsField([Frozen] ClrHeap heap, [Frozen] ClrType objectType, ClrObject rawClrObject, ClrInstanceField clrField, ulong fieldAddress, ClrObject target)
        {
            // Arrange
            IAddressableTypedEntity entity = rawClrObject;

            clrField.IsObjectReference.Returns(true);
            clrField.GetAddress(entity.Address).Returns(fieldAddress);

            heap.ReadPointer(fieldAddress, out var whatever)
            .Returns(call =>
            {
                call[1] = target.Address;
                return(true);
            });

            // Act
            var fieldFoundByName = entity.GetFieldFrom(clrField.Name);

            // Assert
            fieldFoundByName.Address.Should().Be(target.Address);
        }
Esempio n. 4
0
        public static KcpKeyFile GetKcpKeyFileInfo(ulong KcpKeyFileAddr, ClrType KcpKeyFileType, ClrHeap Heap, string databaseLocation)
        {
            KcpKeyFile KeyFileInfo = new KcpKeyFile();

            // key file path
            ClrInstanceField KcpStringField     = KcpKeyFileType.GetFieldByName("m_strPath");
            ulong            KcpStringFieldAddr = KcpStringField.GetAddress(KcpKeyFileAddr);
            object           keyFilePath        = KcpStringField.GetValue(KcpStringFieldAddr, true);

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

            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);
            }

            KeyFileInfo.databaseLocation     = databaseLocation;
            KeyFileInfo.encryptedBlob        = EncData;
            KeyFileInfo.encryptedBlobAddress = (IntPtr)KcpKeyFileType.GetArrayElementAddress(EncDataArrayAddr, 0);
            KeyFileInfo.encryptedBlobLen     = len;
            KeyFileInfo.keyFilePath          = keyFilePath.ToString();

            return(KeyFileInfo);
        }
Esempio n. 5
0
        public static KcpPassword GetKcpPasswordInfo(ulong KcpPasswordAddr, ClrType KcpPasswordType, ClrHeap Heap, string databaseLocation)
        {
            KcpPassword PasswordInfo = new KcpPassword();

            // Protected String
            ClrInstanceField KcpProtectedStringField   = KcpPasswordType.GetFieldByName("m_psPassword");
            ulong            KcpProtectedStringAddr    = KcpProtectedStringField.GetAddress(KcpPasswordAddr);
            ulong            KcpProtectedStringObjAddr = (ulong)KcpProtectedStringField.GetValue(KcpPasswordAddr);

            // Get the embedded ProtectedBinary
            ClrInstanceField KcpProtectedBinaryField   = KcpProtectedStringField.Type.GetFieldByName("m_pbUtf8");
            ulong            KcpProtectedBinaryAddr    = KcpProtectedBinaryField.GetAddress(KcpProtectedStringObjAddr);
            ulong            KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpProtectedStringObjAddr);

            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);
            }

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

            return(PasswordInfo);
        }
Esempio n. 6
0
        static string GetOutput(ulong obj, ClrInstanceField field)
        {
            // If we don't have a simple value, return the address of the field in hex.
            if (!field.HasSimpleValue)
            {
                return(field.GetAddress(obj).ToString("X"));
            }

            object value = field.GetValue(obj);

            if (value == null)
            {
                return("{error}");  // Memory corruption in the target process.
            }
            // Decide how to format the string based on the underlying type of the field.
            switch (field.ElementType)
            {
            case ClrElementType.String:
                // In this case, value is the actual string itself.
                return((string)value);

            case ClrElementType.Array:
            case ClrElementType.SZArray:
            case ClrElementType.Object:
            case ClrElementType.Class:
            case ClrElementType.FunctionPointer:
            case ClrElementType.NativeInt:
            case ClrElementType.NativeUInt:
                // These types are pointers.  Print as hex.
                return(string.Format("{0:X}", value));

            default:
                // Everything else will look fine by simply calling ToString.
                return(value.ToString());
            }
        }
Esempio n. 7
0
 public         ClrObject this[ClrInstanceField field] => GetInnerObject(field.GetAddress(Address, IsInterior), field.Type);
Esempio n. 8
0
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (IsNull())
            {
                result = new ClrNullValue(m_heap);
                return(true);
            }

            ClrInstanceField field = null;

            if (binder.IgnoreCase)
            {
                foreach (var inst in m_type.Fields)
                {
                    if (inst.Name.Equals(binder.Name, StringComparison.CurrentCultureIgnoreCase))
                    {
                        field = inst;
                        break;
                    }
                }
            }
            else
            {
                field = m_type.GetFieldByName(binder.Name);
            }

            if (field == null)
            {
                if (ClrDynamicClass.GetStaticField(m_heap, m_type, binder, out result))
                {
                    return(true);
                }

                throw new InvalidOperationException(string.Format("Type '{0}' does not contain a '{1}' field.", m_type.Name, binder.Name));
            }

            if (field.IsPrimitive)
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrPrimitiveValue(value, field.ElementType);
                }

                return(true);
            }
            else if (field.IsValueClass)
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                result = new ClrObject(m_heap, field.Type, addr, true);
                return(true);
            }
            else if (field.ElementType == ClrElementType.String)
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                if (!m_heap.Runtime.ReadPointer(addr, out addr))
                {
                    result = new ClrNullValue(m_heap);
                    return(true);
                }

                result = new ClrObject(m_heap, field.Type, addr);
                return(true);
            }
            else
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrObject(m_heap, field.Type, (ulong)value);
                }

                return(true);
            }
        }
Esempio n. 9
0
        private static ulong GetFieldAddressValue(ClrRuntime runtime, ClrInstanceField field, ulong addr)
        {
            ulong fieldAddress = field.GetAddress(addr);

            return(ReadMemory(runtime, fieldAddress));
        }
Esempio n. 10
0
        // Returns all the info about any Composite Keys stored in memory
        public static List <CompositeKeyInfo> GetCompositeKeyInfo(Process process)
        {
            List <CompositeKeyInfo> keyInfo = new List <CompositeKeyInfo>();
            DataTarget dt = null;
            string     databaseLocation = "";

            try
            {
                dt = DataTarget.AttachToProcess(process.Id, 50000);

                if (dt.ClrVersions.Count == 0)
                {
                    string err = "CLR is not loaded. Is it Keepass 1.x, perhaps?";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                if (dt.ClrVersions.Count > 1)
                {
                    Logger.WriteLine("*** Interesting... there are multiple .NET runtimes loaded in KeePass");
                }

                ClrInfo    Version = dt.ClrVersions[0];
                ClrRuntime Runtime = Version.CreateRuntime();
                ClrHeap    Heap    = Runtime.GetHeap();

                if (!Heap.CanWalkHeap)
                {
                    string err = "Error: Cannot walk the heap!";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                foreach (ulong obj in Heap.EnumerateObjectAddresses())
                {
                    ClrType type = Heap.GetObjectType(obj);

                    if (type == null || type.Name != "KeePassLib.PwDatabase")
                    {
                        continue;
                    }

                    Logger.WriteLine("************ Found a PwDatabase! **********");

                    List <ulong> referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                    // First walk the referenced objects to find the database path
                    foreach (ulong refObj in referencedObjects)
                    {
                        ClrType refObjType = Heap.GetObjectType(refObj);
                        if (refObjType.Name == "KeePassLib.Serialization.IOConnectionInfo")
                        {
                            ClrInstanceField UrlField     = refObjType.GetFieldByName("m_strUrl");
                            ulong            UrlFieldAddr = UrlField.GetAddress(refObj);
                            object           Url          = UrlField.GetValue(UrlFieldAddr, true);
                            databaseLocation = (string)Url;
                        }
                    }

                    if (databaseLocation != "")
                    {
                        Logger.WriteLine("*** PwDatabase location : " + databaseLocation);

                        referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                        // now walk the referenced objects looking for a master composite key
                        foreach (ulong refObj in referencedObjects)
                        {
                            ClrType refObjType = Heap.GetObjectType(refObj);
                            if (refObjType.Name == "KeePassLib.Keys.CompositeKey")
                            {
                                Logger.WriteLine("************ Found a CompositeKey! **********");
                                CompositeKeyInfo CompositeKey = new CompositeKeyInfo();

                                // Get all objects kept alive by the composite key.
                                // (A shortcut to get references to all Key types)
                                List <ulong> referencedObjects2 = ClrMDHelper.GetReferencedObjects(Heap, refObj);

                                foreach (ulong refObj2 in referencedObjects2)
                                {
                                    ClrType refObjType2 = Heap.GetObjectType(refObj2);

                                    if (refObjType2.Name == "KeePassLib.Keys.KcpPassword")
                                    {
                                        KcpPassword KcpPassword = GetKcpPasswordInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpPassword == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpPassword);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpKeyFile")
                                    {
                                        KcpKeyFile KcpKeyFile = GetKcpKeyFileInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpKeyFile == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpKeyFile);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpUserAccount")
                                    {
                                        KcpUserAccount KcpUserAccount = GetKcpUserAccountInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpUserAccount == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpUserAccount);
                                    }
                                }
                                if (CompositeKey.UserKeyCount > 0)
                                {
                                    keyInfo.Add(CompositeKey);
                                }
                            }
                        }
                    }
                }

                Logger.Write("\n");
            }
            catch (Exception e)
            {
                Logger.WriteLine(e.Message);
                throw;
            }
            finally
            {
                if (dt != null)
                {
                    dt.Dispose();
                }
            }

            return(keyInfo);
        }
Esempio n. 11
0
 /// <summary>
 ///     Returns the address of the value of this field.  Equivalent to GetFieldAddress(objRef, false).
 /// </summary>
 /// <param name="objRef">The object to get the field address for.</param>
 /// <returns>The value of the field.</returns>
 /// <exception cref="NotImplementedException"></exception>
 /// <inheritdoc />
 public ulong GetAddress(ulong objRef) => InstanceField.GetAddress(objRef);
Esempio n. 12
0
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (IsNull())
            {
                result = new ClrNullValue(m_heap);
                return(true);
            }

            if (binder.Name == "__Size")
            {
                result = m_type.GetSize(m_addr);
                return(true);
            }

            if (binder.Name == "__Type")
            {
                result = m_type.Name;
                return(true);
            }

            if (binder.Name == "__Address")
            {
                result = String.Format("{0:x16}", m_addr);
                return(true);
            }

            if (binder.Name == "__Fields")
            {
                result = (from f in m_type.Fields where f.Type != null select new { Name = f.Name, Type = f.Type.Name }).ToArray();
                return(true);
            }

            ClrInstanceField field = null;

            foreach (var instanceField in m_type.Fields)
            {
                // Auto-generated properties have this ugly <> thing around their fields that you can't put
                // in a C# expression. Clean them up to make them accessible by their property name.
                var cleanFieldName = instanceField.Name;
                if (cleanFieldName.StartsWith("<") && cleanFieldName.EndsWith(">k__BackingField"))
                {
                    cleanFieldName = cleanFieldName.Substring(
                        1, cleanFieldName.Length - (1 + ">k__BackingField".Length));
                }
                if (cleanFieldName == binder.Name)
                {
                    field = instanceField;
                    break;
                }
            }

            if (field == null)
            {
                if (ClrDynamicClass.GetStaticField(m_heap, m_type, binder, out result))
                {
                    return(true);
                }

                throw new InvalidOperationException(string.Format("Type '{0}' does not contain a '{1}' field.", m_type.Name, binder.Name));
            }

            if (field.IsPrimitive())
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrPrimitiveValue(value, field.ElementType);
                }

                return(true);
            }
            else if (field.IsValueClass())
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                result = new ClrObject(m_heap, field.Type, addr, true);
                return(true);
            }
            else if (field.ElementType == ClrElementType.String)
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                if (!m_heap.GetRuntime().ReadPointer(addr, out addr))
                {
                    result = new ClrNullValue(m_heap);
                    return(true);
                }

                result = new ClrObject(m_heap, field.Type, addr);
                return(true);
            }
            else
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrObject(m_heap, field.Type, (ulong)value);
                }

                return(true);
            }
        }