def _on_delete_breakpoint(self, num_row): breakpoint_type = self._breakpoints_model.item(num_row, 1).text() if breakpoint_type == 'N': ptr = self._breakpoints_model.item(num_row, 0).text() ptr = utils.parse_ptr(ptr) self._app_window.dwarf.dwarf_api('removeBreakpoint', ptr) self.onBreakpointRemoved.emit(str(ptr)) elif breakpoint_type == 'J': target = self._breakpoints_model.item(num_row, 0).text() self._app_window.dwarf.dwarf_api('removeBreakpoint', target) elif breakpoint_type == 'C': item = self._breakpoints_model.item(num_row, 0) target = item.text() is_native = item.data(Qt.UserRole + 2) is None if is_native: self._app_window.dwarf.dwarf_api( 'removeModuleInitializationBreakpoint', target) else: self._app_window.dwarf.dwarf_api( 'removeJavaClassInitializationBreakpoint', target) elif breakpoint_type == 'U': ptr = self._breakpoints_model.item(num_row, 0).text() ptr = utils.parse_ptr(ptr) self._app_window.dwarf.dwarf_api('removeBreakpoint', ptr) self.onBreakpointRemoved.emit(str(ptr))
def _on_showmemory_request(self, ptr): # its simple ptr show in memorypanel if isinstance(ptr, str): ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr, 0) elif isinstance(ptr, list): # TODO: extend caller, ptr = ptr ptr = utils.parse_ptr(ptr) if caller == 'backtrace' or caller == 'bt': # jumpto in disasm self.jump_to_address(ptr, 1)
def _on_hook_deleted(self, parts): _msg, _type, _val = parts additional = None if _type == 'java' or _type == 'java_on_load': _val = _val.split('.') str_frmt = '.'.join(_val[:-1]) additional = _val[-1] item_index = 0 elif _type == 'native_on_load': str_frmt = _val item_index = 2 else: _ptr = utils.parse_ptr(_val) if self._hooks_list._uppercase_hex: str_frmt = '0x{0:X}'.format(_ptr) else: str_frmt = '0x{0:x}'.format(_ptr) item_index = 0 for _item in range(self._hooks_model.rowCount()): item = self._hooks_model.item(_item, item_index) if item is None: continue if str_frmt == item.text(): if additional is not None: if additional == self._hooks_model.item(_item, 2).text(): self._hooks_model.removeRow(_item) else: self._hooks_model.removeRow(_item)
def read_async(self, ptr, length, callback): ptr = utils.parse_ptr(ptr) reader = Reader(self, ptr, length) reader.ioReaderFinish.connect( lambda x: self._on_io_reader_finish(x[0], x[1], callback)) self.refs[hex(ptr)] = reader reader.start()
def _on_dump_module(self, data): """ DumpBinary MenuItem in ModulePanel was selected """ ptr, size = data ptr = utils.parse_ptr(ptr) size = int(size, 10) self.dwarf.dump_memory(ptr=ptr, length=size)
def _on_watcher_added(self, ptr, flags): """ Callback from Dwarf after Watcher is added """ ptr = utils.parse_ptr(ptr) # add to watcherslist self.add_address(ptr, flags, from_api=True) self.onItemAdded.emit(ptr)
def search(self, start, size, pattern): # sanify args start = utils.parse_ptr(start) size = int(size) # convert to frida accepted pattern pattern = ' '.join([pattern[i:i + 2] for i in range(0, len(pattern), 2)]) self.dwarf_api('memoryScan', [start, size, pattern])
def breakpoint_native(self, input_=None): if input_ is None or not isinstance(input_, str): ptr, input_ = InputDialog.input_pointer(self._app_window) else: ptr = utils.parse_ptr(self._app_window.dwarf.dwarf_api('evaluatePtr', input_)) if ptr > 0: self.dwarf_api('putBreakpoint', ptr)
def _on_breakpoint_deleted(self, parts): _msg, _type, _val = parts additional = None if _type == 'java' or _type == 'java_class_initialization': str_frmt = _val item_index = 0 elif _type == 'module_initialization': str_frmt = _val item_index = 0 else: _ptr = utils.parse_ptr(_val) if self._breakpoints_list._uppercase_hex: str_frmt = '0x{0:X}'.format(_ptr) else: str_frmt = '0x{0:x}'.format(_ptr) item_index = 0 for _item in range(self._breakpoints_model.rowCount()): item = self._breakpoints_model.item(_item, item_index) if item is None: continue if str_frmt == item.text(): if additional is not None: if additional == self._breakpoints_model.item(_item, 2).text(): self._breakpoints_model.removeRow(_item) else: self._breakpoints_model.removeRow(_item)
def _on_watchpoint_removed(self, ptr): """ Callback from Dwarf after watchpoint is removed """ ptr = utils.parse_ptr(ptr) # remove from list self.remove_address(ptr, from_api=True) self.onItemRemoved.emit(ptr)
def _on_add_hook(self, hook): try: # set highlight ptr = hook.get_ptr() ptr = utils.parse_ptr(ptr) self.debug_panel.memory_panel.add_highlight( HighLight('hook', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass
def _on_add_breakpoint(self, breakpoint): try: # set highlight ptr = breakpoint.get_target() ptr = utils.parse_ptr(ptr) self.debug_panel.memory_panel.add_highlight( HighLight('breakpoint', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass
def _on_delete_hook(self, num_row): hook_type = self._hooks_model.item(num_row, 1).text() if hook_type == 'N': ptr = self._hooks_model.item(num_row, 0).text() ptr = utils.parse_ptr(ptr) self._app_window.dwarf.dwarf_api('deleteHook', ptr) self.onHookRemoved.emit(str(ptr)) elif hook_type == 'J': input_ = self._hooks_model.item(num_row, 2).data(Qt.UserRole + 2) self._app_window.dwarf.dwarf_api('deleteHook', input_) elif hook_type == 'O': input_ = self._hooks_model.item(num_row, 2).data(Qt.UserRole + 2) self._app_window.dwarf.dwarf_api('deleteHook', input_) elif hook_type == 'U': ptr = self._hooks_model.item(num_row, 0).text() ptr = utils.parse_ptr(ptr) self._app_window.dwarf.dwarf_api('deleteHook', ptr) self.onHookRemoved.emit(str(ptr))
def read_range_async(self, ptr, callback): ptr = utils.parse_ptr(ptr) if hex(ptr) in self.refs: # already reading this range return reader = Reader(self, ptr, 0) reader.ioReaderFinish.connect(lambda x: self._on_io_reader_range_finish(x[0], x[1], x[2], callback)) self.refs[hex(ptr)] = reader reader.start()
def hook_native(self, input_=None, pending_args=None, own_input=None): if input_ is None or not isinstance(input_, str): ptr, input_ = InputDialog.input_pointer(self._app_window) else: ptr = utils.parse_ptr( self._app_window.dwarf.dwarf_api('evaluatePtr', input_)) if ptr > 0: self.temporary_input = input_ if own_input is not None: self.temporary_input = own_input self.native_pending_args = pending_args self.dwarf_api('hookNative', ptr)
def do_addwatchpoint_dlg(self, ptr=None): # pylint: disable=too-many-branches """ Shows AddWatchpointDialog """ watchpoint_dlg = AddWatchpointDialog(self, ptr) if watchpoint_dlg.exec_() == QDialog.Accepted: mem_r = watchpoint_dlg.acc_read.isChecked() mem_w = watchpoint_dlg.acc_write.isChecked() mem_x = watchpoint_dlg.acc_execute.isChecked() mem_s = watchpoint_dlg.singleshot.isChecked() ptr = watchpoint_dlg.text_field.toPlainText() if ptr: if isinstance(ptr, str): if ptr.startswith('0x') or ptr.startswith('#'): ptr = utils.parse_ptr(ptr) else: try: ptr = int(ptr, 10) except ValueError: pass # int now? if not isinstance(ptr, int): try: ptr = int( self._app_window.dwarf.dwarf_api( 'evaluatePtr', ptr), 16) except ValueError: ptr = 0 if ptr == 0: return if not self._app_window.dwarf.dwarf_api( 'isValidPointer', ptr): return else: return mem_val = 0 if mem_r: mem_val |= self.MEMORY_ACCESS_READ if mem_w: mem_val |= self.MEMORY_ACCESS_WRITE if mem_x: mem_val |= self.MEMORY_ACCESS_EXECUTE if mem_s: mem_val |= self.MEMORY_WATCH_SINGLESHOT self.add_address(ptr, mem_val, from_api=False)
def add_address(self, ptr, flags, from_api=False): """ Adds Address to display ptr - str or int flags - int """ if isinstance(ptr, str): ptr = utils.parse_ptr(ptr) if not isinstance(flags, int): try: flags = int(flags, 10) except ValueError: flags = 3 if not from_api: # function was called directly so add it to dwarf if not self._app_window.dwarf.is_address_watched(ptr): self._app_window.dwarf.dwarf_api('putWatchpoint', [ptr, flags]) return # show header self.list_view.setHeaderHidden(False) # create items to add if self._uppercase_hex: str_frmt = '0x{0:X}' else: str_frmt = '0x{0:x}' addr = QStandardItem() addr.setText(str_frmt.format(ptr)) read = QStandardItem() write = QStandardItem() execute = QStandardItem() singleshot = QStandardItem() if flags & self.MEMORY_ACCESS_READ: read.setIcon(self._dot_icon) if flags & self.MEMORY_ACCESS_WRITE: write.setIcon(self._dot_icon) if flags & self.MEMORY_ACCESS_EXECUTE: execute.setIcon(self._dot_icon) if flags & self.MEMORY_WATCH_SINGLESHOT: singleshot.setIcon(self._dot_icon) # add items as new row on top self._watchpoints_model.insertRow( 0, [addr, read, write, execute, singleshot])
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.dwarf.read_range_async( address, lambda base, data, offset: self._apply_data( base, data, offset, view=view))
def _on_modify_logic(self, num_row): item = self._hooks_model.item(num_row, 3) data = item.data(Qt.UserRole + 2) if data is None: data = '' ptr = self._hooks_model.item(num_row, 0).text() accept, input_ = InputMultilineDialog().input('Insert logic for %s' % ptr, input_content=data) if accept: what = utils.parse_ptr(ptr) if what == 0: what = self._hooks_model.item(num_row, 2).data(Qt.UserRole + 2) if self._app_window.dwarf.dwarf_api( 'setHookLogic', [what, input_.replace('\n', '')]): item.setData(input_, Qt.UserRole + 2) if not item.text(): item.setText('ƒ') item.setToolTip(input_) self.onHookChanged.emit(ptr)
def _on_modify_condition(self, num_row): item = self._hooks_model.item(num_row, 4) data = item.data(Qt.UserRole + 2) if data is None: data = '' ptr = self._hooks_model.item(num_row, 0).text() accept, input_ = InputDialog().input(self._app_window, 'Insert condition for %s' % ptr, input_content=data) if accept: what = utils.parse_ptr(ptr) if what == 0: what = self._hooks_model.item(num_row, 2).data(Qt.UserRole + 2) if self._app_window.dwarf.dwarf_api('setHookCondition', [what, input_]): item.setData(input_, Qt.UserRole + 2) if not item.text(): item.setText('ƒ') item.setToolTip(input_) self.onHookChanged.emit(ptr)
def remove_address(self, ptr, from_api=False): """ Remove Address from List """ if isinstance(ptr, str): ptr = utils.parse_ptr(ptr) if not from_api: # called somewhere so remove watchpoint in dwarf too self._app_window.dwarf.dwarf_api('removeWatchpoint', ptr) return str_frmt = '' if self._uppercase_hex: str_frmt = '0x{0:X}'.format(ptr) else: str_frmt = '0x{0:x}'.format(ptr) model = self.list_view.model() for item in range(model.rowCount()): if str_frmt == model.item(item).text(): model.removeRow(item)
def _on_modify_condition(self, num_row): item = self._breakpoints_model.item(num_row, 2) data = item.data(Qt.UserRole + 2) if data is None: data = '' ptr = self._breakpoints_model.item(num_row, 0).text() accept, input_ = InputMultilineDialog().input( 'Condition for breakpoint %s' % ptr, input_content=data) if accept: what = utils.parse_ptr(ptr) if what == 0: what = self._breakpoints_model.item(num_row, 2).data(Qt.UserRole + 2) if self._app_window.dwarf.dwarf_api( 'setBreakpointCondition', [what, input_.replace('\n', '')]): item.setData(input_, Qt.UserRole + 2) if not item.text(): item.setText('ƒ') item.setToolTip(input_) self.onBreakpointChanged.emit(ptr)
def read_range_data(self): data = bytes() base = 0 try: _range = self.dwarf.dwarf_api('getRange', self.ptr) if _range: if _range['protection'][0] == 'r': base = utils.parse_ptr(_range['base']) self.ptr = base self.length = _range['size'] hex_base = hex(base) if hex_base in self.io.range_cache: data = self.io.range_cache[hex_base] else: data = self.read_data() if data: self.io.range_cache[hex_base] = data except Exception as e: print('IO - failed to read data') raise e return base, data
def _create_bookmark(self, index=-1, ptr='', note=''): if ptr == '': if isinstance(index, int) and index >= 0: ptr = self._bookmarks_model.item(index, 0).text() note = self._bookmarks_model.item(index, 1).text() ptr, _ = InputDialog.input_pointer(parent=self._app_window, input_content=ptr) else: ptr = utils.parse_ptr(ptr) if ptr > 0: ptr = hex(ptr) if self._bookmarks_list.uppercase_hex: ptr = ptr.upper().replace('0X', '0x') index = self._bookmarks_model.findItems(ptr, Qt.MatchExactly) if len(index) > 0: index = index[0].row() note = self._bookmarks_model.item(index, 1).text() else: index = -1 accept = note != '' if note == '': accept, note = InputDialog.input(hint='Insert notes for %s' % ptr, input_content=note) if accept: if index < 0: self.insert_bookmark(ptr, note) else: item = self._bookmarks_model.item(index, 0) item.setText(ptr) item = self._bookmarks_model.item(index, 1) item.setText(note) self.bookmarks[ptr] = note
def get_line_for_address(self, ptr): ptr = utils.parse_ptr(ptr) for x in range(len(self._lines)): if self._lines[x].address == ptr: return x return -1
def _on_breakpoint_removed(self, ptr): ptr = utils.parse_ptr(ptr) self.debug_panel.memory_panel.remove_highlight(ptr)
def read_range(self, ptr): ptr = utils.parse_ptr(ptr) reader = Reader(self, ptr, 0) base, data = reader.read_range_data() return base, data, ptr - base
def _range_dblclicked(self, ptr): """ Range in RangesPanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr)
def _on_module_dblclicked(self, data): """ Module in ModulePanel was doubleclicked """ addr, size = data addr = utils.parse_ptr(addr) self.jump_to_address(addr)
def _on_modulefunc_dblclicked(self, ptr): """ Function in ModulePanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr)