/// <summary> /// Recursively build the heirarchy of .Net objects in the external process. /// </summary> /// <param name="proxyService">The proxy service collecting the .Net objects.</param> /// <param name="visited">A set of visited object addresses.</param> /// <param name="parent">The parent of the current object.</param> /// <param name="parentRef">The address of the parent of the current object.</param> private void RecursiveBuild(IProxyService proxyService, HashSet <UInt64> visited, DotNetObject parent, UInt64 parentRef) { // Add all fields foreach (UInt64 fieldRef in proxyService.GetObjectFields(parentRef)) { DotNetObject childObject = new DotNetObject( parent, parent.ObjectReference.ToIntPtr().Add(proxyService.GetFieldOffset(fieldRef)).ToUInt64(), Conversions.TypeCodeToType((TypeCode)proxyService.GetFieldType(fieldRef)), proxyService.GetFieldName(fieldRef)); parent.Children.Add(childObject); } // Add all nested objects recursively foreach (UInt64 childObjectRef in proxyService.GetObjectChildren(parentRef)) { if (childObjectRef == 0 || visited.Contains(childObjectRef)) { return; } visited.Add(childObjectRef); Type type = Conversions.TypeCodeToType((TypeCode)proxyService.GetObjectType(childObjectRef)); if (type == null || excludedNameSpaces.Any(X => type.Name.StartsWith(X, StringComparison.OrdinalIgnoreCase))) { return; } DotNetObject child = new DotNetObject(parent, childObjectRef, type, type.Name); parent.Children.Add(child); this.RecursiveBuild(proxyService, visited, child, childObjectRef); } parent.Children.Sort(); }
/// <summary> /// Collects .Net objects in the external process. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { this.UpdateInterval = DotNetObjectCollector.PollingTime; ProxyCommunicator proxyCommunicator = ProxyCommunicator.GetInstance(); NormalizedProcess process = EngineCore.GetInstance()?.Processes?.GetOpenedProcess(); IProxyService proxyService = proxyCommunicator.GetProxyService(EngineCore.GetInstance().Processes.IsOpenedProcess32Bit()); if (proxyService == null) { return; } try { if (process == null || !proxyService.RefreshHeap(process.ProcessId)) { return; } List <DotNetObject> objectTrees = new List <DotNetObject>(); HashSet <UInt64> visited = new HashSet <UInt64>(); foreach (UInt64 rootRef in proxyService.GetRoots()) { String rootName = proxyService.GetRootName(rootRef); Type rootType = Conversions.TypeCodeToType((TypeCode)proxyService.GetRootType(rootRef)); if (rootRef == 0 || rootName == null) { continue; } foreach (String excludedPrefix in excludedPrefixes) { if (rootName.StartsWith(excludedPrefix, StringComparison.OrdinalIgnoreCase)) { rootName = rootName.Substring(excludedPrefix.Length, rootName.Length - excludedPrefix.Length).Trim(); } } if (excludedNameSpaces.Any(x => rootName.StartsWith(x, StringComparison.OrdinalIgnoreCase))) { continue; } if (rootType != null) { if (excludedNameSpaces.Any(x => rootType.Name.StartsWith(x, StringComparison.OrdinalIgnoreCase))) { continue; } } if (visited.Contains(rootRef)) { continue; } try { DotNetObject rootObject = new DotNetObject(null, rootRef, rootType, rootName); visited.Add(rootRef); objectTrees.Add(rootObject); this.RecursiveBuild(proxyService, visited, rootObject, rootRef); } catch { } } this.ObjectTrees = objectTrees; } catch { } }