def __init__(self, dwarf): super(Emulator, self).__init__() self.setTerminationEnabled(True) self.dwarf = dwarf self._prefs = Prefs() self._setup_done = False self._blacklist_regs = [] self.cs = None self.uc = None self.context = None self.thumb = False self.end_ptr = 0 self.current_context = None self.stepping = [False, False] self._current_instruction = 0 self._current_cpu_mode = 0 self._request_stop = False # configurations self.callbacks_path = None self.callbacks = None self.instructions_delay = 0 self._start_address = 0 self._end_address = 0
def __init__(self, app_window): self.app_window = app_window self.app = app_window.get_app_instance() self.java_available = False self.loading_library = False # process self.pid = 0 self.process = None self.script = None # hooks self.hooks = {} self.on_loads = {} self.java_hooks = {} self.temporary_input = '' self.native_pending_args = None self.java_pending_args = None self.keystone_installed = False try: import keystone.keystone_const self.keystone_installed = True except: pass self.prefs = Prefs()
def __init__(self, app_window): self.app_window = app_window self.app = app_window.get_app_instance() self.java_available = False self.loading_library = False self.pid = 0 self.process = None self.script = None self.prefs = Prefs()
def __init__(self, app_window): self.app_window = app_window self.app = app_window.get_app_instance() self.java_available = False self.loading_library = False # frida device self.device = None # process self.pid = 0 self.process = None self.script = None # kernel self.kernel = Kernel(self) # hooks self.hooks = {} self.on_loads = {} self.java_hooks = {} self.temporary_input = '' self.native_pending_args = None self.java_pending_args = None # context self.arch = '' self.pointer_size = 0 self.contexts = {} self.context_tid = 0 # tracers self.native_traced_tid = 0 # core utils self.bus = EventBus() self.emulator = Emulator(self) self.git = Git() self.prefs = Prefs() self.script_manager = ScriptsManager(self) self.keystone_installed = False try: import keystone.keystone_const self.keystone_installed = True except: pass
def __init__(self, app): self.app = app self._prefs = Prefs() self.pipe = None self.js_api_pipe = None self.current_seek = '' self.with_r2dec = False self._working = False self.menu_items = [] self.app.session_manager.sessionCreated.connect( self._on_session_created) self.app.session_manager.sessionStopped.connect( self._on_session_stopped) self.app.onUIElementCreated.connect(self._on_ui_element_created)
def copy_hex_to_clipboard(hex_str): """ Helper for copying hexstr in prefered style """ _prefs = Prefs() uppercase = (_prefs.get('dwarf_ui_hexstyle', 'upper').lower() == 'upper') if isinstance(hex_str, str): if hex_str.startswith('0x'): if uppercase: hex_str = hex_str.upper().replace('0X', '0x') else: hex_str = hex_str.lower() pyperclip.copy(hex_str) elif isinstance(hex_str, int): str_fmt = '0x{0:x}' if uppercase: str_fmt = '0x{0:X}' pyperclip.copy(str_fmt.format(hex_str))
def __init__(self, parent=None, search_enabled=True): super(DwarfListView, self).__init__(parent=parent) self._search_enabled = search_enabled self._current_search = '' self._uppercase_hex = True _prefs = Prefs() self.rows_dualcolor = _prefs.get('dwarf_ui_alternaterowcolors', False) self.uppercase_hex = _prefs.get('dwarf_ui_hexstyle', 'upper').lower() == 'upper' self.setEditTriggers(self.NoEditTriggers) self.setHeaderHidden(False) self.setAutoFillBackground(True) self.setRootIsDecorated(False) # TODO: use filter self._proxy_model = QSortFilterProxyModel(self) self._proxy_model.setSourceModel(self.model())
def __init__(self, dwarf): super(Emulator, self).__init__() self.setTerminationEnabled(True) self.dwarf = dwarf self._prefs = Prefs() self._setup_done = False self._blacklist_regs = [] self.cs = None self.uc = None self.context = None self.thumb = False self.end_ptr = 0 self.step_mode = STEP_MODE_NONE self.current_context = None self._current_instruction = 0 self._next_instruction = 0 self._current_cpu_mode = 0 self._request_stop = False # configurations self.callbacks_path = None self.callbacks = None self.instructions_delay = 0 self._start_address = 0 self._end_address = 0 # prevent emulator loop for any reason # i.e through custom callback # we don't want any UI freeze, so we just setup a n00b way to check if we are looping # inside the same instruction for N times. # notice that when an unmapped memory region is required during emulation, this will be taken from target proc # and mapped into unicorn context. Later, the code fallback to execute the same instruction once again self._anti_loop = 0
def __init__(self, dwarf, parent=None): super(EmulatorConfigsDialog, self).__init__(parent) self.dwarf = dwarf self._prefs = Prefs() layout = QVBoxLayout(self) self.setMinimumWidth(500) layout.addWidget(QLabel('callbacks path')) callbacks_layout = QHBoxLayout() pick_path = QPushButton('choose') pick_path.clicked.connect(self.pick_callbacks_path) current_callbacks_path = self._prefs.get(prefs.EMULATOR_CALLBACKS_PATH) if current_callbacks_path == '': current_callbacks_path = 'none' self.callbacks_path_label = QLabel(current_callbacks_path) callbacks_layout.addWidget(pick_path) callbacks_layout.addWidget(self.callbacks_path_label) layout.addLayout(callbacks_layout) layout.addWidget(QLabel('delay between instructions')) self.instructions_delay = QLineEdit() self.instructions_delay.setText( str(self._prefs.get(prefs.EMULATOR_INSTRUCTIONS_DELAY, 0.5))) layout.addWidget(self.instructions_delay) buttons = QHBoxLayout() cancel = QPushButton('cancel') cancel.clicked.connect(self.close) buttons.addWidget(cancel) accept = QPushButton('accept') accept.clicked.connect(self.accept) buttons.addWidget(accept) layout.addLayout(buttons)
def __init__(self, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self._tab_order = [ 'debug', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger' ] self._is_newer_dwarf = False self.q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat) self.menu = self.menuBar() self.view_menu = None self._initialize_ui_elements() self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() self.remove_tmp_dir() # themes self.prefs = Prefs() utils.set_theme(self.prefs.get('dwarf_ui_theme', 'black'), self.prefs) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/Anton.ttf')) if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Regular.ttf')) font = QFont("OpenSans", 9, QFont.Normal) # TODO: add settingsdlg font_size = self.prefs.get('dwarf_ui_font_size', 12) font.setPixelSize(font_size) _app.setFont(font) if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Bold.ttf')) # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(False) self.main_tabs.setTabsClosable(True) self.main_tabs.setAutoFillBackground(True) self.main_tabs.tabCloseRequested.connect(self._on_close_tab) self.setCentralWidget(self.main_tabs) # pluginmanager self.plugin_manager = PluginManager(self) self.plugin_manager.reload_plugins() if dwarf_args.any == '': self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) # wait for welcome screen self.hide() self.welcome_window.show() else: print('* Starting new Session') self._start_session(dwarf_args.target)
def __init__(self, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self._tab_order = [ 'memory', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger' ] self.menu = self.menuBar() self._is_newer_dwarf = False self.view_menu = None #dockwidgets self.watchers_dwidget = None self.hooks_dwiget = None self.bookmarks_dwiget = None self.registers_dock = None self.console_dock = None self.backtrace_dock = None self.threads_dock = None #panels self.asm_panel = None self.console_panel = None self.context_panel = None self.backtrace_panel = None self.contexts_list_panel = None self.data_panel = None self.emulator_panel = None self.ftrace_panel = None self.hooks_panel = None self.bookmarks_panel = None self.smali_panel = None self.java_inspector_panel = None self.java_explorer_panel = None self.java_trace_panel = None self.memory_panel = None self.modules_panel = None self.ranges_panel = None self.search_panel = None self.trace_panel = None self.watchers_panel = None self.welcome_window = None self._ui_elems = [] self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() self.remove_tmp_dir() # themes self.prefs = Prefs() self.set_theme(self.prefs.get('dwarf_ui_theme', 'black')) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/Anton.ttf')) if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Regular.ttf')) _app.setFont(QFont("OpenSans", 9, QFont.Normal)) if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Bold.ttf')) # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(False) self.main_tabs.setTabsClosable(True) self.main_tabs.setAutoFillBackground(True) self.main_tabs.tabCloseRequested.connect(self._on_close_tab) self.setCentralWidget(self.main_tabs) if self.dwarf_args.package is None: self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) self.welcome_window.onSessionRestore.connect(self._restore_session) # wait for welcome screen self.hide() self.welcome_window.show() else: if dwarf_args.package is not None: if dwarf_args.type is None: # no device given check if package is local path if os.path.exists(dwarf_args.package): print('* Starting new LocalSession') self._start_session('local') else: print('use -t to set sessiontype') exit(0) else: print('* Starting new Session') self._start_session(dwarf_args.type)
def __init__(self, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self.menu = self.menuBar() self._is_newer_dwarf = False self.view_menu = None self.asm_panel = None self.console_panel = None self.context_panel = None self.backtrace_panel = None self.contexts_list_panel = None self.data_panel = None self.emulator_panel = None self.ftrace_panel = None self.hooks_panel = None self.smali_panel = None self.java_inspector_panel = None self.java_explorer_panel = None self.java_trace_panel = None self.memory_panel = None self.modules_panel = None self.ranges_panel = None self.search_panel = None self.trace_panel = None self.watchers_panel = None self.welcome_window = None self._ui_elems = [] self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() self.remove_tmp_dir() # themes self.prefs = Prefs() self.set_theme(self.prefs.get('dwarf_ui_theme', 'black')) # set icon if os.name == 'nt': # windows stuff import ctypes try: # write ini to show folder with dwarficon folder_stuff = "[.ShellClassInfo]\nIconResource=assets\dwarf.ico,0\n[ViewState]\nMode=\nVid=\nFolderType=Generic\n" try: with open('desktop.ini', 'w') as ini: ini.writelines(folder_stuff) FILE_ATTRIBUTE_HIDDEN = 0x02 FILE_ATTRIBUTE_SYSTEM = 0x04 # set fileattributes to hidden + systemfile ctypes.windll.kernel32.SetFileAttributesW( r'desktop.ini', FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) except PermissionError: # its hidden+system already pass # fix for showing dwarf icon in windows taskbar instead of pythonicon _appid = u'iGio90.dwarf.debugger' ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( _appid) if os.path.exists(utils.resource_path('assets/dwarf.png')): _icon = QIcon(utils.resource_path('assets/dwarf.png')) _app.setWindowIcon(_icon) self.setWindowIcon(_icon) except: pass else: if os.path.exists(utils.resource_path('assets/dwarf.png')): _icon = QIcon(utils.resource_path('assets/dwarf.png')) _app.setWindowIcon(_icon) self.setWindowIcon(_icon) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont('assets/Anton.ttf') if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont('assets/OpenSans-Regular.ttf') _app.setFont(QFont("OpenSans", 9, QFont.Normal)) if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont('assets/OpenSans-Bold.ttf') # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(True) self.main_tabs.setAutoFillBackground(True) self.setCentralWidget(self.main_tabs) if self.dwarf_args.package is None: self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) # wait for welcome screen self.hide() self.welcome_window.show() else: if dwarf_args.package is not None: if dwarf_args.type is None: # no device given check if package is local path if os.path.exists(dwarf_args.package): print('* Starting new LocalSession') self._start_session('local') else: print('use -t to set sessiontype') exit(0) else: print('* Starting new Session') self._start_session(dwarf_args.type)
def __init__(self, parent=None): super(DisassemblyView, self).__init__(parent=parent) _prefs = Prefs() self._uppercase_hex = (_prefs.get('dwarf_ui_hexstyle', 'upper').lower() == 'upper') self._app_window = parent self.debug_panel = None self.setAutoFillBackground(True) self._running_disasm = False # setting font self.font = utils.get_os_monospace_font() self.font.setFixedPitch(True) self.setFont(self.font) self._char_width = QFontMetricsF(self.font).width( '#') # self.fontMetrics().width("#") if (self._char_width % 1) < .5: self.font.setLetterSpacing(QFont.AbsoluteSpacing, -(self._char_width % 1.0)) self._char_width -= self._char_width % 1.0 else: self.font.setLetterSpacing(QFont.AbsoluteSpacing, 1.0 - (self._char_width % 1.0)) self._char_width += 1.0 - (self._char_width % 1.0) self._char_height = self.fontMetrics().height() self._base_line = self.fontMetrics().ascent() self._history = [] self._lines = [] self._longest_bytes = 0 self._longest_mnemonic = 0 self._ctrl_colors = { 'background': QColor('#181818'), 'foreground': QColor('#666'), 'jump_arrows': QColor('#444'), 'jump_arrows_hover': QColor('#ef5350'), 'divider': QColor('#666'), 'line': QColor('#111'), 'selection_fg': QColor(Qt.white), 'selection_bg': QColor('#ef5350') } self._jump_color = QColor('#39a') self._header_height = 0 self._ver_spacing = 2 self._dash_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.DashLine) self._solid_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.SolidLine) self._line_pen = QPen(self._ctrl_colors['divider'], 0, Qt.SolidLine) self._breakpoint_linewidth = 5 self._jumps_width = 100 self.setMouseTracking(True) self.current_jump = -1 self._current_line = -1 self._display_jumps = True self._follow_jumps = True self.pos = 0
def __init__(self, parent=None): super(DisassemblyView, self).__init__(parent=parent) _prefs = Prefs() self._uppercase_hex = (_prefs.get('dwarf_ui_hexstyle', 'upper').lower() == 'upper') self._app_window = parent self.setAutoFillBackground(True) # setting font self.font = utils.get_os_monospace_font() self.font.setFixedPitch(True) self.setFont(self.font) self._char_width = self.fontMetrics().width("2") self._char_height = self.fontMetrics().height() self._base_line = self.fontMetrics().ascent() self._history = [] self._lines = [] self._range = None self._max_instructions = 128 self._longest_bytes = 0 self._longest_mnemonic = 0 self.capstone_arch = 0 self.capstone_mode = 0 self.keystone_arch = 0 self.keystone_mode = 0 self.on_arch_changed() self._ctrl_colors = { 'background': QColor('#181818'), 'foreground': QColor('#666'), 'jump_arrows': QColor('#444'), 'jump_arrows_hover': QColor('#ef5350'), 'divider': QColor('#666'), 'line': QColor('#111'), 'selection_fg': QColor(Qt.white), 'selection_bg': QColor('#ef5350') } self._jump_color = QColor('#39a') self._header_height = 0 self._ver_spacing = 2 self._dash_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.DashLine) self._solid_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.SolidLine) self._line_pen = QPen(self._ctrl_colors['divider'], 0, Qt.SolidLine) self._breakpoint_linewidth = 5 self._jumps_width = 100 self.setMouseTracking(True) self.current_jump = -1 self._current_line = -1 self._display_jumps = True self._follow_jumps = True self.pos = 0
def run_dwarf(): """ fire it up """ #os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" os.environ["QT_SCALE_FACTOR"] = "1" os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "0" os.environ["QT_SCREEN_SCALE_FACTORS"] = "1" args = process_args() #_check_dependencies() # not enabled atm from lib import utils from lib.git import Git from lib.prefs import Prefs from ui.app import AppWindow _prefs = Prefs() local_update_disabled = _prefs.get('disable_local_frida_update', False) if not local_update_disabled: _git = Git() import frida remote_frida = _git.get_frida_version() local_frida = frida.__version__ if remote_frida and local_frida != remote_frida[0]['tag_name']: print('Updating local frida version to ' + remote_frida[0]['tag_name']) try: res = utils.do_shell_command('pip3 install frida --upgrade --user') if 'Successfully installed frida-' + remote_frida[0]['tag_name'] in res: _on_restart() elif 'Requirement already up-to-date' in res: if os.path.exists('.git_cache'): shutil.rmtree('.git_cache', ignore_errors=True) else: print('failed to update local frida') print(res) except Exception as e: # pylint: disable=broad-except, invalid-name print('failed to update local frida') print(str(e)) if os.name == 'nt': # windows stuff import ctypes try: # write ini to show folder with dwarficon folder_stuff = "[.ShellClassInfo]\n" folder_stuff += "IconResource=assets\\dwarf.ico,0\n" folder_stuff += "[ViewState]\n" folder_stuff += "Mode=\n" folder_stuff += "Vid=\n" folder_stuff += "FolderType=Generic\n" try: with open('desktop.ini', 'w') as ini: ini.writelines(folder_stuff) # set fileattributes to hidden + systemfile ctypes.windll.kernel32.SetFileAttributesW( r'desktop.ini', 0x02 | 0x04 ) # FILE_ATTRIBUTE_HIDDEN = 0x02 | FILE_ATTRIBUTE_SYSTEM = 0x04 except PermissionError: # its hidden+system already pass # fix for showing dwarf icon in windows taskbar instead of pythonicon _appid = u'iGio90.dwarf.debugger' ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( _appid) ctypes.windll.user32.SetProcessDPIAware() except Exception: # pylint: disable=broad-except pass from PyQt5.QtCore import Qt from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication qapp = QApplication([]) qapp.setDesktopSettingsAware(True) qapp.setAttribute(Qt.AA_EnableHighDpiScaling) qapp.setAttribute(Qt.AA_UseHighDpiPixmaps) qapp.setLayoutDirection(Qt.LeftToRight) qapp.setOrganizationName("https://github.com/iGio90/Dwarf") qapp.setApplicationName("dwarf") # set icon if os.name == "nt" and os.path.exists( utils.resource_path('assets/dwarf.ico')): _icon = QIcon(utils.resource_path('assets/dwarf.ico')) qapp.setWindowIcon(_icon) else: if os.path.exists(utils.resource_path('assets/dwarf.png')): _icon = QIcon(utils.resource_path('assets/dwarf.png')) qapp.setWindowIcon(_icon) app_window = AppWindow(args) app_window.setWindowIcon(_icon) app_window.onRestart.connect(_on_restart) try: sys.exit(qapp.exec_()) except SystemExit as sys_err: if sys_err.code == 0: # thanks for using dwarf print('Thank\'s for using Dwarf\nHave a nice day...') else: # something was wrong print('sysexit with: %d' % sys_err.code)
def __init__(self, parent=None): super(DisassemblyView, self).__init__(parent=parent) _prefs = Prefs() self._uppercase_hex = (_prefs.get('dwarf_ui_hexstyle', 'upper').lower() == 'upper') self._app_window = parent self.setAutoFillBackground(True) self._app_window.dwarf.onApplyContext.connect(self.on_arch_changed) # setting font self.font = utils.get_os_monospace_font() self.font.setFixedPitch(True) self.setFont(self.font) self._char_width = QFontMetricsF(self.font).width( '#') # self.fontMetrics().width("#") if (self._char_width % 1) < .5: self.font.setLetterSpacing(QFont.AbsoluteSpacing, -(self._char_width % 1.0)) self._char_width -= self._char_width % 1.0 else: self.font.setLetterSpacing(QFont.AbsoluteSpacing, 1.0 - (self._char_width % 1.0)) self._char_width += 1.0 - (self._char_width % 1.0) self._char_height = self.fontMetrics().height() self._base_line = self.fontMetrics().ascent() self._history = [] self._lines = [] self._range = None self._longest_bytes = 0 self._longest_mnemonic = 0 self._running_disasm = False self.capstone_arch = 0 self.capstone_mode = 0 self.keystone_arch = 0 self.keystone_mode = 0 self.on_arch_changed() self._ctrl_colors = { 'background': QColor('#181818'), 'foreground': QColor('#666'), 'jump_arrows': QColor('#444'), 'jump_arrows_hover': QColor('#ef5350'), 'divider': QColor('#666'), 'line': QColor('#111'), 'selection_fg': QColor(Qt.white), 'selection_bg': QColor('#ef5350') } self._jump_color = QColor('#39a') self._header_height = 0 self._ver_spacing = 2 self._dash_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.DashLine) self._solid_pen = QPen(self._ctrl_colors['jump_arrows'], 2.0, Qt.SolidLine) self._line_pen = QPen(self._ctrl_colors['divider'], 0, Qt.SolidLine) self._breakpoint_linewidth = 5 self._jumps_width = 100 self.setMouseTracking(True) self.current_jump = -1 self._current_line = -1 self._display_jumps = True self._follow_jumps = True self.pos = 0 # hacky way to let plugins hook this and inject menu actions self.menu_extra_menu_hooks = [] """ this is one more way for allowing plugin hooks and perform additional operation on the range object """ self.run_default_disassembler = True