Пример #1
0
 def repositionCaret(self):
     self.updateCache()
     found = False
     for i in range(0, len(self.lines)):
         if (((self.cursorAddr >= self.lines[i].address) and
              (self.cursorAddr <
               (self.lines[i].address + self.lines[i].length)))
                 or (((i + 1) == len(self.lines)) and
                     (self.cursorAddr
                      == (self.lines[i].address + self.lines[i].length)))):
             if i < self.topLine:
                 self.topLine = i
             elif i > (self.topLine + self.visibleRows - 1):
                 self.topLine = i - (self.visibleRows - 1)
             self.updatingScrollBar = True
             addr = self.lines[self.topLine].address
             self.verticalScrollBar().setValue(
                 self.getContiguousOffsetForAddress(addr) //
                 self.scrollBarMultiplier)
             self.updatingScrollBar = False
             self.updateCache()
             self.viewport().update()
             found = True
             break
     if not found:
         self.setTopToAddress(self.cursorAddr)
         self.refreshLines()
         self.showContextAroundTop()
     # Force caret to be visible and repaint
     self.caretBlink = True
     self.cursorTimer.stop()
     self.cursorTimer.start()
     self.updateCaret()
     UIContext.updateStatus()
Пример #2
0
def executeSnippet(code, description):
    #Get UI context, try currently selected otherwise default to the first one if the snippet widget is selected.
    ctx = UIContext.activeContext()
    dummycontext = {
        'binaryView': None,
        'address': None,
        'function': None,
        'token': None,
        'lowLevelILFunction': None,
        'mediumLevelILFunction': None
    }
    if not ctx:
        ctx = UIContext.allContexts()[0]
    if not ctx:
        #There is no tab open at all but we still want other snippest to run that don't rely on context.
        context = namedtuple("context",
                             dummycontext.keys())(*dummycontext.values())

    else:
        handler = ctx.contentActionHandler()
        if handler:
            context = handler.actionContext()
        else:
            context = namedtuple("context",
                                 dummycontext.keys())(*dummycontext.values())

    snippetGlobals = setupGlobals(context)

    SnippetTask(code, snippetGlobals, context, snippetName=description).start()
Пример #3
0
    def __init__(self):
        UIContextNotification.__init__(self)
        UIContext.registerNotification(self)
        self.request_handler = RequestHandler(self)
        self.client_listener = None
        self.client = None
        self.next_tab_lock = threading.Event()
        self.pgm_mgr = ProgramManager()

        # binary ninja objects
        self.widget = None
        self.view_frame = None
        self.view = None
        self.binary_view = None
        self.frame = None

        # context
        self.current_tab = None
        self.current_pgm = None
        self.target_tab = None
        self.base = None
        self.base_remote = None
        self.sync_enabled = False
        self.sync_mode_auto = True
        self.cb_trace_enabled = False
Пример #4
0
    def __init__(self, widget):
        UIContextNotification.__init__(self)
        self.widget = widget

        # __del__ will not be called because the widget owns a reference to this object. Use
        # QWidget.destroyed event to know when to stop listening for notifications.
        self.widget.destroyed.connect(self.destroyed)

        UIContext.registerNotification(self)
Пример #5
0
def display_block(bv, addr):
    view = bv.view

    # Navigate to location in view
    result = bv.file.navigate(view, addr)
    if result is False:
        view = "Linear:" + view.split(":")[1]
        result = bv.file.navigate(view, addr)

    # Switch displayed view
    UIContext.activeContext().navigateForBinaryView(bv, addr)
Пример #6
0
 def selectNone(self):
     for i in self.lines:
         if (self.cursorAddr >=
                 i.address) and (self.cursorAddr <
                                 (i.address + i.length)) and i.separator:
             self.cursorAddr = i.address + i.length
             break
     self.selectionStartAddr = self.cursorAddr
     if self.selectionVisible:
         self.viewport().update()
     self.repositionCaret()
     UIContext.updateStatus()
    def view_memory(self):
        memory_view = self.parent().view.session_data['emulator.memory.view']

        ctx = UIContext.activeContext()
        linear_view = LinearView(memory_view, None)
        memory_view.register_notification(linear_view)
        ctx.createTabForWidget('Emulator Memory', linear_view)
