public void HeapEnumerationWhileClearingCache() { // Simply test that we can enumerate the heap. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrObject[] objects = heap.EnumerateObjects().ToArray(); Assert.NotEmpty(objects); int i = 0; foreach (ClrObject obj in heap.EnumerateObjects()) { Assert.Equal(objects[i].Address, obj.Address); Assert.Equal(objects[i].Type, obj.Type); if ((i % 8) == 0) { runtime.FlushCachedData(); } i++; } }
public static IEnumerable <ClrDynamic> EnumerateDynamicObjects(this ClrHeap heap, string typeName) { if (!typeName.Contains("*")) { var type = (from t in heap.EnumerateTypes() let deobfuscator = ClrMDSession.Current.GetTypeDeobfuscator(t) where deobfuscator.OriginalName == typeName select t).First(); return((ClrDynamic)heap.EnumerateObjects().First(item => item.Type == type)); } var regex = new Regex($"^{Regex.Escape(typeName).Replace("\\*", ".*")}$", RegexOptions.Compiled | RegexOptions.IgnoreCase); var types = from type in heap.EnumerateTypes() let deobfuscator = ClrMDSession.Current.GetTypeDeobfuscator(type) where regex.IsMatch(deobfuscator.OriginalName) select type; var typeSet = new HashSet <ClrType>(types); return(heap.EnumerateObjects().Where(o => typeSet.Contains(o.Type)).Select(o => (ClrDynamic)o)); }
public void HeapCachedEnumerationMatches() { // Simply test that we can enumerate the heap. using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; List <ClrObject> expectedList = new List <ClrObject>(heap.EnumerateObjects()); heap.CacheHeap(CancellationToken.None); Assert.True(heap.IsHeapCached); List <ClrObject> actualList = new List <ClrObject>(heap.EnumerateObjects()); Assert.True(actualList.Count > 0); Assert.Equal(expectedList.Count, actualList.Count); for (int i = 0; i < actualList.Count; i++) { ClrObject expected = expectedList[i]; ClrObject actual = actualList[i]; Assert.True(expected == actual); Assert.Equal(expected, actual); } } }
public void Can_find_instances_of_a_type() { var expectedNumber = _heap.EnumerateObjects().Count(o => o.Type.Name == typeof(ClassWithStringField).FullName); var proxies = _heap.GetProxies <ClassWithStringField>().ToList(); Assert.AreEqual(expectedNumber, proxies.Count); Assert.IsTrue(proxies.All(p => p.GetClrType().Name == typeof(ClassWithStringField).FullName)); }
public void Execute(ClrHeap heap) { var dict = new Dictionary <string, ulong>(); foreach (var instance in heap.EnumerateObjects()) { if (instance.Type.IsString) { var value = (string)instance.Type.GetValue(instance.Address); if (dict.ContainsKey(value)) { dict[value]++; } else { dict[value] = 1; } } } foreach (var pair in dict.OrderByDescending(x => x.Value).Take(50)) { Console.WriteLine(pair); } }
public void GetObjectMethodTableTest() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; int i = 0; foreach (ClrObject obj in heap.EnumerateObjects()) { i++; ClrType type = obj.Type; Assert.NotNull(type); ulong mt = dt.DataReader.ReadPointer(obj); Assert.NotEqual(0ul, mt); if (dt.CacheOptions.CacheTypes) { Assert.Same(type, runtime.GetTypeByMethodTable(mt)); } else { Assert.Equal(type, runtime.GetTypeByMethodTable(mt)); } Assert.Equal(mt, type.MethodTable); } }
public static IEnumerable <ClrObject> EnumerateClrObjects(this ClrHeap heap, IEnumerable <ClrType> types) { if (types == null) { return(heap.EnumerateClrObjects()); } IList <ClrType> castedTypes = types as IList <ClrType> ?? types.ToList(); if (castedTypes.Count == 0) { return(heap.EnumerateClrObjects()); } if (castedTypes.Count == 1) { return(heap.EnumerateClrObjects(castedTypes[0])); } HashSet <ClrType> set = new HashSet <ClrType>(castedTypes); return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where set.Contains(type) select new ClrObject(address, type)); }
public static IEnumerable <ClrObject> EnumerateClrObjects(this ClrHeap heap, ClrType type) { return(from address in heap.EnumerateObjects() let objectType = heap.GetSafeObjectType(address) where objectType == type select new ClrObject(address, type)); }
public static IEnumerable <ClrObject> EnumerateClrObjects(this ClrHeap heap, IEnumerable <string> typeNames) { if (typeNames == null) { return(heap.EnumerateClrObjects()); } IList <string> castedTypes = typeNames as IList <string> ?? typeNames.ToList(); if (castedTypes.Count == 0) { return(heap.EnumerateClrObjects()); } if (castedTypes.Count == 1) { return(heap.EnumerateClrObjects(castedTypes[0])); } HashSet <string> set = new HashSet <string>(castedTypes, StringComparer.OrdinalIgnoreCase); return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where type != null && set.Contains(type.Name) select new ClrObject(address, type)); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Must specify a coredump to inspect."); return; } if (args.Length == 1) { Console.WriteLine("Must specify a dac to use."); return; } Stopwatch sw = new Stopwatch(); sw.Start(); using (DataTarget dt = DataTarget.LoadCoreDump(args[0])) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(args[1], true); ClrHeap heap = runtime.Heap; foreach (ClrObject obj in heap.EnumerateObjects()) { Console.WriteLine($"{obj.Address:x12} {obj.Type?.Name ?? "error"}"); } } Console.WriteLine(sw.Elapsed); }
public void TestEnumerateRefsWithFieldsArrayFieldValues() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; foreach (ClrObject obj in heap.EnumerateObjects()) { foreach (ClrReference reference in obj.EnumerateReferencesWithFields(carefully: false, considerDependantHandles: false)) { if (obj.IsArray) { // Ensure we didn't try to set .Field if it's an array reference Assert.True(reference.IsArrayElement); Assert.False(reference.IsDependentHandle); Assert.False(reference.IsField); Assert.Null(reference.Field); } else { // Ensure that we always have a .Field when it's a field reference Assert.False(reference.IsArrayElement); Assert.False(reference.IsDependentHandle); Assert.True(reference.IsField); Assert.NotNull(reference.Field); } } } }
public void HeapEnumeration() { // Simply test that we can enumerate the heap. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; bool encounteredFoo = false; int count = 0; foreach (ClrObject obj in heap.EnumerateObjects()) { ClrType type = heap.GetObjectType(obj); Assert.NotNull(type); string name = type.Name; if (type.Name == "Foo") { encounteredFoo = true; } count++; } Assert.True(count > 0); Assert.True(encounteredFoo); }
public static ClrType GetTypeFromEE(ClrRuntime Runtime, ulong EEClass) { ClrHeap heap = Runtime.GetHeap(); ClrType type = null; int max = heap.TypeIndexLimit; if (max < 1) { var objList = heap.EnumerateObjects().GetEnumerator(); if (objList.MoveNext()) { type = heap.GetObjectType(objList.Current); } } else { type = Runtime.GetHeap().GetTypeByIndex(0); } if (type == null) { throw new NullReferenceException("There is no object in the heap"); } ClrType EEType = (ClrType)RunMethod(type, "ConstructObjectType", EEClass); return(EEType); }
public static void HeapStat(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args) { // Must be the first thing in our extension. if (!InitApi(client)) { return; } // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime). All other // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and // reobtained every run. ClrHeap heap = Runtime.Heap; var stats = from obj in heap.EnumerateObjects() group obj by obj.Type into g let size = g.Sum(p => (long)p.Size) orderby size select new { Size = size, Count = g.Count(), g.Key.Name }; // Console.WriteLine now writes to the debugger. foreach (var entry in stats) { Console.WriteLine("{0,12:n0} {1,12:n0} {2}", entry.Count, entry.Size, entry.Name); } }
public void Execute(ClrHeap heap) { ulong counter = 0; foreach (var instance in heap.EnumerateObjects()) { if (instance.Type.IsArray && instance.Type.Name == "System.Char[]") { if (instance.Size > 84000 || instance.Type.GetSize(instance.Address) > 84000) { int arrayLength = instance.Type.GetArrayLength(instance.Address); var chars = new char[arrayLength]; for (var index = 0; index < arrayLength; index++) { chars[index] = (char)instance.Type.GetArrayElementValue(instance.Address, index); } var sb = new StringBuilder(); foreach (var c in chars) { sb.Append(c); } File.WriteAllText($"file_{counter++}_{instance.Size}.txt", sb.ToString()); } } } }
public void ArrayComponentTypeTest() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; // Ensure that we always have a component for every array type. foreach (ClrObject obj in heap.EnumerateObjects()) { ClrType type = obj.Type; Assert.True(!type.IsArray || type.ComponentType != null); foreach (ClrInstanceField field in type.Fields) { Assert.NotNull(field.Type); Assert.Same(heap, field.Type.Heap); } } foreach (ClrModule module in runtime.AppDomains.SelectMany(ad => ad.Modules)) { foreach (ClrType type in module.EnumerateTypes()) { Assert.True(!type.IsArray || type.ComponentType != null); Assert.Same(heap, type.Heap); } } }
public void HeapEnumeration() { // Simply test that we can enumerate the heap. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; // Ensure that we never find objects within allocation contexts. MemoryRange[] allocationContexts = heap.EnumerateAllocationContexts().ToArray(); Assert.NotEmpty(allocationContexts); bool encounteredFoo = false; int count = 0; foreach (ClrObject obj in heap.EnumerateObjects()) { ClrType type = heap.GetObjectType(obj); Assert.NotNull(type); string name = type.Name; if (type.Name == "Foo") { encounteredFoo = true; } count++; Assert.DoesNotContain(allocationContexts, ac => ac.Contains(obj)); } Assert.True(count > 0); Assert.True(encounteredFoo); }
public void SegmentEnumeration() { // Simply test that we can enumerate the heap. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrObject[] objs = heap.EnumerateObjects().ToArray(); // Enumerating each segment and then each object on each segment should produce // the same enumeration as ClrHeap.EnumerateObjects(). int index = 0; foreach (ClrSegment seg in heap.Segments) { foreach (ClrObject obj in seg.EnumerateObjects()) { Assert.Equal(objs[index], obj); index++; } } ClrSegment large = heap.Segments.Single(s => s.IsLargeObjectSegment); large.EnumerateObjects().ToArray(); Assert.Equal(objs.Length, index); }
public void EnumerateMethodTableTest() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrObject[] fooObjects = (from obj in heap.EnumerateObjects() where obj.Type.Name == "Foo" select obj).ToArray(); // There are exactly two Foo objects in the process, one in each app domain. // They will have different method tables. Assert.Equal(2, fooObjects.Length); ClrType fooType = heap.GetObjectType(fooObjects[0]); ClrType fooType2 = heap.GetObjectType(fooObjects[1]); Assert.NotSame(fooType, fooType2); ClrObject appDomainsFoo = fooObjects.Where(o => o.Type.Module.AppDomain.Name.Contains("AppDomains")).Single(); ClrObject nestedFoo = fooObjects.Where(o => o.Type.Module.AppDomain.Name.Contains("Second")).Single(); Assert.NotSame(appDomainsFoo.Type, nestedFoo.Type); ulong nestedExceptionFooMethodTable = dt.DataReader.ReadPointer(nestedFoo.Address); ulong appDomainsFooMethodTable = dt.DataReader.ReadPointer(appDomainsFoo.Address); // These are in different domains and should have different type handles: Assert.NotEqual(nestedExceptionFooMethodTable, appDomainsFooMethodTable); // The MethodTable returned by ClrType should always be the method table that lives in the "first" // AppDomain (in order of ClrAppDomain.Id). Assert.Equal(appDomainsFooMethodTable, fooType.MethodTable); Assert.Equal(nestedExceptionFooMethodTable, fooType2.MethodTable); }
public void IntegerObjectClrType() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrAppDomain domain = runtime.AppDomains.Single(); ClrModule module = runtime.GetModule(ModuleName); ClrType typesType = module.GetTypeByName("Types"); ClrStaticField field = typesType.GetStaticFieldByName("s_i"); ClrObject obj = field.ReadObject(domain); Assert.False(obj.IsNull); ClrType type = obj.Type; Assert.NotNull(type); Assert.True(type.IsPrimitive); Assert.False(type.IsObjectReference); Assert.True(type.IsValueType); var fds = obj.Type.Fields; Assert.True(obj.IsBoxedValue); int value = obj.ReadBoxedValue <int>(); Assert.Equal(42, value); Assert.Contains(obj.Address, heap.EnumerateObjects().Select(a => a.Address)); }
public void RunAnalysisRule(NetScriptManager manager, NetDbgObj debugger, NetProgress progress) { if (debugger.ClrRuntime == null) { return; } #region Sample Code to Scan for Large Objects On Heap manager.WriteNameValuePair("PID", debugger.ProcessID.ToString()); ClrHeap heap = debugger.ClrHeap; Dictionary <string, int> lohtype = new Dictionary <string, int>(); foreach (var heapobj in heap.EnumerateObjects()) { ClrType type = heap.GetObjectType(heapobj); if (type.GetSize(heapobj) > 85000) { if (lohtype.ContainsKey(type.Name)) { lohtype[type.Name]++; } else { lohtype.Add(type.Name, 1); } } } foreach (var item in lohtype) { manager.WriteLine(item.Key + " " + item.Value, true, "green"); } #endregion }
public static IEnumerable <ClrObject> EnumerateClrObjects(this ClrHeap heap, string typeName) { if (typeName.Contains("*")) { string typeNameRegex = "^" + Regex.Escape(typeName).Replace("\\*", ".*") + "$"; Regex regex = new Regex(typeNameRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase); return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where type != null && regex.IsMatch(type.Name) select new ClrObject(address, type)); } return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where type != null && type.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase) select new ClrObject(address, type)); }
private ClrObject FindFirstInstanceOfType(ClrHeap heap, string typeName) { ClrObject obj = heap.EnumerateObjects().FirstOrDefault(o => o.Type.Name == typeName); if (obj.IsNull) { throw new InvalidOperationException($"Could not find {typeName} in {TestTarget.Source} source."); } return(obj); }
public static int EntryPoint(string pwzArgument) { Debug.WriteLine("[KeeFarceDLL] Starting"); //string processName = Process.GetCurrentProcess().ProcessName; //MessageBox.Show("The current process is " + processName + " and I am running C# code! Yuss!"); if (is64Bit) { Debug.WriteLine("[KeeFarceDLL] Target is 64 bit"); } // Retrieve the DocumentManagerEx object off the heap // TODO: KeePass can support multiple password files , so should probably modify this to load // ALL of the DocumentManagerEx's into a list and process 'em, as opposed to just breaking // after finding the first one. IntPtr docManagerPtr = IntPtr.Zero; using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation(); ClrRuntime runtime = CreateRuntimeHack(dataTarget, dacLocation, 4, 5); Debug.WriteLine("[KeeFarceDLL] Attached to process."); ClrHeap heap = runtime.GetHeap(); foreach (ulong obj in heap.EnumerateObjects()) { ClrType type = heap.GetObjectType(obj); ulong size = type.GetSize(obj); if (type.Name == "KeePass.UI.DocumentManagerEx") { Debug.WriteLine("[KeeFarceDLL] Found DocumentManagerEx at: " + obj.ToString("X") + " " + type.Name); docManagerPtr = (IntPtr)obj; break; } } if (docManagerPtr == IntPtr.Zero) { // Didn't find a document manager, time to return. Debug.WriteLine("[KeeFarceDLL] No DocumentManagerEx found"); return(1); } } // Get the DocumentManagerEx object Converter <object> ptrconv = new Converter <object>(); object documentManagerEx = ptrconv.ConvertFromIntPtr(docManagerPtr); var info = new DocumentManagerExInfo(documentManagerEx); int r = doExport(info.ActiveDatabase, info.RootGroup, exportFile); return(r); }
public static void PrintDictionaries(ClrHeap heap) { foreach (var clrObject in heap.EnumerateObjects()) { if (!string.Equals(clrObject.Type?.Name, "System.Collections.Generic.Dictionary<System.String,System.String>")) { continue; } Console.WriteLine("** Dictionary<string, string> at " + clrObject.HexAddress); PrintDictionary(clrObject); } }
private ClrObject FindSingleRefPointingToType(ClrHeap heap, string targetTypeName) { foreach (ClrObject obj in heap.EnumerateObjects().Where(o => o.Type.Name == "SingleRef")) { ClrObject item1 = obj.GetObjectField("Item1"); if (item1.Type?.Name == targetTypeName) { return(obj); } } throw new InvalidOperationException($"Did not find a SingleRef pointing to a {targetTypeName}."); }
public void ObjectSetAddRemove() { using DataTarget dataTarget = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ObjectSet hash = new ObjectSet(heap); foreach (ulong obj in heap.EnumerateObjects()) { Assert.False(hash.Contains(obj)); hash.Add(obj); Assert.True(hash.Contains(obj)); } foreach (ulong obj in heap.EnumerateObjects()) { Assert.True(hash.Contains(obj)); hash.Remove(obj); Assert.False(hash.Contains(obj)); } }
private void StartRuntime(string Target) { DataTarget dataTarget = DataTarget.LoadCrashDump(Target); ClrInfo latest = null; foreach (var version in dataTarget.ClrVersions) { WriteLine("Version: {0}.{1}.{2}.{3} from {4}", version.Version.Major, version.Version.Minor, version.Version.Patch, version.Version.Revision, version.DacInfo.FileName); latest = version; } m_runtime = dataTarget.CreateRuntime(latest.TryDownloadDac()); ulong strMT, arrMT, freeMT = 0; AdHoc.GetCommonMT(m_runtime, out strMT, out arrMT, out freeMT); WriteLine("Free MT: {0:x16}, String MT: {1:x16}, Array MT: {2:x16}", freeMT, strMT, arrMT); WriteLine("== App Domains ==="); int i = 0; DumpDomains(); //foreach (var appDomain in AdHoc.GetDomains(m_runtime)) //{ // i++; // if (i == 1) // { // WriteLine("{0:x16} System", appDomain.Address); // WriteLine(" Modules: {0}", appDomain.Modules.Count); // continue; // } // if (i == 2) // { // WriteLine("{0:x16} Shared", appDomain.Address); // WriteLine(" Modules: {0}", appDomain.Modules.Count); // continue; // } // WriteLine("{0:x16} {1}", appDomain.Address, appDomain.Name); // WriteLine(" {0}{1}", appDomain.ApplicationBase, appDomain.ConfigurationFile); // WriteLine(" Modules: {0}", appDomain.Modules.Count); //} WriteLine("=================="); WriteLine("Heap(s): {0} GC Server Mode: {1}", m_runtime.HeapCount, m_runtime.ServerGC); m_heap = m_runtime.GetHeap(); heapObjs = m_heap.EnumerateObjects().GetEnumerator(); count = 0; }
public static void PrintConcurrentDictionaries(ClrHeap heap) { const string concurrentDictionaryTypeName = "System.Collections.Concurrent.ConcurrentDictionary<System.String,System.String>"; foreach (var clrObject in heap.EnumerateObjects()) { if (!string.Equals(clrObject.Type?.Name, concurrentDictionaryTypeName)) { continue; } Console.WriteLine("** ConcurrentDictionary<string, string> at " + clrObject.HexAddress); PrintConcurrentDictionary(clrObject); } }
private ClrObject FindSingleRefPointingToTarget(ClrHeap heap) { foreach (ClrObject obj in heap.EnumerateObjects().Where(o => o.Type.Name == "SingleRef")) { foreach (ClrObject reference in obj.EnumerateReferences(considerDependantHandles: true)) { if (reference.Type.Name == "TargetType") { return(obj); } } } throw new InvalidOperationException("Did not find a SingleRef pointing to a TargetType"); }