private static void DrawTraceCombo(TraceRecord trace, bool abbreviate) { var tracelist = trace.Target.GetTracesUIList(); string selString = (abbreviate ? "PID " : "Process ") + trace.PID; if (ImGui.TableNextColumn()) { ImGui.AlignTextToFramePadding(); ImGuiUtils.DrawHorizCenteredText($"{tracelist.Length}x"); SmallWidgets.MouseoverText($"This target binary has {tracelist.Length} loaded trace{(tracelist.Length != 1 ? 's' : "")} associated with it"); } if (ImGui.TableNextColumn()) { ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 35); if (ImGui.BeginCombo("##ProcessTraceCombo", selString)) { foreach (var selectableTrace in tracelist) { bool current = trace.PID == selectableTrace.PID && trace.randID == selectableTrace.randID; string label = "PID " + selectableTrace.PID; if (current is false) { //label = "Parent: " + label + $" ({selectableTrace.Target.FileName})"; label = label + $" ({selectableTrace.Target.FileName})"; } if (selectableTrace.GraphCount == 0) { label = label + "[0 graphs]"; } if (ImGui.Selectable(label, current)) { rgatState.SelectActiveTrace(selectableTrace); } if (selectableTrace.Children.Length > 0) { CreateTracesDropdown(selectableTrace, 1); } } ImGui.EndCombo(); } ImGui.SameLine(); ImGui.Text($"{ImGuiController.FA_ICON_COGS}"); } }
private void DrawModSymTreeNodes(PlottedGraph plot) { string LowerFilterText = _activeHighlights.SymFilterText.ToLower(); foreach (moduleEntry module_modentry in _activeHighlights.displayedModules.Values) { var keyslist = module_modentry.symbols.Keys.ToArray(); bool hasFilterMatches = false; bool moduleMatchesFilter = false; if (_activeHighlights.SymFilterText.Length == 0) { hasFilterMatches = true; } else if (module_modentry.path.ToLower().Contains(LowerFilterText)) { moduleMatchesFilter = true; hasFilterMatches = true; } else { foreach (ulong symaddr in keyslist) { symbolInfo syminfo = module_modentry.symbols[symaddr]; if (syminfo.name.ToLower().Contains(LowerFilterText)) { hasFilterMatches = true; break; } } } if (hasFilterMatches) { if (ImGui.TreeNode($"{module_modentry.path}")) { float cursX = ImGui.GetCursorPosX() + 75; foreach (ulong symaddr in keyslist) { symbolInfo syminfo = module_modentry.symbols[symaddr]; if (_activeHighlights.SymFilterText.Length > 0 && !moduleMatchesFilter && !syminfo.name.ToLower().Contains(_activeHighlights.SymFilterText.ToLower()) ) { continue; } ImGui.SetCursorPosX(10); ImGui.BeginGroup(); if (ImGui.Selectable($"{syminfo.name}", syminfo.selected)) { HandleSelectedSym(plot, module_modentry, syminfo); } if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { ImGui.OpenPopup("HighlightColorPicker"); } if (ImGui.BeginPopup("HighlightColorPicker")) { ImGui.PushStyleColor(ImGuiCol.Text, 0xffffffff); ImGui.Text($"Configuring highlight colour for {syminfo.name} (0x{syminfo.address}:x)"); ImGuiColorEditFlags flags = ImGuiColorEditFlags.NoInputs; flags |= ImGuiColorEditFlags.AlphaBar; if (ImGui.ColorPicker4("Highlight Colour", ref _activeColorPick1, flags)) { foreach (uint node in syminfo.threadNodes) { plot.SetCustomHighlightColour((int)node, _activeColorPick1); } } ImGui.Text("Highlight active:"); ImGui.SameLine(); if (SmallWidgets.ToggleButton("NodeActiveHighlightToggle", syminfo.selected, "Node is highlighted")) { HandleSelectedSym(plot, module_modentry, syminfo); } ImGui.PopStyleColor(); ImGui.EndPopup(); } ImGui.SameLine(190); ImGui.Text($"0x{syminfo.address:X}"); ImGui.SameLine(305); ImGui.Text($"{syminfo.threadNodes.Count}"); ImGui.EndGroup(); if (!syminfo.selected) { if (ImGui.IsItemHovered(ImGuiHoveredFlags.None)) { if (syminfo.hovered == false) { syminfo.hovered = true; HandleMouseoverSym(plot, module_modentry, syminfo); } } else { if (syminfo.hovered == true) { syminfo.hovered = false; HandleMouseoverSym(plot, module_modentry, syminfo); } } } } ImGui.TreePop(); } } } }
private static void DrawThreadSelectorCombo(TraceRecord?trace, out PlottedGraph?selectedGraph, bool abbreviate) { selectedGraph = null; ProtoGraph?graph = rgatState.ActiveGraph?.InternalProtoGraph; if (trace is not null && graph is not null) { string selString = $"{(abbreviate ? "TID" : "Thread")} {graph.ThreadID}: {graph.FirstInstrumentedModuleName}"; if (graph.NodeCount == 0) { selString += " [Uninstrumented]"; } List <PlottedGraph> graphs = trace.GetPlottedGraphs(); if (ImGui.TableNextColumn()) { ImGui.AlignTextToFramePadding(); ImGuiUtils.DrawHorizCenteredText($"{graphs.Count}x"); SmallWidgets.MouseoverText($"This trace has {graphs.Count} thread{(graphs.Count != 1 ? 's' : "")}"); } if (ImGui.TableNextColumn()) { ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 35); if (ImGui.BeginCombo("##SelectorThreadCombo", selString)) { foreach (PlottedGraph selectablegraph in graphs) { string caption = $"{selectablegraph.TID}: {selectablegraph.InternalProtoGraph.FirstInstrumentedModuleName}"; int nodeCount = selectablegraph.GraphNodeCount(); if (nodeCount == 0) { ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.Dull1)); caption += " [Uninstrumented]"; } else { ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.WindowText)); caption += $" [{nodeCount} nodes]"; } if (ImGui.Selectable(caption, graph.ThreadID == selectablegraph.TID) && nodeCount > 0) { selectedGraph = selectablegraph; } if (ImGui.IsItemHovered()) { ImGui.BeginTooltip(); ImGui.Text($"Thread Start: 0x{selectablegraph.InternalProtoGraph.StartAddress:X} [{selectablegraph.InternalProtoGraph.StartModuleName}]"); if (selectablegraph.InternalProtoGraph.NodeList.Count > 0) { NodeData?n = selectablegraph.InternalProtoGraph.GetNode(0); if (n is not null) { string insBase = System.IO.Path.GetFileName(graph.ProcessData.GetModulePath(n.GlobalModuleID)); ImGui.Text($"First Instrumented: 0x{n.Address:X} [{insBase}]"); } } ImGui.EndTooltip(); } ImGui.PopStyleColor(); } ImGui.EndCombo(); } ImGui.SameLine(); ImGui.Text($"{ImGuiController.FA_ICON_COG}"); } } }
public void Draw(ImFontPtr font) { Vector2 availArea = ImGui.GetContentRegionAvail(); Vector2 targetSize = availArea - new Vector2(0, 6); if (targetSize != chartSize && targetSize.X > 50 && targetSize.Y > 50) { StopLayout(); chartSize = targetSize; layout.Parameters.Width = targetSize.X; layout.Parameters.Height = targetSize.Y; FitNodesToChart(); } if (_fittingActive) { DoLayoutFittingCycle(); } if (_computeRequired && !_layoutActive) { _layoutActive = true; _computeRequired = false; Task.Run(() => { layout.Compute(); _layoutActive = false; }); } ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.SandboxChartBG)); bool nodeClicked = false; Vector2 cursorPos = ImGui.GetCursorPos(); Vector2 chartPos = cursorPos + chartOffset + new Vector2(padding, padding); if (ImGui.BeginChild("ChartFrame", chartSize, false, ImGuiWindowFlags.NoScrollbar)) { MouseOverWidget = ImGui.IsMouseHoveringRect(cursorPos, cursorPos + chartSize); if (MouseOverWidget) { HandleMouseInput(); } var edges = sbgraph.Edges; List <Tuple <ItemNode, ItemNode> > drawnEdges = new List <Tuple <ItemNode, ItemNode> >(); var positions = new Dictionary <ItemNode, GraphShape.Point>(layout.VerticesPositions); foreach (var edge in edges) { if (positions.TryGetValue(edge.Source, out GraphShape.Point srcPoint) && positions.TryGetValue(edge.Target, out GraphShape.Point targPoint)) { Vector2 sourcePos = chartPos + Point2Vec(srcPoint); Vector2 targPos = chartPos + Point2Vec(targPoint); Tuple <ItemNode, ItemNode> edgeTuple = new Tuple <ItemNode, ItemNode>(edge.Source, edge.Target); if (drawnEdges.Contains(edgeTuple)) { continue; } drawnEdges.Add(edgeTuple); ImGui.GetWindowDrawList().AddLine(sourcePos, targPos, 0xffff00ff); if (_edgeLabels.TryGetValue(edgeTuple, out List <string>?edgeLabels)) { ImGui.GetWindowDrawList().AddText(Vector2.Lerp(sourcePos, targPos, 0.5f), 0xff000000, string.Join(",", edgeLabels)); } } } foreach (var node in positions) { Vector2 nCenter = chartPos + Point2Vec(node.Value); nodeClicked = nodeClicked || DrawNode(node.Key, nCenter, font); } ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(5, 5)); ImGui.SetCursorPos(chartSize - new Vector2(60, 30)); ImGui.BeginGroup(); if (ImGui.Button($"{ImGuiController.FA_ICON_REFRESH}", new Vector2(26, 27))) //refresh button { timelineItemsOnChartDraw = 0; } SmallWidgets.MouseoverText("Force Replot"); if (!_fittingActive) { ImGui.SameLine(30); if (ImGui.Button($"{ImGuiController.FA_ICON_MOVEMENT}", new Vector2(26, 27))) //centering button { FitNodesToChart(); } SmallWidgets.MouseoverText("Center graph"); } ImGui.EndGroup(); ImGui.PopStyleVar(); ImGui.SetCursorScreenPos(cursorPos); ImGui.EndChild(); } ImGui.PopStyleColor(); if (ImGui.IsMouseClicked(ImGuiMouseButton.Left) is true && nodeClicked is false) { _selectedNode = null; } }