Пример #8
0
    def current_function(self, message_box=False) -> Optional[Function]:
        all_contexts = UIContext.allContexts()
        if not all_contexts:
            if message_box:
                show_message_box(
                    "UI contexts not found",
                    "No UI context is available. Please open a binary first.",
                    MessageBoxButtonSet.OKButtonSet,
                    MessageBoxIcon.ErrorIcon,
                )
            return
        ctx = all_contexts[0]
        handler = ctx.contentActionHandler()
        if handler is None:
            if message_box:
                show_message_box(
                    "Action handler not found",
                    "No action handler is available. Please open a binary first.",
                    MessageBoxButtonSet.OKButtonSet,
                    MessageBoxIcon.ErrorIcon,
                )
            return
        actionContext = handler.actionContext()
        func = actionContext.function
        if func is None:
            if message_box:
                show_message_box(
                    "No function is in selection",
                    "Please navigate to a function in the disassembly view.",
                    MessageBoxButtonSet.OKButtonSet,
                    MessageBoxIcon.ErrorIcon,
                )
            return None

        return func
Пример #9
0
    def init(self):
        self.raw = self.data
        self.binary = self.raw.read(0, len(self.raw))
        macho_list = self.get_macho_names(self.data, len(self.raw))

        print(f"Found {len(macho_list)} apps")
        [print(f" - {macho}") for macho in macho_list]

        offset = self.get_header_offset()
        sep_fw_header = self.get_fw_header(offset)
        offset += 0xC8

        choice = interaction.get_choice_input("sep-firmware modules",
                                              "choices", macho_list)
        if choice is not None:
            print(f"extracting {macho_list[choice]}")
            if choice == 0:
                app = self.extract_sepos_kernel(sep_fw_header)
            elif choice == 1:
                app = self.extract_sepos_root(sep_fw_header)
            else:
                name = macho_list[choice]
                app = self.process_apps(sep_fw_header, offset, name, choice)

            mainthread.execute_on_main_thread_and_wait(
                lambda: UIContext.allContexts()[0].openFilename(app))
        else:
            return False
        return True
Пример #10
0
 def __init__(self, parent, view, data):
     super(ExportsWidget, self).__init__(parent)
     layout = QVBoxLayout()
     layout.setContentsMargins(0, 0, 0, 0)
     self.imports = ExportsTreeView(self, view, data)
     self.filter = FilteredView(self, self.imports, self.imports)
     layout.addWidget(self.filter, 1)
     self.setLayout(layout)
     self.setMinimumSize(UIContext.getScaledWindowSize(100, 196))
