diff --git a/pate_binja/pate.py b/pate_binja/pate.py index 90156ed0..9af408fc 100644 --- a/pate_binja/pate.py +++ b/pate_binja/pate.py @@ -371,28 +371,34 @@ def extract_graph_rec(self, existing_cfar_node = cfar_graph.get(id) cfar_node = cfar_graph.add_node(id, this, rec) + # Look for observable difference trace for this node + for n in rec['trace_node_contents']: + if n.get('pretty') == 'Observable difference found': + traceContent = rec['trace_node_contents'][n['index'] + 1] + cfar_node.observableDiffTrace = traceContent['content'] + break + elif rec['trace_node_kind'] == 'blocktarget': id = get_blocktarget_id(rec, context, cfar_parent) existing_cfar_node = cfar_graph.get(id) cfar_node = cfar_graph.add_node(id, this, rec) - # If we created a CFAR node and have a parent, link them up. - if cfar_node and cfar_parent: + # connect block target (ie exit) to parent cfar_exit = cfar_node cfar_parent.addExit(cfar_node) - if rec['trace_node_kind'] == 'blocktarget': - for c in rec['trace_node_contents']: - if c.get('content') and c['content'].get('traces', {}): - cfar_parent.addExitMetaData(cfar_exit, 'event_trace', c['content']) + # Look for event trace on this exit + for c in rec['trace_node_contents']: + if c.get('content') and c['content'].get('traces', {}): + cfar_parent.addExitMetaData(cfar_exit, 'event_trace', c['content']) + break - observableDiff = next( - (n for n in rec['trace_node_contents'] if n.get('pretty') == 'Observable difference found'), None) - if observableDiff: - traceContent = rec['trace_node_contents'][observableDiff['index'] + 1] - cfar_parent.addExitMetaData(cfar_exit, 'observable_diff_trace', traceContent['content']) - # don't go any deeper - return + # Look for observable difference trace for this node + for n in rec['trace_node_contents']: + if n.get('pretty') == 'Observable difference found': + traceContent = rec['trace_node_contents'][n['index'] + 1] + cfar_parent.observableDiffTrace = traceContent['content'] + break if self.debug_cfar: print('CFAR ID (parent):', cfar_parent.id) @@ -762,6 +768,7 @@ def __init__(self, id: str, desc: str, data: dict): self.traceConstraints = None self.instruction_trees = None self.wideningInfo = None + self.observableDiffTrace = None # After default initializations above, update the node self.update_node(desc, data) diff --git a/pate_binja/view.py b/pate_binja/view.py index 6c2a8854..a706b91a 100644 --- a/pate_binja/view.py +++ b/pate_binja/view.py @@ -1245,6 +1245,11 @@ def nodePopupMenu(self, event: QMouseEvent, node: FlowGraphNode): action.triggered.connect(lambda _: self.showWideningInfoDialog(cfarNode)) menu.addAction(action) + if cfarNode.observableDiffTrace: + action = QAction(f'Show Observable Diff Trace', self) + action.triggered.connect(lambda _: self.showObservableDiffTrace(cfarNode, 'Observable Diff Trace')) + menu.addAction(action) + if menu.actions(): menu.exec_(event.globalPos()) @@ -1256,6 +1261,12 @@ def showWideningInfoDialog(self, cfarNode: pate.CFARNode): d = PateWideningInfoDialog(cfarNode, parent=self) d.show() + def showObservableDiffTrace(self, cfarNode: pate.CFARNode, label: str = None): + d = PateCfarExitDialog(self) + d.setWindowTitle(f'Observable Diff Trace - {cfarNode.id}') + d.setTrace(cfarNode.observableDiffTrace, label) + d.show() + def edgePopupMenu(self, event: QMouseEvent, edgeTuple: tuple[FlowGraphEdge, bool]): edge = edgeTuple[0] incoming = edgeTuple[1] # Direction of edge depends on which half was clicked @@ -1283,13 +1294,6 @@ def edgePopupMenu(self, event: QMouseEvent, edgeTuple: tuple[FlowGraphEdge, bool sourceCfarNode.id + " to exit " + exitCfarNode.id)) menu.addAction(action) - if exitMetaData.get('observable_diff_trace'): - action = QAction(f'Show Observable Diff Trace', self) - action.triggered.connect(lambda _: self.showExitTraceInfo(sourceCfarNode, exitCfarNode, - exitMetaData['observable_diff_trace'], - 'Observable Diff Trace')) - menu.addAction(action) - if menu.actions(): menu.exec_(event.globalPos())