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