class CollapsibleWidget(QWidget): """a dialog to which collapsible sections can be added; subclass and reimplement define_sections() to define sections and add them as (title, widget) tuples to self.sections """ def __init__(self): super().__init__() self.tree = QTreeWidget() self.tree.setHeaderHidden(True) self.tree.setPalette(get_verifone_color()) self.setStyleSheet("background-color: rgba(3, 169, 229, 0)") layout = QVBoxLayout() self.buttonGroup = QButtonGroup() layout.addWidget(self.tree) self.setLayout(layout) self.tree.setIndentation(0) self.setPalette(get_verifone_color()) self.sections = [] self.setFixedWidth(500) def get_tree(self): return self.tree def add_sections(self): """adds a collapsible sections for every (title, widget) tuple in self.sections """ for (title, widget) in self.sections: button1 = self.add_button(title) section1 = self.add_widget(button1, widget) button1.addChild(section1) def include_section(self, title, frame): """reimplement this to define all your sections and add them as (title, widget) tuples to self.sections """ self.sections.append((title, frame)) def add_button(self, title): """creates a QTreeWidgetItem containing a button to expand or collapse its section """ item = QTreeWidgetItem() item.setBackgroundColor(0, QColor(3, 169, 229)) self.tree.addTopLevelItem(item) self.tree.setItemWidget(item, 0, SectionExpandButton(item, text = title, group = self.buttonGroup)) return item def add_widget(self, button, widget): """creates a QWidgetItem containing the widget, as child of the button-QWidgetItem """ section = QTreeWidgetItem(button) section.setDisabled(True) section.setBackgroundColor(0, QColor(3, 169, 229)) self.tree.setItemWidget(section, 0, widget) return section
class CollapsibleDialog(QDialog): """a dialog to which collapsible sections can be added; subclass and reimplement define_sections() to define sections and add them as (title, widget) tuples to self.sections """ def __init__(self): super().__init__() self.tree = QTreeWidget() self.tree.setHeaderHidden(True) layout = QVBoxLayout() layout.addWidget(self.tree) self.setLayout(layout) self.tree.setIndentation(0) self.sections = [] self.define_sections() self.add_sections() def add_sections(self): """adds a collapsible sections for every (title, widget) tuple in self.sections """ for (title, widget) in self.sections: button1 = self.add_button(title) section1 = self.add_widget(button1, widget) button1.addChild(section1) def define_sections(self): """reimplement this to define all your sections and add them as (title, widget) tuples to self.sections """ widget = QFrame(self.tree) layout = QHBoxLayout(widget) layout.addWidget(QLabel("Bla")) layout.addWidget(QLabel("Blubb")) title = "Section 1" self.sections.append((title, widget)) def add_button(self, title): """creates a QTreeWidgetItem containing a button to expand or collapse its section """ item = QTreeWidgetItem() self.tree.addTopLevelItem(item) self.tree.setItemWidget(item, 0, SectionExpandButton(item, text=title)) return item def add_widget(self, button, widget): """creates a QWidgetItem containing the widget, as child of the button-QWidgetItem """ section = QTreeWidgetItem(button) section.setDisabled(True) self.tree.setItemWidget(section, 0, widget) return section
def add_tree_no_header(self, parent): tw = QTreeWidget() parent.addWidget(tw) tw.setHeaderHidden(True) tw.setAlternatingRowColors(True) i1 = QTreeWidgetItem(tw, ['Mammal']) i2 = QTreeWidgetItem(i1, ['Rodent']) i3 = QTreeWidgetItem(i2, ['Rat']) i3 = QTreeWidgetItem(i2, ['Beaver']) i2 = QTreeWidgetItem(i1, ['Primate']) i3 = QTreeWidgetItem(i2, ['Baboon']) i3 = QTreeWidgetItem(i2, ['Human']) i1 = QTreeWidgetItem(tw, ['Reptile']) i2 = QTreeWidgetItem(i1, ['Snake']) i3 = QTreeWidgetItem(i1, ['Crocodile']) self.add_expand_collapse_buttons(parent, tw)
def _init_finds_tab(self, tab): finds_list = QTreeWidget() finds_list.setHeaderHidden(True) self._finds_list = finds_list layout = QVBoxLayout() layout.addWidget(finds_list) frame = QFrame() frame.setLayout(layout) import_button = QPushButton("Import List") import_button.clicked.connect(lambda: self._import_to_list(self._finds_list)) layout.addWidget(import_button) tab.addTab(frame, 'Finds') self._finds_list.itemChanged.connect(self._on_explore_addr_changed)
class ComponentsView(BaseView): def __init__(self, workspace, default_docking_position, *args, **kwargs): super().__init__('components', workspace, default_docking_position, *args, **kwargs) self.caption = "Components" self.width_hint = 100 self.height_hint = 100 self._tree: QTreeWidget = None self._init_widgets() def _init_widgets(self): self._tree = QTreeWidget() self._tree.setHeaderHidden(True) self._tree.itemDoubleClicked.connect(self.on_item_doubleclicked) layout = QVBoxLayout() layout.addWidget(self._tree) self.setLayout(layout) def minimumSizeHint(self) -> PySide2.QtCore.QSize: return QSize(100, 100) def load(self, tree: ComponentTree): """ Display a component tree. """ if self.workspace.instance.project is None: return proj = self.workspace.instance.project funcs = self.workspace.instance.kb.functions self._tree.clear() queue: List[Tuple[ComponentTreeNode, Optional[QComponentItem]]] = [(tree.root, None)] while queue: node, parent = queue.pop(0) if parent is None: # this is the root parent = self._tree # create a widget item item = QComponentItem(parent, node) # add all functions for comp_func in node.functions: try: func = funcs.get_by_addr( proj.loader.main_object.mapped_base + comp_func.virtual_addr) except KeyError: func = None func_node = QFunctionItem(self.workspace.instance.project, item, comp_func, function=func) item.function_nodes.append(func_node) # insert all components into the queue for comp in node.components: queue.append((comp, item)) def reset(self): self._tree.clear() # # Event # def on_item_doubleclicked(self, item: QTreeWidgetItem, column: int): if isinstance(item, QFunctionItem): if item.function is not None: # display the function, either in the disassembly view or in the pseudo code view self.workspace.on_function_selected(item.function) else: # jump to the function address self.workspace.jump_to(item.func_addr)
def _init_widgets(self): layout = QGridLayout() row = 0 validation_failures = set() # name name_label = QLabel(self) name_label.setText("Name") name_box = QLineEdit(self) name_box.setText(NameGenerator.random_name()) def handle_name(txt): nonlocal validation_failures key = {'name'} if txt and not any(s.gui_data.name == txt for s in self.instance.states): validation_failures -= key else: validation_failures |= key validation_update() name_box.textEdited.connect(handle_name) layout.addWidget(name_label, row, 0) layout.addWidget(name_box, row, 1) row += 1 # address address_label = QLabel(self) address_label.setText("Address") address_box = QLineEdit(self) address_box.setText( hex(self.instance.project.entry ) if self._addr is None else hex(self._addr)) def handle_address(_): nonlocal validation_failures key = {'addr'} if parse_address() is not None: validation_failures -= key else: validation_failures |= key validation_update() def parse_address(): txt = address_box.text() try: return self.instance.project.kb.labels.lookup(txt) except KeyError: pass try: return int(txt, 16) except ValueError: return None address_box.textEdited.connect(handle_address) layout.addWidget(address_label, row, 0) layout.addWidget(address_box, row, 1) row += 1 # template template_label = QLabel(self) template_label.setText("Template") template_combo = QComboBox() template_combo.addItem("Blank State", 'blank') template_combo.addItem("Call state", 'call') template_combo.addItem("Entry state", 'entry') template_combo.addItem("Full-init state", 'full') def handle_template(_): base_allowed = template_combo.currentData() in ('blank', 'call') base_state_combo.setHidden(not base_allowed) base_state_label.setHidden(not base_allowed) template_combo.currentIndexChanged.connect(handle_template) layout.addWidget(template_label, row, 0) layout.addWidget(template_combo, row, 1) row += 1 # base state base_state_label = QLabel(self) base_state_label.setText('Base state') base_state_combo = QStateComboBox(self.instance, self) self._base_state_combo = base_state_combo layout.addWidget(base_state_label, row, 0) layout.addWidget(base_state_combo, row, 1) row += 1 # mode mode_label = QLabel(self) mode_label.setText("Mode") mode_combo = QComboBox(self) mode_combo.addItem("Symbolic", "symbolic") mode_combo.addItem("Static", "static") mode_combo.addItem("Fast-path", "fastpath") mode_combo.addItem("Tracing", "tracing") self._mode_combo = mode_combo def mode_changed(): self._options.clear() self._options.update( angr.sim_options.modes[mode_combo.currentData()]) for child in children_items: child.setCheckState( 0, Qt.Checked if child.text(0) in self._options else Qt.Unchecked) mode_combo.currentIndexChanged.connect(mode_changed) self._options.clear() self._options.update(angr.sim_options.modes[mode_combo.currentData()]) layout.addWidget(mode_label, row, 0) layout.addWidget(mode_combo, row, 1) row += 1 # options tree options_label = QLabel(self) options_label.setText("Options") options_tree = QTreeWidget(self) options_tree.setHeaderHidden(True) children_items = [] for name, members in angr.sim_options.__dict__.items(): if type(members) is not set: continue if name == 'resilience_options': continue parent = QTreeWidgetItem(options_tree) parent.setText(0, name) parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for option in members: child = QTreeWidgetItem(parent) child.setText(0, option) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setCheckState( 0, Qt.Checked if option in self._options else Qt.Unchecked) children_items.append(child) parent = QTreeWidgetItem(options_tree) parent.setText(0, "All options") parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for option in { x for x in angr.sim_options.__dict__.values() if type(x) is str and is_option(x) }: child = QTreeWidgetItem(parent) child.setText(0, option) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setCheckState( 0, Qt.Checked if option in self._options else Qt.Unchecked) children_items.append(child) def maintain_model(item: QTreeWidgetItem, _): option = item.text(0) if not is_option(option): return checked = item.checkState(0) if (option in self._options) == checked: return if checked: self._options.add(option) else: self._options.remove(option) for child in children_items: if child is not item and child.text(0) == option: child.setCheckState(0, checked) options_tree.itemChanged.connect(maintain_model) layout.addWidget(options_label, row, 0) layout.addWidget(options_tree, row, 1) row += 1 # options filter options_filter_label = QLabel(self) options_filter_label.setText("") options_filter_box = QLineEdit(self) options_filter_box.setPlaceholderText("Filter") def do_filter(text): for child in children_items: child.setHidden(text.upper() not in child.text(0)) options_filter_box.textEdited.connect(do_filter) layout.addWidget(options_filter_label, row, 0) layout.addWidget(options_filter_box, row, 1) row += 1 # buttons ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): name = name_box.text() template = template_combo.currentData() addr = parse_address() base_state = base_state_combo.state mode = mode_combo.currentData() if template in ('blank', 'call') and base_state is not None: if template == 'blank': self.state = self.instance.project.factory.blank_state( addr=addr, base_state=base_state, options=self._options) else: self.state = self.instance.project.factory.call_state( addr, base_state=base_state, options=self._options) self.state.gui_data.base_name = base_state.gui_data.name else: if template == 'blank': self.state = self.instance.project.factory.blank_state( addr=addr, mode=mode, options=self._options) elif template == 'call': self.state = self.instance.project.factory.call_state( addr, mode=mode, options=self._options) elif template == 'entry': self.state = self.instance.project.factory.entry_state( mode=mode, options=self._options) else: self.state = self.instance.project.factory.full_init_state( mode=mode, options=self._options) self.state.gui_data.base_name = name self.state.gui_data.is_base = True self.state.gui_data.name = name self.state.gui_data.is_original = True if self._create_simgr: self.instance.workspace.create_simulation_manager( self.state, name) self.close() ok_button.clicked.connect(do_ok) def validation_update(): ok_button.setDisabled(bool(validation_failures)) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) self.main_layout.addLayout(layout) self.main_layout.addLayout(buttons_layout)
class DataToDrawSelector(QWidget): exampleDataToDraw = { 'OS': {'Original Signal': None}, 'PS-,PS+': {'Processed Signal -' : None, 'Processed Signal +' : None}, 'OS,PS+': {'Original Signal' : None, 'Processed Signal +' : None}} ''' self.chartSelector = QListWidget() for ch in self.charts: self.chartSelector.addItem(ch) self.chartSelector.currentTextChanged.connect(self.setAtiveChart) return self.chartSelector ''' newChannelSelected = Signal(str, str, dict) newSignalSelected = Signal(str, str, dict) newMaskSelected = Signal(str, str) signalColorChanged = Signal(str, str) def __init__(self, dataManager, chartData, charManager, algManager, parent=None): QWidget.__init__(self, parent) self.dataManager = dataManager self.chartData = chartData self.charManager = charManager self.algManager = algManager self._crateSelectors() self.curSelect = None self.signalPressed = False def _crateSelectors(self): self.mLayout = QVBoxLayout(self) wsLayout = QVBoxLayout() alg = self.algManager self.wsSelector = WorkspaceChooser(alg) self.wsSelector.setMaximumHeight(70) groups = self.chartData.getDataGroups() self.wsSelector.addItems(groups) self.wsSelector.currentTextChanged.connect(self._updateAll) self.chartData.dataGroupAdded.connect(self.addNewGroup) self.mLayout.addWidget(QLabel('Workspaces')) self.mLayout.addWidget(self.wsSelector) self.chartData.allRemoved.connect(self._resetWorkspaces) self.chSelector = QTreeWidget() self.chSelector.setHeaderHidden(True) self.chSelector.itemClicked.connect(self.changeCurrentSelect) self.chSelector.itemChanged.connect(self.itemChanged) self.mLayout.addWidget(QLabel('Channels')) self.mLayout.addWidget(self.chSelector) self.sSelector = SignalChooser() self.sSelector.setHeaderHidden(True) self.sSelector.setDragEnabled(True) self.sSelector.setDropIndicatorShown(True) self.sSelector.setContextMenuPolicy(Qt.CustomContextMenu) self.createSignalPopupMenu(self.sSelector) self.sSelector.customContextMenuRequested.connect(self.onSignalContextMenu) self.sSelector.itemClicked.connect(self.changeCurrentSelect) self.sSelector.itemPressed.connect(self.signalPress) self.sSelector.itemChanged.connect(self.itemChanged) self.mLayout.addWidget(QLabel('Signals')) self.mLayout.addWidget(self.sSelector) self.gSelector = SignalGroupsChooser(self.chartData, self.wsSelector) self.mLayout.addWidget(QLabel('Signal Groups')) self.mLayout.addWidget(self.gSelector) self.wsSelector.setCurrentRow(0) self.chartData.signalAdded.connect(self._updateAll) self.chartData.signalRemoved.connect(self._updateAll) self.chartData.signalGroupAdded.connect(self._updateAll) self.chartData.signalGroupRemoved.connect(self._updateAll) self.chartData.signalToGrupAdded.connect(self._updateAll) self.chartData.signalFromGroupRemoved.connect(self._updateAll) def signalPress(self): self.signalPressed = True def createSignalPopupMenu(self, parent=None): self.popupMenu = QMenu(parent) self.popupMenu.addAction("Process...", self.openSignalProcessingDialog) self.popupMenu.addAction("Apply algorithm...", self.openAlgorithmDialog) self.popupMenu.addAction("Set as Current Mask", self.maskSelected) self.popupMenu.addAction("Change color", self.changeSignalColor) self.popupMenu.addSeparator() self.popupMenu.addAction("Delete", self.deleteSignal) def onSignalContextMenu(self, pos): self.clickedItem = self.sSelector.itemAt(pos) if self.clickedItem is None: return if self.clickedItem.parent() is None: self.popupMenu.exec_(self.sSelector.mapToGlobal(pos)) def deleteSignal(self): ws = self.wsSelector.currentItem().text() signalToDel = self.clickedItem.text(0) self.dataManager.removeSignal(ws, signalToDel) def addNewGroup(self, newGroup, gKind): newItem = QListWidgetItem(newGroup) newItem.setData(1, gKind) self.wsSelector.addItem(newItem) self.wsSelector.setCurrentItem(newItem) def _resetWorkspaces(self): self.wsSelector.currentTextChanged.disconnect(self._updateAll) wsCount = self.wsSelector.count() for i in range(wsCount-1, -1, -1): self.wsSelector.takeItem(i) self.wsSelector.currentTextChanged.connect(self._updateAll) def _updateAll(self, newGroup=None): try: self.chSelector.itemChanged.disconnect(self.itemChanged) self.sSelector.itemChanged.disconnect(self.itemChanged) except: pass if newGroup == '': return chStruct = self.chartData[newGroup] sStruct = self.chartData[newGroup].getColStructure() self.chSelector.clear() for ws in chStruct: gparent = QTreeWidgetItem(self.chSelector) gparent.setText(0, ws) gparent.setBackgroundColor(0, Qt.white) gparent.setFlags(Qt.ItemIsEnabled) for key in chStruct[ws]: parent = QTreeWidgetItem(gparent) parent.setText(0, key) if chStruct[ws][key][0] == True: dataNames = chStruct[ws][key][3] sColor = QColor(chStruct[ws][key][4]) sColor.setAlpha(100) parent.setBackgroundColor(0, sColor) else: dataNames = ','.join(chStruct[ws][key][2]) sColor = QColor(chStruct[ws][key][3]) sColor.setAlpha(100) parent.setBackgroundColor(0, sColor) parent.setText(1, dataNames) if chStruct[ws][key][1] == True: parent.setCheckState(0, Qt.Checked) else: parent.setCheckState(0, Qt.Unchecked) parent.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.sSelector.clear() self.gSelector.clear() for ws in sStruct: firstChannel = sStruct[ws][0] isOneSignal = self.chartData[newGroup][firstChannel][ws][0] if isOneSignal: gparent = QTreeWidgetItem(self.sSelector) gparent.setText(0, ws) gparent.setFlags(Qt.ItemIsEnabled | Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable) if True: ## if chStruct['CH1'][ws][5] == True: gparent.setCheckState(0, Qt.Checked) else: gparent.setCheckState(0, Qt.Unchecked) for key in sStruct[ws]: parent = QTreeWidgetItem(gparent) parent.setText(0, key) if chStruct[key][ws][2] == True: parent.setCheckState(0, Qt.Checked) else: parent.setCheckState(0, Qt.Unchecked) parent.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) sColor = QColor(chStruct[key][ws][4]) sColor.setAlpha(100) sGradient = QLinearGradient(0, 0, 100, 10) sGradient.setColorAt(0, sColor) sGradient.setColorAt(1, Qt.white) sBrush = QBrush(sGradient) sBrush.setStyle(Qt.LinearGradientPattern) sBrush.setColor(sColor) gparent.setBackground(0, sBrush) else: gparent = QTreeWidgetItem(self.gSelector) gparent.setText(0, ws) gparent.setFlags(Qt.ItemIsEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsUserCheckable) if chStruct['CH1'][ws][5] == True: gparent.setCheckState(0, Qt.Checked) else: gparent.setCheckState(0, Qt.Unchecked) signalNames = chStruct[key][ws][2] sColor = QColor(chStruct[key][ws][3]) sColor.setAlpha(100) gparent.setBackgroundColor(0, sColor) for signal in signalNames: parent = QTreeWidgetItem(gparent) parent.setText(0, signal) parent.setFlags(Qt.ItemIsEnabled) for key in sStruct[signal]: sColor = QColor(chStruct[key][signal][4]) sColor.setAlpha(100) parent.setBackgroundColor(0, sColor) break self.chSelector.itemChanged.connect(self.itemChanged) self.sSelector.itemChanged.connect(self.itemChanged) self.curSelect = None def _updateSignalColor(self, signalName, newColor): chIter = QTreeWidgetItemIterator(self.chSelector, QTreeWidgetItemIterator.Checked) while chIter.value(): if chIter.value().text(0) == signalName: sColor = QColor(newColor) sColor.setAlpha(100) chIter.value().setBackgroundColor(0, sColor) chIter += 1 sIter = QTreeWidgetItemIterator(self.sSelector) while sIter.value(): if sIter.value().text(0) == signalName: sColor = QColor(newColor) sColor.setAlpha(100) sGradient = QLinearGradient(0, 0, 100, 10) sGradient.setColorAt(0, sColor) sGradient.setColorAt(1, Qt.white) sBrush = QBrush(sGradient) sBrush.setStyle(Qt.LinearGradientPattern) sBrush.setColor(sColor) sIter.value().setBackground(0, sBrush) if sIter.value() is self.curSelect: self.prevBackGround = sIter.value().background(0) sIter += 1 self.changeCurrentSelect(self.curSelect) def changeCurrentSelect(self, newItem): if newItem is None: print('newItem is None') self.curSelect = None return if (newItem.treeWidget() is self.sSelector and not self.signalPressed): ws = self.wsSelector.currentItem().text() isChecked = [True if newItem.checkState(0) is Qt.Checked else False] channel = 'CH1' signal = newItem.text(0) self.chartData[ws][channel][signal][5] = isChecked[0] return self.signalPressed = False newItem.setSelected(False) if newItem.parent() is None: if self.curSelect is not None: self.curSelect.setFont(0, self.prevFont) self.curSelect.setBackground(0, self.prevBackGround) self.curSelect.setForeground(0, self.prevForeground) self.prevBackGround = newItem.background(0) self.prevForeground = newItem.foreground(0) self.prevFont = newItem.font(0) sBrush = newItem.background(0) sBColor = sBrush.color() sBColor.setAlpha(200) sBrush.setColor(sBColor) sBrush.setStyle(Qt.SolidPattern) sFont = newItem.font(0) sFont.setBold(True) if newItem.treeWidget() is self.chSelector: sBrush.setColor(QColor(56, 211, 255, 120)) newItem.setBackground(0, sBrush) newItem.setForeground(0, QBrush(Qt.white)) newItem.setFont(0, sFont) self.curSelect = newItem if self.curSelect.treeWidget() is self.chSelector: self.ChannelSelected() elif self.curSelect.treeWidget() is self.sSelector: self.SignalSelected() def ChannelSelected(self): dChecked = [] sIter = QTreeWidgetItemIterator(self.sSelector, QTreeWidgetItemIterator.Checked) while sIter.value(): if not sIter.value().parent(): dChecked.append(sIter.value().text(0)) sIter += 1 gIter = QTreeWidgetItemIterator(self.gSelector, QTreeWidgetItemIterator.Checked) while gIter.value(): if not gIter.value().parent(): dChecked.append(gIter.value().text(0)) gIter += 1 chStruct = {} sIter = QTreeWidgetItemIterator(self.curSelect, QTreeWidgetItemIterator.Checked) while (sIter.value() and sIter.value().parent() is self.curSelect and sIter.value().checkState(0) == Qt.Checked): sItem = sIter.value() dataName = sItem.text(0) if dataName in dChecked: chStruct[sItem.text(0)] = None sIter += 1 group = self.wsSelector.currentItem().text() channel = self.curSelect.text(0) self.newChannelSelected.emit(group, channel, chStruct) def SignalSelected(self): sStruct = {} chIter = QTreeWidgetItemIterator(self.curSelect, QTreeWidgetItemIterator.Checked) if not chIter.value().parent(): #Skip signal chIter += 1 while (chIter.value() and chIter.value().parent() is self.curSelect and chIter.value().checkState(0) == Qt.Checked): chItem = chIter.value() sStruct[chItem.text(0)] = None chIter += 1 ws = self.wsSelector.currentItem().text() signal = self.curSelect.text(0) self.newSignalSelected.emit(ws, signal, sStruct) def maskSelected(self): ws = self.wsSelector.currentItem().text() signal = self.clickedItem.text(0) self.newMaskSelected.emit(ws, signal) def changeSignalColor(self): ws = self.wsSelector.currentItem().text() signal = self.clickedItem.text(0) channels = [] sIter = QTreeWidgetItemIterator(self.clickedItem) sIter += 1 # First children while(sIter.value()): if sIter.value().parent() is self.clickedItem: channels.append(sIter.value().text(0)) sIter += 1 else: break sData = self.chartData[ws].getDataFromStructure({signal : channels}, inv=True)[signal] sColor = sData[0][4] newColor = QColorDialog().getColor(QColor(sColor), self) if newColor.isValid(): for sD in sData: sD[4] = newColor.name() self._updateSignalColor(signal, newColor.name()) self.signalColorChanged.emit(ws, signal) def openSignalProcessingDialog(self): ws = self.wsSelector.currentItem().text() signal = self.clickedItem.text(0) dialog = DataProcessingDialog(self.dataManager, self, [ws, signal]) dialog.show() dialog.exec() def openAlgorithmDialog(self): ws = self.wsSelector.currentItem().text() signal = self.clickedItem.text(0) self.algManager.showAlgorithmDialog(ws, signal) def itemChanged(self, item): if item.flags() == (Qt.ItemIsUserCheckable | Qt.ItemIsEnabled): ws = self.wsSelector.currentItem().text() isChecked = [True if item.checkState(0) is Qt.Checked else False] if item.treeWidget() is self.chSelector: channel = item.parent().text(0) signal = item.text(0) self.chartData[ws][channel][signal][1] = isChecked[0] elif item.treeWidget() is self.sSelector: signal = item.parent().text(0) channel = item.text(0) self.chartData[ws][channel][signal][1] = isChecked[0] def addSignalItem(self, group, signal, chList): pass '''
class QDecompilationOptions(QWidget): def __init__(self, code_view, instance, options=None, passes=None, peephole_opts=None): super().__init__() self._code_view = code_view self._instance = instance self._options = options self._opti_passes = passes self._peephole_opts = peephole_opts # widgets self._search_box = None # type:QLineEdit self._treewidget = None # type:QTreeWidget self._apply_btn = None # type:QPushButton self._qoptions = [ ] self._qoptipasses = [ ] self._qpeephole_opts = [ ] self._init_widgets() self.reload() def reload(self, force=False): if force or self._options is None: self._options = self.get_default_options() if force or self._opti_passes is None: if not self._instance.project.am_none: self._opti_passes = self.get_all_passes() else: self._opti_passes = [] if force or self._peephole_opts is None: self._peephole_opts = self.get_all_peephole_opts() self._reload_options() @property def selected_passes(self): selected = [ ] for item in self._qoptipasses: if item.checkState(0): selected.append(item.option) return selected @property def selected_peephole_opts(self): selected = [] for item in self._qpeephole_opts: if item.checkState(0): selected.append(item.option) return selected @property def option_and_values(self): ov = [ ] for item in self._qoptions: if item.checkState(0): ov.append((item.option, True)) else: ov.append((item.option, False)) return ov @property def options(self): return self._options @options.setter def options(self, v): self._options = v self._reload_options() def get_default_options(self): return dec_options def get_default_passes(self): if self._instance is None or self._instance.project.am_none: return set() return get_default_optimization_passes(self._instance.project.arch, self._instance.project.simos.name) def get_all_passes(self): return get_optimization_passes(self._instance.project.arch, self._instance.project.simos.name) def get_default_peephole_opts(self): return STMT_OPTS + EXPR_OPTS def get_all_peephole_opts(self): return STMT_OPTS + EXPR_OPTS def _init_widgets(self): # search box self._search_box = QLineEdit() # tree view self._treewidget = QTreeWidget() self._treewidget.setHeaderHidden(True) # refresh button self._apply_btn = QPushButton("Apply") self._apply_btn.clicked.connect(self._code_view.decompile) layout = QVBoxLayout() layout.addWidget(self._search_box) layout.addWidget(self._treewidget) layout.addWidget(self._apply_btn) self.setLayout(layout) def _reload_options(self): self._treewidget.clear() self._qoptions.clear() self._qoptipasses.clear() self._qpeephole_opts.clear() categories = { } # populate the tree widget with new options for option in sorted(self._options, key=lambda x: x.name): if option.category in categories: category = categories[option.category] else: category = QTreeWidgetItem(self._treewidget, [option.category]) w = QDecompilationOption(category, option, OptionType.OPTION, enabled=option.default_value==True) self._qoptions.append(w) passes_category = QTreeWidgetItem(self._treewidget, ["Optimization Passes"]) categories['passes'] = passes_category default_passes = set(self.get_default_passes()) for pass_ in self._opti_passes: w = QDecompilationOption(passes_category, pass_, OptionType.OPTIMIZATION_PASS, enabled=pass_ in default_passes) self._qoptipasses.append(w) po_category = QTreeWidgetItem(self._treewidget, ["Peephole Optimizations"]) categories['peephole_opts'] = po_category default_peephole_opts = self.get_default_peephole_opts() for opt_ in self._peephole_opts: w = QDecompilationOption(po_category, opt_, OptionType.PEEPHOLE_OPTIMIZATION, enabled=opt_ in default_peephole_opts) self._qpeephole_opts.append(w) # expand all self._treewidget.expandAll()
def initUI(self): #Заполнение дерева def treeItems(): categories = Categories().data for key in categories: parent = QTreeWidgetItem(tree) parent.setText(0, key) for item in categories[key]: child = QTreeWidgetItem(parent) child.setText(0, item) #Базовое окно self.setGeometry(0, 0, 1920, 1080) self.setWindowTitle('УНЦ ПроектБалтЭнерго') #Инициализация дерева tree = QTreeWidget(self) tree.setHeaderHidden(True) #Инициализация объектов self.c = Communicate() self.c2 = Communicate() self.c3 = Communicate() self.wid = DataTable() self.table = MainTable() #Создание кнопок font_button = QFont('Helvetica [Cronyx]', 8, QFont.Bold) self.clipboard_button = QPushButton('Буфер') self.export_button = QPushButton('Экспорт в Excel') self.total_button = QPushButton('Итого') self.clipboard_button.setFont(font_button) self.export_button.setFont(font_button) self.total_button.setFont(font_button) #Формирование сигналов self.c.update_table.connect(self.wid.update_table) self.c2.update_main_table.connect(self.table.update_table) self.c3.recalculation.connect(self.table.recalculation) tree.itemClicked.connect(self.onItemClicked) self.wid.cellClicked.connect(self.onTableItemClicked) self.table.cellClicked.connect(self.recalc) self.export_button.clicked.connect(self.export_excel) self.clipboard_button.clicked.connect(self.to_clipboard) #Ининциализация слоев grid = QGridLayout() self.setLayout(grid) hbox = QVBoxLayout() self.export_button.setFixedSize(100, 20) self.total_button.setFixedSize(100, 20) #Заполнение слоев hbox.addWidget(self.clipboard_button) hbox.addWidget(self.export_button) hbox.addWidget(self.total_button) grid.addWidget(tree, 1, 0) grid.addWidget(self.wid, 1, 1) grid.addWidget(self.table, 2, 0, 1, 2) grid.addLayout(hbox, 3, 2) #Заполнить дерево treeItems() self.show()
class QDecompilationOptions(QWidget): def __init__(self, code_view, instance, options=None): super().__init__() self._code_view = code_view self._instance = instance self._options = options if self._options is None: if instance.project is not None: self._options = self.get_default_options() else: self._options = [] # widgets self._search_box = None # type:QLineEdit self._treewidget = None # type:QTreeWidget self._apply_btn = None # type:QPushButton self._qoptions = [] self._init_widgets() self._reload_options() @property def selected_options(self): selected = [] for item in self._qoptions: if item.checkState(0): selected.append(item.option) return selected @property def options(self): return self._options @options.setter def options(self, v): self._options = v self._reload_options() def get_default_options(self): return get_optimization_passes(self._instance.project.arch, self._instance.project.simos.name) def _init_widgets(self): # search box self._search_box = QLineEdit() # tree view self._treewidget = QTreeWidget() self._treewidget.setHeaderHidden(True) # refresh button self._apply_btn = QPushButton("Apply") self._apply_btn.clicked.connect(self._code_view.decompile) layout = QVBoxLayout() layout.addWidget(self._search_box) layout.addWidget(self._treewidget) layout.addWidget(self._apply_btn) self.setLayout(layout) def _reload_options(self): self._treewidget.clear() self._qoptions.clear() # populate the tree widget with new options for option in sorted(self._options, key=lambda x: x.__name__): w = QDecompilationOption(self._treewidget, option) self._qoptions.append(w)
class QDecompilationOptions(QWidget): def __init__(self, code_view, instance, options=None, passes=None, peephole_opts=None): super().__init__() self.dirty = True self._code_view = code_view self._instance = instance self._options = options self._opti_passes = passes self._peephole_opts = peephole_opts # widgets self._search_box = None # type:QLineEdit self._treewidget = None # type:QTreeWidget self._apply_btn = None # type:QPushButton self._qoptions = [ ] self._qoptipasses = [ ] self._qpeephole_opts = [ ] self._init_widgets() self.reload() def reload(self, force=False): if force or self._options is None: self._options = self.get_default_options() if force or self._opti_passes is None: if not self._instance.project.am_none: self._opti_passes = self.get_all_passes() else: self._opti_passes = [] if force or self._peephole_opts is None: self._peephole_opts = self.get_all_peephole_opts() self._reload_options() def _on_item_changed(self, item, _column): if getattr(item.option, 'clears_cache', True): self.dirty = True def _on_apply_pressed(self): if self.dirty: self.dirty = False # clear the cached version self._code_view.decompile(reset_cache=True) else: self._code_view.codegen.reapply_options(self.option_and_values) self._code_view.codegen.am_event() @property def selected_passes(self): selected = [ ] for item in self._qoptipasses: if item.checkState(0): selected.append(item.option) return selected @property def selected_peephole_opts(self): selected = [] for item in self._qpeephole_opts: if item.checkState(0): selected.append(item.option) return selected @property def option_and_values(self): ov = [ ] for item in self._qoptions: if item.checkState(0): ov.append((item.option, True)) else: ov.append((item.option, False)) return ov @property def options(self): return self._options @options.setter def options(self, v): self._options = v self._reload_options() def get_default_options(self): # pylint: disable=no-self-use return dec_options def get_default_passes(self): if self._instance is None or self._instance.project.am_none: return set() return get_default_optimization_passes(self._instance.project.arch, self._instance.project.simos.name) def get_all_passes(self): return get_optimization_passes(self._instance.project.arch, self._instance.project.simos.name) def get_default_peephole_opts(self): # pylint: disable=no-self-use return STMT_OPTS + EXPR_OPTS def get_all_peephole_opts(self): # pylint: disable=no-self-use return STMT_OPTS + EXPR_OPTS def _init_widgets(self): # search box self._search_box = QLineEdit() self._search_box.textChanged.connect(self._on_search_box_text_changed) # tree view self._treewidget = QTreeWidget() self._treewidget.setHeaderHidden(True) self._treewidget.itemChanged.connect(self._on_item_changed) # refresh button self._apply_btn = QPushButton("Apply") self._apply_btn.clicked.connect(self._on_apply_pressed) layout = QVBoxLayout() layout.addWidget(self._search_box) layout.addWidget(self._treewidget) layout.addWidget(self._apply_btn) self.setLayout(layout) def _reload_options(self, filter_by: Optional[str]=None): self._treewidget.clear() self._qoptions.clear() self._qoptipasses.clear() self._qpeephole_opts.clear() categories = { } if filter_by: filter_by = filter_by.lower() # populate the tree widget with new options for option in sorted(self._options, key=lambda x: x.NAME): if filter_by and not (filter_by in option.NAME.lower() or filter_by in option.category.lower()): continue if option.category in categories: category = categories[option.category] else: category = QTreeWidgetItem(self._treewidget, [option.category]) categories[option.category] = category w = QDecompilationOption(category, option, OptionType.OPTION, enabled=option.default_value) self._qoptions.append(w) passes_category = QTreeWidgetItem(self._treewidget, ["Optimization Passes"]) categories['passes'] = passes_category default_passes = set(self.get_default_passes()) for pass_ in self._opti_passes: if filter_by and not (filter_by in pass_.__name__.lower() or filter_by in pass_.NAME.lower()): continue w = QDecompilationOption(passes_category, pass_, OptionType.OPTIMIZATION_PASS, enabled=pass_ in default_passes) self._qoptipasses.append(w) po_category = QTreeWidgetItem(self._treewidget, ["Peephole Optimizations"]) categories['peephole_opts'] = po_category default_peephole_opts = self.get_default_peephole_opts() for opt_ in self._peephole_opts: if filter_by and not (filter_by in opt_.NAME.lower() or filter_by in opt_.DESCRIPTION.lower()): continue w = QDecompilationOption(po_category, opt_, OptionType.PEEPHOLE_OPTIMIZATION, enabled=opt_ in default_peephole_opts) self._qpeephole_opts.append(w) # expand all self._treewidget.expandAll() def _on_search_box_text_changed(self, text: str): self._reload_options(filter_by=text)
def _init_widgets(self): layout = QGridLayout() row = 0 validation_failures = set() # name name_label = QLabel(self) name_label.setText("Name") name_box = QLineEdit(self) name_box.setText(NameGenerator.random_name()) def handle_name(txt): nonlocal validation_failures key = {'name'} if txt and not any(s.gui_data.name == txt for s in self.instance.states): validation_failures -= key else: validation_failures |= key validation_update() name_box.textEdited.connect(handle_name) layout.addWidget(name_label, row, 0) layout.addWidget(name_box, row, 1) row += 1 # address address_label = QLabel(self) address_label.setText("Address") address_box = QLineEdit(self) self._address_box = address_box address_box.setText( hex(self.instance.project.entry ) if self._addr is None else hex(self._addr)) def handle_address(_): nonlocal validation_failures key = {'addr'} if parse_address() is not None: validation_failures -= key else: validation_failures |= key validation_update() def parse_address(): txt = address_box.text() try: return self.instance.project.kb.labels.lookup(txt) except KeyError: pass try: return int(txt, 16) except ValueError: return None address_box.textEdited.connect(handle_address) layout.addWidget(address_label, row, 0) layout.addWidget(address_box, row, 1) row += 1 # template template_label = QLabel(self) template_label.setText("Template") template_combo = QComboBox() template_combo.addItem("Blank State", 'blank') template_combo.addItem("Call state", 'call') template_combo.addItem("Entry state", 'entry') template_combo.addItem("Full-init state", 'full') def handle_template(_): base_allowed = template_combo.currentData() in ('blank', 'call') base_state_combo.setHidden(not base_allowed) base_state_label.setHidden(not base_allowed) args_allowed = template_combo.currentData() in ("entry", ) args_label.setHidden(not args_allowed) args_edit.setHidden(not args_allowed) template_combo.currentIndexChanged.connect(handle_template) layout.addWidget(template_label, row, 0) layout.addWidget(template_combo, row, 1) row += 1 # base state base_state_label = QLabel(self) base_state_label.setText('Base state') base_state_combo = QStateComboBox(self.instance, self) self._base_state_combo = base_state_combo layout.addWidget(base_state_label, row, 0) layout.addWidget(base_state_combo, row, 1) row += 1 # args args_label = QLabel(self) args_label.setText('Args') args_edit = QLineEdit(self) self._args_edit = args_edit def handle_args(): self._args = [ self.instance.project.filename.encode() or b'dummy_filename' ] for x in args_edit.text().split(): if len(x) > 2 and x[0] == "`" and x[-1] == "`": tmp = [ symbol for symbol in self.instance.symbols if symbol.args[0].split('_')[0] == x[1:-1] ] if len(tmp) == 1: self._args.append(tmp[0]) else: self._args.append(x.encode()) args_edit.editingFinished.connect(handle_args) layout.addWidget(args_label, row, 0) layout.addWidget(args_edit, row, 1) row += 1 # fs_mount fs_label = QLabel(self) fs_label.setText('Filesystem') fs_button = QPushButton(self) fs_button.setText("Change") layout.addWidget(fs_label, row, 0) layout.addWidget(fs_button, row, 1) def fs_edit_button(): fs_dialog = FilesystemMount(fs_config=self._fs_config, instance=self.instance, parent=self) fs_dialog.exec_() self._fs_config = fs_dialog.fs_config fs_button.setText("{} Items".format(len(self._fs_config))) fs_button.clicked.connect(fs_edit_button) row += 1 # mode mode_label = QLabel(self) mode_label.setText("Mode") mode_combo = QComboBox(self) mode_combo.addItem("Symbolic", "symbolic") mode_combo.addItem("Static", "static") mode_combo.addItem("Fast-path", "fastpath") mode_combo.addItem("Tracing", "tracing") self._mode_combo = mode_combo def mode_changed(): if mode_combo.currentData() == "tracing": TraceState(self.instance, self._base_state_combo, self._address_box) self._options.clear() self._options.update( angr.sim_options.modes[mode_combo.currentData()]) for child in children_items: child.setCheckState( 0, Qt.Checked if child.text(0) in self._options else Qt.Unchecked) mode_combo.currentIndexChanged.connect(mode_changed) self._options.clear() self._options.update(angr.sim_options.modes[mode_combo.currentData()]) layout.addWidget(mode_label, row, 0) layout.addWidget(mode_combo, row, 1) row += 1 # options tree options_label = QLabel(self) options_label.setText("Options") options_tree = QTreeWidget(self) options_tree.setHeaderHidden(True) children_items = [] for name, members in angr.sim_options.__dict__.items(): if type(members) is not set: continue if name == 'resilience_options': continue parent = QTreeWidgetItem(options_tree) parent.setText(0, name) parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for option in members: child = QTreeWidgetItem(parent) child.setText(0, option) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setCheckState( 0, Qt.Checked if option in self._options else Qt.Unchecked) children_items.append(child) parent = QTreeWidgetItem(options_tree) parent.setText(0, "All options") parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for option in { x for x in angr.sim_options.__dict__.values() if type(x) is str and is_option(x) }: child = QTreeWidgetItem(parent) child.setText(0, option) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setCheckState( 0, Qt.Checked if option in self._options else Qt.Unchecked) children_items.append(child) def maintain_model(item: QTreeWidgetItem, _): option = item.text(0) if not is_option(option): return checked = item.checkState(0) if (option in self._options) == checked: return if checked: self._options.add(option) else: self._options.remove(option) for child in children_items: if child is not item and child.text(0) == option: child.setCheckState(0, checked) options_tree.itemChanged.connect(maintain_model) layout.addWidget(options_label, row, 0) layout.addWidget(options_tree, row, 1) row += 1 # options filter options_filter_label = QLabel(self) options_filter_label.setText("") options_filter_box = QLineEdit(self) options_filter_box.setPlaceholderText("Filter") def do_filter(text): for child in children_items: child.setHidden(text.upper() not in child.text(0)) options_filter_box.textEdited.connect(do_filter) layout.addWidget(options_filter_label, row, 0) layout.addWidget(options_filter_box, row, 1) row += 1 # buttons ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): name = name_box.text() template = template_combo.currentData() addr = parse_address() base_state = base_state_combo.state mode = mode_combo.currentData() if template in ('blank', 'call') and base_state is not None: if template == 'blank': self.state = self.instance.project.factory.blank_state( addr=addr, base_state=base_state, options=self._options) else: self.state = self.instance.project.factory.call_state( addr, base_state=base_state, options=self._options) self.state.gui_data.base_name = base_state.gui_data.name else: if template == 'blank': self.state = self.instance.project.factory.blank_state( addr=addr, mode=mode, options=self._options) elif template == 'call': self.state = self.instance.project.factory.call_state( addr, mode=mode, options=self._options) elif template == 'entry': self.state = self.instance.project.factory.entry_state( mode=mode, options=self._options, args=self._args) else: self.state = self.instance.project.factory.full_init_state( mode=mode, options=self._options) self.state.gui_data.base_name = name self.state.gui_data.is_base = True self.state.gui_data.name = name self.state.gui_data.is_original = True # TODO: there should prob be an am_event here def attach_addr_annotation(state): for i in range(len(state.solver.constraints)): if SrcAddrAnnotation not in [ type(a) for a in state.solver.constraints[i].annotations ]: state.solver.constraints[i] = \ state.solver.constraints[i].annotate(SrcAddrAnnotation(state.addr)) return state self.state.inspect.b(event_type='constraints', when=angr.BP_AFTER, action=attach_addr_annotation) # mount fs if self._fs_config: for path, real in self._fs_config: if os.path.isdir(real): fs = angr.SimHostFilesystem(real) fs.set_state(self.state) self.state.fs.mount(path, fs) if self._create_simgr: self.instance.workspace.create_simulation_manager( self.state, name) self.close() ok_button.clicked.connect(do_ok) def validation_update(): ok_button.setDisabled(bool(validation_failures)) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) self.main_layout.addLayout(layout) self.main_layout.addLayout(buttons_layout)