Пример #11
0
 def refreshLines(self):
     addr = self.topAddr
     self.lines = []
     self.topLine = 0
     self.bottomAddr = self.topAddr
     self.updateRanges()
     if self.allocatedLength > 0x7fffffff:
         self.scrollBarMultiplier = (self.allocatedLength // 0x7fffffff) + 1
     else:
         self.scrollBarMultiplier = 1
     self.updatingScrollBar = True
     self.verticalScrollBar().setRange(0, (self.allocatedLength - 1) //
                                       self.scrollBarMultiplier)
     self.verticalScrollBar().setValue(
         self.getContiguousOffsetForAddress(addr) //
         self.scrollBarMultiplier)
     self.updatingScrollBar = False
     self.updateCache()
     self.viewport().update()
     UIContext.updateStatus()
Пример #12
0
    def __init__(self, parent, data):
        super(SegmentsWidget, self).__init__(parent)

        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setVerticalSpacing(1)
        layout.setHorizontalSpacing(
            UIContext.getScaledWindowSize(16, 16).width())

        self.segments = []
        for segment in data.segments:
            if segment.readable or segment.writable or segment.executable:
                self.segments.append(segment)
        self.segments.sort(key=lambda segment: segment.start)

        row = 0
        for segment in self.segments:
            begin = "0x%x" % segment.start
            end = "0x%x" % segment.end

            permissions = ""
            if segment.readable:
                permissions += "r"
            else:
                permissions += "-"
            if segment.writable:
                permissions += "w"
            else:
                permissions += "-"
            if segment.executable:
                permissions += "x"
            else:
                permissions += "-"

            rangeLayout = QHBoxLayout()
            rangeLayout.setContentsMargins(0, 0, 0, 0)
            beginLabel = headers.ClickableAddressLabel(begin)
            dashLabel = QLabel("-")
            dashLabel.setFont(binaryninjaui.getMonospaceFont(self))
            endLabel = headers.ClickableAddressLabel(end)
            rangeLayout.addWidget(beginLabel)
            rangeLayout.addWidget(dashLabel)
            rangeLayout.addWidget(endLabel)
            layout.addLayout(rangeLayout, row, 0)

            permissionsLabel = QLabel(permissions)
            permissionsLabel.setFont(binaryninjaui.getMonospaceFont(self))
            layout.addWidget(permissionsLabel, row, 1)

            row += 1

        layout.setColumnStretch(2, 1)
        self.setLayout(layout)
def add_function_hook(emulator, function):
    ctx = UIContext.activeContext()
    handler = ctx.globalActions()
    hook_options = [
        a
        for a in handler.getAllValidActions()
        if "Snippets\\" in a and "emulator" in a.lower()
    ]
    snippets = ChoiceField("Snippets:", hook_options)

    get_form_input([snippets], "Add Function Hook")

    choice = hook_options[snippets.result]
    def execute(self, il: LowLevelILInstruction):
        function = self.hooks.get(il.function, {})
        hook = function.get(il.instr_index)

        if hook is None:
            super().execute(il)

        else:
            ctx = UIContext.contextForWidget(
                self.view.session_data['emulator.memory.widget'])

            handler = ctx.contentActionHandler()
            handler.executeAction(hook)

        if self.current_instr_index == il.instr_index:
            self.set_next_instr_index(il.function, il.instr_index + 1)
    def remove_hook(self):
        emulator = self.parent().view.session_data['emulator']

        ctx = UIContext.activeContext()

        content = ctx.contentActionHandler()
        action_context = content.actionContext()

        llil = action_context.lowLevelILFunction
        instr_index = action_context.instrIndex

        if None in (llil, instr_index) or instr_index == 0xffffffffffffffff:
            log.log_alert('LLIL Function/Instruction not selected!')
            return

        remove_hook(emulator, llil[instr_index])
Пример #16
0
    def updateState(self):
        # Get the currently active view frame for this group of panes. There can be
        # multiple view frames in a single window, or the pane could be popped out
        # into its own window. UIContext.currentViewFrameForWidget will determine
        # the best view frame to use for context.
        frame = UIContext.currentViewFrameForWidget(self)

        # Update UI according to the active frame
        if frame:
            self.datatype.setText(frame.getCurrentView())
            view = frame.getCurrentViewInterface()
            self.data = view.getData()
            self.offset.setText(hex(view.getCurrentOffset()))
        else:
            self.datatype.setText("None")
            self.data = None
Пример #17
0
 def __init__(self, parent, header):
     super(HeaderWidget, self).__init__(parent)
     layout = QGridLayout()
     layout.setContentsMargins(0, 0, 0, 0)
     layout.setVerticalSpacing(1)
     row = 0
     col = 0
     for field in header.fields:
         name = field[0]
         value = field[1]
         fieldType = ""
         if len(field) > 2:
             fieldType = field[2]
         layout.addWidget(QLabel(name + ": "), row, col * 3)
         if isinstance(value, list):
             for i in range(0, len(value)):
                 if fieldType == "ptr":
                     label = ClickableAddressLabel(value[i])
                 elif fieldType == "code":
                     label = ClickableCodeLabel(value[i])
                 else:
                     label = QLabel(value[i])
                     label.setFont(binaryninjaui.getMonospaceFont(self))
                 layout.addWidget(label, row, col * 3 + 1)
                 row += 1
         else:
             if fieldType == "ptr":
                 label = ClickableAddressLabel(value)
             elif fieldType == "code":
                 label = ClickableCodeLabel(value)
             else:
                 label = QLabel(value)
                 label.setFont(binaryninjaui.getMonospaceFont(self))
             layout.addWidget(label, row, col * 3 + 1)
             row += 1
         if (header.columns > 1) and (row >= header.rows_per_column) and (
             (col + 1) < header.columns):
             row = 0
             col += 1
     for col in range(1, header.columns):
         layout.setColumnMinimumWidth(
             col * 3 - 1,
             UIContext.getScaledWindowSize(20, 20).width())
     layout.setColumnStretch(header.columns * 3 - 1, 1)
     self.setLayout(layout)
def add_hook(emulator, instruction):
    ctx = UIContext.activeContext()
    handler = ctx.globalActions()
    hook_options = [
        a
        for a in handler.getAllValidActions()
        if "Snippets\\" in a and "emulator" in a.lower()
    ]
    snippets = ChoiceField("Snippets:", hook_options)

    get_form_input([snippets], "Add Hook")

    choice = hook_options[snippets.result]

    emulator.add_hook(instruction, choice)

    instruction.function.source_function.set_auto_instr_highlight(
        instruction.address, HighlightStandardColor.BlackHighlightColor
    )
Пример #19
0
    def active_context(self):
        all_contexts = UIContext.allContexts()
        if not all_contexts:
            return None

        ctx = all_contexts[0]
        handler = ctx.contentActionHandler()
        if handler is None:
            return None

        actionContext = handler.actionContext()
        func = actionContext.function
        if func is None:
            return None

        return binsync.data.Function(func.start,
                                     0,
                                     header=FunctionHeader(
                                         func.name, func.start))
Пример #20
0
	def __init__(self, parent, view, data):
		super(EntropyWidget, self).__init__(parent)
		self.view = view
		self.data = data
		self.raw_data = data.file.raw

		self.block_size = (len(self.raw_data) / 4096) + 1
		if self.block_size < 1024:
			self.block_size = 1024
		self.width = int(len(self.raw_data) / self.block_size)
		self.image = QImage(self.width, 1, QImage.Format_ARGB32)
		self.image.fill(QColor(0, 0, 0, 0))

		self.thread = EntropyThread(self.raw_data, self.image, self.block_size)
		self.started = False

		self.timer = QTimer()
		self.timer.timeout.connect(self.timerEvent)
		self.timer.setInterval(100)
		self.timer.setSingleShot(False)
		self.timer.start()

		self.setMinimumHeight(UIContext.getScaledWindowSize(32, 32).height())
Пример #21
0
 def setCurrentOffset(self, offset):
     #log.log_debug('setCurrentOffset(0x%X)' % offset)
     self.rootSelectionStart = offset
     UIContext.updateStatus(True)
Пример #22
0
 def destroyed(self):
     UIContext.unregisterNotification(self)
Пример #23
0
    def __init__(self, parent, data):
        super(SectionsWidget, self).__init__(parent)

        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setVerticalSpacing(1)
        layout.setHorizontalSpacing(
            UIContext.getScaledWindowSize(16, 16).width())

        maxNameLen = 0
        for section in data.sections.values():
            if len(section.name) > maxNameLen:
                maxNameLen = len(section.name)
        if maxNameLen > 32:
            maxNameLen = 32

        self.sections = []
        for section in data.sections.values():
            if section.semantics != SectionSemantics.ExternalSectionSemantics:
                self.sections.append(section)
        self.sections.sort(key=lambda section: section.start)

        row = 0
        for section in self.sections:
            name = section.name
            if len(name) > maxNameLen:
                name = name[:maxNameLen - 1] + "…"

            begin = "0x%x" % section.start
            end = "0x%x" % section.end
            typeName = section.type

            permissions = ""
            if data.is_offset_readable(section.start):
                permissions += "r"
            else:
                permissions += "-"
            if data.is_offset_writable(section.start):
                permissions += "w"
            else:
                permissions += "-"
            if data.is_offset_executable(section.start):
                permissions += "x"
            else:
                permissions += "-"

            semantics = ""
            if section.semantics == SectionSemantics.ReadOnlyCodeSectionSemantics:
                semantics = "Code"
            elif section.semantics == SectionSemantics.ReadOnlyDataSectionSemantics:
                semantics = "Ready-only Data"
            elif section.semantics == SectionSemantics.ReadWriteDataSectionSemantics:
                semantics = "Writable Data"

            nameLabel = QLabel(name)
            nameLabel.setFont(binaryninjaui.getMonospaceFont(self))
            layout.addWidget(nameLabel, row, 0)

            rangeLayout = QHBoxLayout()
            rangeLayout.setContentsMargins(0, 0, 0, 0)
            beginLabel = headers.ClickableAddressLabel(begin)
            dashLabel = QLabel("-")
            dashLabel.setFont(binaryninjaui.getMonospaceFont(self))
            endLabel = headers.ClickableAddressLabel(end)
            rangeLayout.addWidget(beginLabel)
            rangeLayout.addWidget(dashLabel)
            rangeLayout.addWidget(endLabel)
            layout.addLayout(rangeLayout, row, 1)

            permissionsLabel = QLabel(permissions)
            permissionsLabel.setFont(binaryninjaui.getMonospaceFont(self))
            layout.addWidget(permissionsLabel, row, 2)
            typeLabel = QLabel(typeName)
            typeLabel.setFont(binaryninjaui.getMonospaceFont(self))
            layout.addWidget(typeLabel, row, 3)
            semanticsLabel = QLabel(semantics)
            semanticsLabel.setFont(binaryninjaui.getMonospaceFont(self))
            layout.addWidget(semanticsLabel, row, 4)

            row += 1

        layout.setColumnStretch(5, 1)
        self.setLayout(layout)
Пример #24
0
    def __init__(self, parent, data):
        assert type(data) == BinaryView
        self.bv = data
        QDialog.__init__(self, parent)

        debug_state = binjaplug.get_state(self.bv)

        self.setWindowTitle("Debug Adapter Settings")
        self.setMinimumSize(UIContext.getScaledWindowSize(400, 130))
        self.setAttribute(Qt.WA_DeleteOnClose)

        layout = QVBoxLayout()
        layout.setSpacing(0)

        titleLabel = QLabel("Adapter Settings")
        titleLayout = QHBoxLayout()
        titleLayout.setContentsMargins(0, 0, 0, 0)
        titleLayout.addWidget(titleLabel)

        self.adapterEntry = QPushButton(self)
        self.adapterMenu = QMenu(self)
        for adapter in DebugAdapter.ADAPTER_TYPE:
            if not DebugAdapter.ADAPTER_TYPE.can_use(adapter):
                continue

            def select_adapter(adapter):
                return lambda: self.selectAdapter(adapter)

            self.adapterMenu.addAction(adapter.name, select_adapter(adapter))
            if adapter == debug_state.adapter_type:
                self.adapterEntry.setText(adapter.name)

        self.adapterEntry.setMenu(self.adapterMenu)

        self.argumentsEntry = QLineEdit(self)
        self.addressEntry = QLineEdit(self)
        self.portEntry = QLineEdit(self)
        self.requestTerminalEmulator = QCheckBox(self)

        self.formLayout = QFormLayout()
        self.formLayout.addRow("Adapter Type", self.adapterEntry)
        self.formLayout.addRow("Command Line Arguments", self.argumentsEntry)
        self.formLayout.addRow("Address", self.addressEntry)
        self.formLayout.addRow("Port", self.portEntry)
        self.formLayout.addRow("Request Terminal Emulator",
                               self.requestTerminalEmulator)

        buttonLayout = QHBoxLayout()
        buttonLayout.setContentsMargins(0, 0, 0, 0)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(lambda: self.reject())
        self.acceptButton = QPushButton("Accept")
        self.acceptButton.clicked.connect(lambda: self.accept())
        self.acceptButton.setDefault(True)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.cancelButton)
        buttonLayout.addWidget(self.acceptButton)

        layout.addLayout(titleLayout)
        layout.addSpacing(10)
        layout.addLayout(self.formLayout)
        layout.addStretch(1)
        layout.addSpacing(10)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)

        self.addressEntry.setText(debug_state.remote_host)
        self.portEntry.setText(str(debug_state.remote_port))

        self.addressEntry.textEdited.connect(lambda: self.apply())
        self.portEntry.textEdited.connect(lambda: self.apply())

        self.argumentsEntry.setText(' '.join(
            shlex.quote(arg) for arg in debug_state.command_line_args))
        self.argumentsEntry.textEdited.connect(lambda: self.updateArguments())

        self.requestTerminalEmulator.setChecked(
            debug_state.request_terminal_emulator)
        self.requestTerminalEmulator.stateChanged.connect(lambda: self.apply())

        self.accepted.connect(lambda: self.apply())
