def __init__(self, app, flags=None): super(QDebugPanel, self).__init__(flags) self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks) self.app = app self.q_settings = app.q_settings self.functions_list = DwarfListView() self.functions_list_model = QStandardItemModel(0, 1) self.functions_list_model.setHeaderData(0, Qt.Horizontal, '') self.functions_list.setModel(self.functions_list_model) self.functions_list.setHeaderHidden(True) self.functions_list.doubleClicked.connect( self._function_double_clicked) self.dock_functions_list = QDockWidget('Functions', self) self.dock_functions_list.setObjectName('functions') self.dock_functions_list.setWidget(self.functions_list) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_functions_list) self.resizeDocks([self.dock_functions_list], [100], Qt.Horizontal) self.app.debug_view_menu.addAction( self.dock_functions_list.toggleViewAction()) screen_size = QtWidgets.QDesktopWidget().screenGeometry(-1) m_width = screen_size.width() self.memory_panel = HexEditor(self.app) self.memory_panel.debug_panel = self self.memory_panel.dataChanged.connect(self.on_memory_modified) self.disassembly_panel = DisassemblyView(self.app) self.disassembly_panel.debug_panel = self self.dock_memory_panel = QDockWidget('Memory', self) self.dock_memory_panel.setWidget(self.memory_panel) self.dock_memory_panel.setObjectName('memory') self.dock_disassembly_panel = QDockWidget('Disassembly', self) self.dock_disassembly_panel.setWidget(self.disassembly_panel) self.dock_disassembly_panel.setObjectName('disassembly') self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_memory_panel, Qt.Horizontal) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_disassembly_panel, Qt.Horizontal) if m_width >= 1920: self.splitDockWidget(self.dock_memory_panel, self.dock_disassembly_panel, Qt.Horizontal) else: self.tabifyDockWidget(self.dock_memory_panel, self.dock_disassembly_panel) self.restoreUiState()
def __init__(self, app, flags=None): super(QDebugPanel, self).__init__(flags) self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks) self.app = app self.q_settings = app.q_settings screen_size = QtWidgets.QDesktopWidget().screenGeometry(-1) m_width = screen_size.width() self.memory_panel = HexEditor(self.app) self.memory_panel.debug_panel = self self.memory_panel.dataChanged.connect(self.on_memory_modified) self.disassembly_panel = DisassemblyView(self.app) self.disassembly_panel.debug_panel = self self.dock_memory_panel = QDockWidget('Memory', self) self.dock_memory_panel.setWidget(self.memory_panel) self.dock_memory_panel.setObjectName('memory') self.dock_disassembly_panel = QDockWidget('Disassembly', self) self.dock_disassembly_panel.setWidget(self.disassembly_panel) self.dock_disassembly_panel.setObjectName('disassembly') self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_memory_panel, Qt.Horizontal) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_disassembly_panel, Qt.Horizontal) if m_width >= 1920: self.splitDockWidget(self.dock_memory_panel, self.dock_disassembly_panel, Qt.Horizontal) else: self.tabifyDockWidget(self.dock_memory_panel, self.dock_disassembly_panel) self.restoreUiState()
class QDebugPanel(QMainWindow): def __init__(self, app, flags=None): super(QDebugPanel, self).__init__(flags) self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks) self.app = app self.q_settings = app.q_settings screen_size = QtWidgets.QDesktopWidget().screenGeometry(-1) m_width = screen_size.width() self.memory_panel = HexEditor(self.app) self.memory_panel.debug_panel = self self.memory_panel.dataChanged.connect(self.on_memory_modified) self.disassembly_panel = DisassemblyView(self.app) self.disassembly_panel.debug_panel = self self.dock_memory_panel = QDockWidget('Memory', self) self.dock_memory_panel.setWidget(self.memory_panel) self.dock_memory_panel.setObjectName('memory') self.dock_disassembly_panel = QDockWidget('Disassembly', self) self.dock_disassembly_panel.setWidget(self.disassembly_panel) self.dock_disassembly_panel.setObjectName('disassembly') self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_memory_panel, Qt.Horizontal) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_disassembly_panel, Qt.Horizontal) if m_width >= 1920: self.splitDockWidget(self.dock_memory_panel, self.dock_disassembly_panel, Qt.Horizontal) else: self.tabifyDockWidget(self.dock_memory_panel, self.dock_disassembly_panel) self.restoreUiState() def restoreUiState(self): ui_state = self.q_settings.value('dwarf_debug_ui_state') if ui_state: self.restoreGeometry(ui_state) window_state = self.q_settings.value('dwarf_debug_ui_window') if window_state: self.restoreState(window_state) def closeEvent(self, event): self.q_settings.setValue('dwarf_debug_ui_state', self.saveGeometry()) self.q_settings.setValue('dwarf_debug_ui_window', self.saveState()) def showEvent(self, event): main_width = self.size().width() new_widths = [main_width * .4, main_width * .5] self.resizeDocks([self.dock_memory_panel, self.dock_disassembly_panel], new_widths, Qt.Horizontal) return super().showEvent(event) def update_functions(self, functions_list=None): if functions_list is None: functions_list = {} for module_info_base in self.app.dwarf.database.modules_info: module_info = self.app.dwarf.database.modules_info[ module_info_base] if len(module_info.functions) > 0: for function in module_info.functions: functions_list[function.name] = function.address for function_name in sorted(functions_list.keys()): function_addr = functions_list[function_name] function_name = function_name.replace('.', '_') if not self.app.bookmarks_panel.is_address_bookmarked( function_addr): self.app.bookmarks_panel._create_bookmark(ptr=function_addr, note=function_name) def on_context_setup(self): self.memory_panel.on_context_setup() def on_memory_modified(self, pos, length): data_pos = self.memory_panel.base + pos data = self.memory_panel.data[pos:pos + length] data = [data[0]] # todo: strange js part if self.dwarf.dwarf_api('writeBytes', [data_pos, data]): pass else: utils.show_message_box('Failed to write Memory') def raise_memory_panel(self): self.dock_memory_panel.raise_() def raise_disassembly_panel(self): self.dock_disassembly_panel.raise_() def jump_to_address(self, address, view=DEBUG_VIEW_MEMORY): address = utils.parse_ptr(address) if view == DEBUG_VIEW_MEMORY: if self.memory_panel.number_of_lines() > 0: if self.is_address_in_view(view, address): return elif view == DEBUG_VIEW_DISASSEMBLY: if self.disassembly_panel.number_of_lines() > 0: if self.is_address_in_view(view, address): return self.app.show_progress('reading data...') self.app.dwarf.read_range_async( address, lambda base, data, offset: self._apply_data( base, data, offset, view=view)) def _apply_data(self, base, data, offset, view=DEBUG_VIEW_MEMORY): self.app.hide_progress() self.update_functions() if view == DEBUG_VIEW_MEMORY: self.memory_panel.set_data(data, base=base, offset=offset) if not self.dock_memory_panel.isVisible(): self.dock_memory_panel.show() self.raise_memory_panel() if self.disassembly_panel.number_of_lines() == 0: self.disassembly_panel.disasm(base, data, offset) elif view == DEBUG_VIEW_DISASSEMBLY: self.disassembly_panel.disasm(base, data, offset) if not self.dock_disassembly_panel.isVisible(): self.dock_disassembly_panel.show() self.raise_disassembly_panel() if self.memory_panel.number_of_lines() == 0: self.memory_panel.set_data(data, base=base, offset=offset) def is_address_in_view(self, view, address): if view == DEBUG_VIEW_MEMORY: if self.memory_panel.data: ptr_exists = self.memory_panel.base <= address <= self.memory_panel.base + len( self.memory_panel.data) if ptr_exists: self.memory_panel.caret.position = address - self.memory_panel.base return True elif view == DEBUG_VIEW_DISASSEMBLY: if self.disassembly_panel.visible_lines() > 0: line_index_for_address = self.disassembly_panel.get_line_for_address( address) if line_index_for_address >= 0: self.disassembly_panel.highlighted_line = line_index_for_address self.disassembly_panel.verticalScrollBar().setValue( line_index_for_address) return True return False def on_cm_jump_to_address(self, view=DEBUG_VIEW_MEMORY): ptr, _ = InputDialog.input_pointer(self.app) if ptr > 0: self.jump_to_address(ptr, view=view) def dump_data(self, address, _len): def _dump(ptr, data): if data is not None: from PyQt5.QtWidgets import QFileDialog _file = QFileDialog.getSaveFileName(self.app) with open(_file[0], 'wb') as f: f.write(data) self.app.dwarf.read_memory_async(address, _len, _dump)
def __init__(self, plugin, *__args): super().__init__(*__args) self.plugin = plugin self.app = plugin.app self.emulator = plugin.emulator self.until_address = 0 self._uc_user_arch = None self._uc_user_mode = None self._cs_user_arch = None self._cs_user_mode = None layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self._toolbar_container = QHBoxLayout() self._toolbar = QToolBar() self._toolbar.addAction('Start', self.handle_start) self._toolbar.addAction('Step', self.handle_step) self._toolbar.addAction('Step next call', self.handle_step_next_call) self._toolbar.addAction('Stop', self.handle_stop) self._toolbar.addAction('Clear', self.handle_clear) self._toolbar.addAction('Options', self.handle_options) self._toolbar_container.addWidget(self._toolbar) selection_layout = QHBoxLayout() selection_layout.setAlignment(Qt.AlignRight) self.cpu_selection = QComboBox(self) index = 0 for v in unicorn_const.__dict__: if 'UC_ARCH_' in v: item = '_'.join(v.split('_')[2:]).lower() if self.app.dwarf.arch == item: index = self.cpu_selection.count() elif self.app.dwarf.arch == 'x64' and item == 'x86' or self.app.dwarf == 'ia32' and item == 'x86': index = self.cpu_selection.count() self.cpu_selection.addItem(item, unicorn_const.__dict__[v]) self.cpu_selection.activated[str].connect(self._on_cpu_selection) self.cpu_selection.setCurrentIndex(index) self.mode_selection = QComboBox(self) index = 0 for v in unicorn_const.__dict__: if 'UC_MODE_' in v: item = '_'.join(v.split('_')[2:]).lower() if self.app.dwarf.arch == item: index = self.mode_selection.count() elif (self.app.dwarf.arch == 'x64' or self.app.dwarf.arch == 'arm64') and item == '64': index = self.mode_selection.count() elif self.app.dwarf.arch == 'ia32' and item == '32': index = self.mode_selection.count() self.mode_selection.addItem(item, unicorn_const.__dict__[v]) self.mode_selection.activated[str].connect(self._on_mode_selection) self.mode_selection.setCurrentIndex(index) selection_layout.addWidget(self.cpu_selection) selection_layout.addWidget(self.mode_selection) self._toolbar_container.addLayout(selection_layout) layout.addLayout(self._toolbar_container) self.tabs = QTabWidget() self.assembly = DisassemblyView(self.app) self.assembly.display_jumps = False self.assembly.follow_jumps = False #self.memory_table = HexEditor(self.app) #self.memory_table._read_only = True self.tabs.addTab(self.assembly, 'Code') #self.tabs.addTab(self.memory_table, 'Memory') layout.addWidget(self.tabs) self.ranges_list = DwarfListView(self.app) self.ranges_list.doubleClicked.connect(self.ranges_item_double_clicked) self._ranges_model = QStandardItemModel(0, 2) self._ranges_model.setHeaderData(0, Qt.Horizontal, 'Memory') self._ranges_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(1, Qt.Horizontal, 'Size') self.ranges_list.setModel(self._ranges_model) self.tabs.addTab(self.ranges_list, 'Ranges') self._access_list = DwarfListView(self.app) self._access_list.doubleClicked.connect( self.access_item_double_clicked) self._access_model = QStandardItemModel(0, 3) self._access_model.setHeaderData(0, Qt.Horizontal, 'Address') self._access_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(1, Qt.Horizontal, 'Access') self._access_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(2, Qt.Horizontal, 'Value') self._access_list.setModel(self._access_model) self.tabs.addTab(self._access_list, 'Access') layout.setSpacing(0) self.setLayout(layout) self.console = plugin.console self.emulator.onEmulatorSetup.connect(self.on_emulator_setup) self.emulator.onEmulatorStart.connect(self.on_emulator_start) self.emulator.onEmulatorStop.connect(self.on_emulator_stop) # self.emulator.onEmulatorStep.connect(self.on_emulator_step) self.emulator.onEmulatorHook.connect(self.on_emulator_hook) self.emulator.onEmulatorMemoryHook.connect( self.on_emulator_memory_hook) self.emulator.onEmulatorMemoryRangeMapped.connect( self.on_emulator_memory_range_mapped) self.emulator.onEmulatorLog.connect(self.on_emulator_log) self._require_register_result = None self._last_instruction_address = 0
class EmulatorPanel(QWidget): def __init__(self, plugin, *__args): super().__init__(*__args) self.plugin = plugin self.app = plugin.app self.emulator = plugin.emulator self.until_address = 0 self._uc_user_arch = None self._uc_user_mode = None self._cs_user_arch = None self._cs_user_mode = None layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self._toolbar_container = QHBoxLayout() self._toolbar = QToolBar() self._toolbar.addAction('Start', self.handle_start) self._toolbar.addAction('Step', self.handle_step) self._toolbar.addAction('Step next call', self.handle_step_next_call) self._toolbar.addAction('Stop', self.handle_stop) self._toolbar.addAction('Clear', self.handle_clear) self._toolbar.addAction('Options', self.handle_options) self._toolbar_container.addWidget(self._toolbar) selection_layout = QHBoxLayout() selection_layout.setAlignment(Qt.AlignRight) self.cpu_selection = QComboBox(self) index = 0 for v in unicorn_const.__dict__: if 'UC_ARCH_' in v: item = '_'.join(v.split('_')[2:]).lower() if self.app.dwarf.arch == item: index = self.cpu_selection.count() elif self.app.dwarf.arch == 'x64' and item == 'x86' or self.app.dwarf == 'ia32' and item == 'x86': index = self.cpu_selection.count() self.cpu_selection.addItem(item, unicorn_const.__dict__[v]) self.cpu_selection.activated[str].connect(self._on_cpu_selection) self.cpu_selection.setCurrentIndex(index) self.mode_selection = QComboBox(self) index = 0 for v in unicorn_const.__dict__: if 'UC_MODE_' in v: item = '_'.join(v.split('_')[2:]).lower() if self.app.dwarf.arch == item: index = self.mode_selection.count() elif (self.app.dwarf.arch == 'x64' or self.app.dwarf.arch == 'arm64') and item == '64': index = self.mode_selection.count() elif self.app.dwarf.arch == 'ia32' and item == '32': index = self.mode_selection.count() self.mode_selection.addItem(item, unicorn_const.__dict__[v]) self.mode_selection.activated[str].connect(self._on_mode_selection) self.mode_selection.setCurrentIndex(index) selection_layout.addWidget(self.cpu_selection) selection_layout.addWidget(self.mode_selection) self._toolbar_container.addLayout(selection_layout) layout.addLayout(self._toolbar_container) self.tabs = QTabWidget() self.assembly = DisassemblyView(self.app) self.assembly.display_jumps = False self.assembly.follow_jumps = False #self.memory_table = HexEditor(self.app) #self.memory_table._read_only = True self.tabs.addTab(self.assembly, 'Code') #self.tabs.addTab(self.memory_table, 'Memory') layout.addWidget(self.tabs) self.ranges_list = DwarfListView(self.app) self.ranges_list.doubleClicked.connect(self.ranges_item_double_clicked) self._ranges_model = QStandardItemModel(0, 2) self._ranges_model.setHeaderData(0, Qt.Horizontal, 'Memory') self._ranges_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(1, Qt.Horizontal, 'Size') self.ranges_list.setModel(self._ranges_model) self.tabs.addTab(self.ranges_list, 'Ranges') self._access_list = DwarfListView(self.app) self._access_list.doubleClicked.connect( self.access_item_double_clicked) self._access_model = QStandardItemModel(0, 3) self._access_model.setHeaderData(0, Qt.Horizontal, 'Address') self._access_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(1, Qt.Horizontal, 'Access') self._access_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(2, Qt.Horizontal, 'Value') self._access_list.setModel(self._access_model) self.tabs.addTab(self._access_list, 'Access') layout.setSpacing(0) self.setLayout(layout) self.console = plugin.console self.emulator.onEmulatorSetup.connect(self.on_emulator_setup) self.emulator.onEmulatorStart.connect(self.on_emulator_start) self.emulator.onEmulatorStop.connect(self.on_emulator_stop) # self.emulator.onEmulatorStep.connect(self.on_emulator_step) self.emulator.onEmulatorHook.connect(self.on_emulator_hook) self.emulator.onEmulatorMemoryHook.connect( self.on_emulator_memory_hook) self.emulator.onEmulatorMemoryRangeMapped.connect( self.on_emulator_memory_range_mapped) self.emulator.onEmulatorLog.connect(self.on_emulator_log) self._require_register_result = None self._last_instruction_address = 0 def _on_cpu_selection(self, cpu): self._uc_user_arch = unicorn_const.__dict__['UC_ARCH_' + cpu.upper()] self._cs_user_arch = capstone.__dict__['CS_ARCH_' + cpu.upper()] self._uc_user_mode = unicorn_const.__dict__[ 'UC_MODE_' + self.mode_selection.itemText( self.mode_selection.currentIndex()).upper()] self._cs_user_mode = capstone.__dict__[ 'CS_MODE_' + self.mode_selection.itemText( self.mode_selection.currentIndex()).upper()] def _on_mode_selection(self, mode): self._uc_user_mode = unicorn_const.__dict__['UC_MODE_' + mode.upper()] self._cs_user_mode = capstone.__dict__['CS_MODE_' + mode.upper()] self._uc_user_arch = unicorn_const.__dict__[ 'UC_ARCH_' + self.cpu_selection.itemText( self.cpu_selection.currentIndex()).upper()] self._cs_user_arch = capstone.__dict__[ 'CS_ARCH_' + self.cpu_selection.itemText( self.cpu_selection.currentIndex()).upper()] def resizeEvent(self, event): self.ranges_list.setFixedHeight((self.height() / 100) * 25) self.ranges_list.setFixedWidth((self.width() / 100) * 30) self._access_list.setFixedHeight((self.height() / 100) * 25) return super().resizeEvent(event) def handle_clear(self): self.ranges_list.clear() self._access_list.clear() self.assembly._lines.clear() self.assembly.viewport().update() # self.memory_table.setRowCount(0) self.console.clear() self.emulator.clean() def handle_options(self): EmulatorConfigsDialog.show_dialog(self.app.dwarf) def handle_start(self): ph = '' if self.until_address > 0: ph = hex(self.until_address) address, inp = InputDialog.input_pointer( self.app, input_content=ph, hint='pointer to last instruction') if address > 0: self.until_address = address self.app.console_panel.show_console_tab('emulator') self.emulator.emulate(self.until_address, user_arch=self._uc_user_arch, user_mode=self._uc_user_mode, cs_arch=self._cs_user_arch, cs_mode=self._cs_user_mode) # if err > 0: # self.until_address = 0 # self.console.log('cannot start emulator. err: %d' % err) # return def handle_step(self): self.app.console_panel.show_console_tab('emulator') try: self.emulator.emulate(step_mode=STEP_MODE_SINGLE, user_arch=self._uc_user_arch, user_mode=self._uc_user_mode, cs_arch=self._cs_user_arch, cs_mode=self._cs_user_mode) except self.emulator.EmulatorAlreadyRunningError: self.console.log('Emulator already running') except self.emulator.EmulatorSetupFailedError as error: self.until_address = 0 self.console.log(error) def handle_step_next_call(self): self.app.console_panel.show_console_tab('emulator') try: self.emulator.emulate(step_mode=STEP_MODE_FUNCTION, user_arch=self._uc_user_arch, user_mode=self._uc_user_mode, cs_arch=self._cs_user_arch, cs_mode=self._cs_user_mode) except self.emulator.EmulatorAlreadyRunningError: self.console.log('Emulator already running') except self.emulator.EmulatorSetupFailedError as error: self.until_address = 0 self.console.log(error) def handle_stop(self): self.emulator.stop() def on_emulator_hook(self, instruction): # @PinkiePonkie why setting context here (which is triggered each instruction) and later, set it again # in emulator_stop? step = double hit in set_context, running emulation on more than 1 instruction # doesn't need spam of set_context # self.app.context_panel.set_context(0, 2, self.emulator.current_context) # check if the previous hook is waiting for a register result if self._require_register_result is not None: row = 1 if len(self._require_register_result) == 1: res = 'jump = %s' % (hex(self._require_register_result[0])) else: res = '%s = %s' % (self._require_register_result[1], hex( self.emulator.uc.reg_read( self._require_register_result[0]))) if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 telescope = self.get_telescope( self.emulator.uc.reg_read( self._require_register_result[0])) if telescope is not None and telescope != 'None': res += ' (' + telescope + ')' self.assembly._lines[len(self.assembly._lines) - row].string = res # invalidate self._require_register_result = None # check if the code jumped self._last_instruction_address = instruction.address self.assembly.add_instruction(instruction) # add empty line if jump if instruction.is_jump or instruction.is_call: self.assembly.add_instruction(None) self._require_register_result = [ instruction.jump_address if instruction.is_jump else instruction.call_address ] else: # implicit regs read are notified later through mem access if len(instruction.regs_read) == 0: if len(instruction.operands) > 0: for i in instruction.operands: if i.type == capstone.CS_OP_REG: self._require_register_result = [ i.value.reg, instruction.reg_name(i.value.reg) ] break self.assembly.verticalScrollBar().setValue(len(self.assembly._lines)) self.assembly.viewport().update() if instruction.is_call: range_ = Range.build_or_get(self.app.dwarf, instruction.address) if range_.base > instruction.call_address > range_.tail: if self.emulator.step_mode == STEP_MODE_NONE: self.emulator.stop() action = JumpOutsideTheBoxDialog.show_dialog(self.app.dwarf) if action == 0: # step to jump if self.emulator.step_mode != STEP_MODE_NONE: self.handle_step() else: self.emulator.emulate(self.until_address, user_arch=self._uc_user_arch, user_mode=self._uc_user_mode, cs_arch=self._cs_user_arch, cs_mode=self._cs_user_mode) if action == 1: # step to next jump if self.emulator.step_mode != STEP_MODE_NONE: self.handle_step_next_jump() else: self.emulator.emulate(self.until_address, user_arch=self._uc_user_arch, user_mode=self._uc_user_mode, cs_arch=self._cs_user_arch, cs_mode=self._cs_user_mode) elif action == 2: # hook lr hook_addr = instruction.address + instruction.size if instruction.thumb: hook_addr += 1 self.app.dwarf.hook_native(input_=hex(hook_addr)) def on_emulator_log(self, log): self.app.console_panel.show_console_tab('emulator') self.console.log(log) def on_emulator_memory_hook(self, data): uc, access, address, value = data _address = QStandardItem() if self.ranges_list.uppercase_hex: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016X}'.format(address) else: str_frmt = '0x{0:08X}'.format(address) else: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016x}'.format(address) else: str_frmt = '0x{0:08x}'.format(address) _address.setText(str_frmt) _address.setTextAlignment(Qt.AlignCenter) _access = QStandardItem() if access == UC_MEM_READ: _access.setText('READ') elif access == UC_MEM_WRITE: _access.setText('WRITE') elif access == UC_MEM_FETCH: _access.setText('FETCH') _access.setTextAlignment(Qt.AlignCenter) _value = QStandardItem() _value.setText(str(value)) self._access_model.appendRow([_address, _access, _value]) res = None row = 1 if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 if access == UC_MEM_READ: if self._require_register_result is not None: if len(self._require_register_result) > 1: res = '%s = %s' % (self._require_register_result[1], hex(value)) else: if self.assembly._lines[len(self.assembly._lines) - row].string: res = '%s, %s = %s' % (self.assembly._lines[ len(self.assembly._lines) - row].string, hex(address), hex(value)) else: res = '%s = %s' % (hex(address), hex(value)) if res is not None: telescope = self.get_telescope(value) if telescope is not None and telescope != 'None': res += ' (' + telescope + ')' # invalidate self._require_register_result = None self.assembly._lines[len(self.assembly._lines) - row].string = res def get_telescope(self, address): try: size = self.app.dwarf.pointer_size telescope = self.emulator.uc.mem_read(address, size) try: for i in range(len(telescope)): if int(telescope[i]) == 0x0 and i != 0: st = telescope.decode('utf8') return st st = telescope.decode('utf8') if len(st) != size: return '0x%s' % telescope.hex() while True: telescope = self.emulator.uc.mem_read(address + size, 1) if int(telescope) == 0x0: break st += telescope.decode('utf8') size += 1 return st except: return '0x%s' % telescope.hex() except UcError as e: # read from js telescope = self.app.dwarf.dwarf_api('getAddressTs', address) if telescope is None: return None telescope = str(telescope[1]).replace('\n', ' ') if len(telescope) > 50: telescope = telescope[:50] + '...' return telescope def on_emulator_memory_range_mapped(self, data): address, size = data _address = QStandardItem() if self.ranges_list.uppercase_hex: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016X}'.format(address) else: str_frmt = '0x{0:08X}'.format(address) else: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016x}'.format(address) else: str_frmt = '0x{0:08x}'.format(address) _address.setText(str_frmt) _address.setTextAlignment(Qt.AlignCenter) _size = QStandardItem() _size.setText("{0:,d}".format(int(size))) self._ranges_model.appendRow([_address, _size]) def on_emulator_setup(self, data): user_arch = data[0] user_mode = data[1] if user_arch is not None and user_mode is not None: index = self.cpu_selection.findData(user_arch) self.cpu_selection.setCurrentIndex(index) index = self.mode_selection.findData(user_mode) self.mode_selection.setCurrentIndex(index) def on_emulator_start(self): pass def on_emulator_stop(self): self.plugin.emulator_context_widget.set_context( 0, self.emulator.current_context) # check if the previous hook is waiting for a register result if self._require_register_result is not None: row = 1 if len(self._require_register_result) == 1: res = 'jump = %s' % (hex(self._require_register_result[0])) else: res = '%s = %s' % (self._require_register_result[1], hex( self.emulator.uc.reg_read( self._require_register_result[0]))) telescope = self.get_telescope( self.emulator.uc.reg_read( self._require_register_result[0])) if telescope is not None and telescope != 'None': res += ' (' + telescope + ')' if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 self.assembly._lines[len(self.assembly._lines) - row].string = res # invalidate self._require_register_result = None def ranges_item_double_clicked(self, model_index): row = self._ranges_model.itemFromIndex(model_index).row() if row != -1: item = self._ranges_model.item(row, 0).text() #self.memory_table.read_memory(item) self.tabs.setCurrentIndex(1) def access_item_double_clicked(self, model_index): row = self._access_model.itemFromIndex(model_index).row() if row != -1: item = self._access_model.item(row, 0).text() #self.memory_table.read_memory(item) self.tabs.setCurrentIndex(1)