Пример #25
0
		"description" : "Controls the amount of analysis performed on functions when opening for triage.",
		"enum" : ["controlFlow", "basic", "full"],
		"enumDescriptions" : [
			"Only perform control flow analysis on the binary. Cross references are valid only for direct function calls.",
			"Perform fast initial analysis of the binary. This mode does not analyze types or data flow through stack variables.",
			"Perform full analysis of the binary." ]
	}
	""")

Settings().register_setting("triage.linearSweep", """
	{
		"title" : "Triage Linear Sweep Mode",
		"type" : "string",
		"default" : "partial",
		"description" : "Controls the level of linear sweep performed when opening for triage.",
		"enum" : ["none", "partial", "full"],
		"enumDescriptions" : [
			"Do not perform linear sweep of the binary.",
			"Perform linear sweep on the binary, but skip the control flow graph analysis phase.",
			"Perform full linear sweep on the binary." ]
	}
	""")

UIAction.registerAction("Open for Triage...", QKeySequence("Ctrl+Alt+O"))
UIAction.registerAction("Open Selected Files")

UIActionHandler.globalActions().bindAction("Open for Triage...", UIAction(openForTriage))
Menu.mainMenu("File").addAction("Open for Triage...", "Open")

UIContext.registerFileOpenMode("Triage...", "Open file(s) for quick analysis in the Triage Summary view.", "Open for Triage...")
Пример #26
0
 def setCurrentOffset(self, offset):
     self.currentOffset = offset
     UIContext.updateStatus(True)
Пример #27
0
	def __init__(self, parent, data):
		assert type(data) == binaryninja.binaryview.BinaryView
		self.bv = data
		QDialog.__init__(self, parent)

		self.setWindowTitle("Debug Adapter Settings")
		self.setMinimumSize(UIContext.getScaledWindowSize(400, 130))
		self.setAttribute(Qt.WA_DeleteOnClose)

		layout = QVBoxLayout()
		layout.setSpacing(0)

		titleLabel = QLabel("Adapter Settings")
		titleLayout = QHBoxLayout()
		titleLayout.setContentsMargins(0, 0, 0, 0)
		titleLayout.addWidget(titleLabel)

		self.argumentsEntry = QLineEdit(self)
		# self.addressEntry = QLineEdit(self)
		# self.portEntry = QLineEdit(self)

		formLayout = QFormLayout()
		formLayout.addRow("Command Line Arguments", self.argumentsEntry)
		# formLayout.addRow("Address", self.addressEntry)
		# formLayout.addRow("Port", self.portEntry)

		buttonLayout = QHBoxLayout()
		buttonLayout.setContentsMargins(0, 0, 0, 0)

		self.cancelButton = QPushButton("Cancel")
		self.cancelButton.clicked.connect(lambda: self.reject())
		self.acceptButton = QPushButton("Accept")
		self.acceptButton.clicked.connect(lambda: self.accept())
		self.acceptButton.setDefault(True)
		buttonLayout.addStretch(1)
		buttonLayout.addWidget(self.cancelButton)
		buttonLayout.addWidget(self.acceptButton)

		layout.addLayout(titleLayout)
		layout.addSpacing(10)
		layout.addLayout(formLayout)
		layout.addStretch(1)
		layout.addSpacing(10)
		layout.addLayout(buttonLayout)

		self.setLayout(layout)

		debug_state = binjaplug.get_state(self.bv)

		# settings = Settings()
		# address = settings.get_string_with_scope("debugger.adapter.address", data, SettingsScope.SettingsContextScope)
		# port = settings.get_integer_with_scope("debugger.adapter.port", data, SettingsScope.SettingsContextScope)

		# self.addressEntry.setText(address[0])
		# self.portEntry.setText(str(port[0]))

		# self.addressEntry.textEdited.connect(lambda: self.updateSettings())
		# self.portEntry.textEdited.connect(lambda: self.updateSettings())

		self.argumentsEntry.setText(' ' .join(shlex.quote(arg) for arg in debug_state.command_line_args))
		self.argumentsEntry.textEdited.connect(lambda: self.updateArguments())

		self.accepted.connect(lambda: self.apply())
Пример #28
0
 def selectAll(self):
     self.selectionStartAddr = self.getStart()
     self.cursorAddr = self.getEnd()
     self.viewport().update()
     UIContext.updateStatus()
Пример #29
0
def open_file_tab(filename: str):
    # TODO: Save libc analysis? (Renaming symbols might cause some issues...)
    execute_on_main_thread_and_wait(
        lambda: UIContext.allContexts()[0].openFilename(filename)
    )