def _module_clicked(self): """ Module Clicked updates imports/exports/symbols """ if not self.modules_list.hasFocus(): return module_index = self.modules_list.selectionModel().currentIndex().row() module_name = self.modules_model.item(module_index, 0) if module_name is None: return module_name = module_name.text() module_address = self.modules_model.item(module_index, 1).text() module_info = self._app_window.dwarf.database.get_module_info( module_address) if module_info is not None: if not module_info.have_details: module_info = ModuleInfo.build_module_info( self._app_window.dwarf, module_name, fill_ied=True) else: module_info = ModuleInfo.build_module_info(self._app_window.dwarf, module_name, fill_ied=True) if module_info is not None: self.update_module_ui(module_info) if not self._sized: self.setSizes([100, 100]) self._sized = True
def _apply_data(self, base, data, offset, view=DEBUG_VIEW_MEMORY): # make sure we have that module in db before updating functions ModuleInfo.build_module_info(self.app.dwarf, base, fill_ied=True) 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 read_range_data(self): data = bytes() base = 0 try: _range = self.dwarf.dwarf_api('getRange', self.ptr) if _range: # make sure we have module info ModuleInfo.build_module_info(self.dwarf, self.ptr, fill_ied=True) 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 add_module(self, module): name = QStandardItem() name.setTextAlignment(Qt.AlignLeft) if 'name' in module: name.setText(module['name']) base = QStandardItem() base.setTextAlignment(Qt.AlignCenter) str_fmt = '0x{0:X}' if not self.uppercase_hex: str_fmt = '0x{0:x}' if 'base' in module: base.setText(str_fmt.format(int(module['base'], 16))) size = QStandardItem() size.setTextAlignment(Qt.AlignRight) if 'size' in module: size.setText("{0:,d}".format(int(module['size']))) path = QStandardItem() path.setTextAlignment(Qt.AlignLeft) if 'path' in module: path.setText(module['path']) self.modules_model.appendRow([name, base, size, path]) module_info = ModuleInfo(module) if 'exports' in module and module['exports']: module_info.apply_exports(module['exports']) if 'imports' in module and module['imports']: module_info.apply_imports(module['imports']) if 'symbols' in module and module['symbols']: module_info.apply_symbols(module['symbols']) module_info._updated_details = True
def _on_message(self, message, data): QApplication.processEvents() if 'payload' not in message: print('payload: ' + str(message)) return self.onReceiveCmd.emit([message, data]) what = message['payload'] parts = what.split(':::') if len(parts) < 2: return cmd = parts[0] if cmd == 'api_ping_timeout': self._script.post({"type": str(parts[1])}) elif cmd == 'backtrace': self.onBackTrace.emit(json.loads(parts[1])) elif cmd == 'class_loader_loading_class': str_fmt = ('@thread {0} loading class := {1}'.format(parts[1], parts[2])) self.log_event(str_fmt) elif cmd == 'enumerate_java_classes_start': self.onEnumerateJavaClassesStart.emit() elif cmd == 'enumerate_java_classes_match': self.onEnumerateJavaClassesMatch.emit(parts[1]) elif cmd == 'enumerate_java_classes_complete': self.onEnumerateJavaClassesComplete.emit() elif cmd == 'enumerate_java_methods_complete': self.onEnumerateJavaMethodsComplete.emit([parts[1], json.loads(parts[2])]) elif cmd == 'enumerate_objc_modules': modules = json.loads(parts[1]) self.onEnumerateObjCModules.emit(modules) elif cmd == 'enumerate_objc_classes_start': self.onEnumerateObjCClassesStart.emit() elif cmd == 'enumerate_objc_classes_match': self.onEnumerateObjCClassesMatch.emit(parts[1]) elif cmd == 'enumerate_objc_classes_complete': self.onEnumerateObjCClassesComplete.emit() elif cmd == 'enumerate_objc_methods_start': self.onEnumerateObjCMethodsStart.emit() elif cmd == 'enumerate_objc_methods_match': self.onEnumerateObjCMethodsMatch.emit(parts[1]) elif cmd == 'enumerate_objc_methods_complete': self.onEnumerateObjCMethodsComplete.emit() elif cmd == 'ftrace': if self.app.get_ftrace_panel() is not None: self.app.get_ftrace_panel().append_data(parts[1]) elif cmd == 'enable_kernel': self._app_window.get_menu().enable_kernel_menu() elif cmd == 'breakpoint_java_callback': b = Breakpoint(BREAKPOINT_JAVA) b.set_target(parts[1]) if len(parts) > 2: b.set_condition(parts[2]) self.java_breakpoints[parts[1]] = b self.onAddJavaBreakpoint.emit(b) elif cmd == 'breakpoint_objc_callback': b = Breakpoint(BREAKPOINT_OBJC) # WORKAROUND: Some ObjC Methods have multiple ':' in name. Restoring ':::': target = ":::".join(parts[1:-1]) b.set_target(target) if parts[-1] != '': b.set_condition(parts[-1]) self.objc_breakpoints[target] = b self.onAddObjCBreakpoint.emit(b) elif cmd == 'java_class_initialization_callback': b = Breakpoint(BREAKPOINT_INITIALIZATION) b.set_target(parts[1]) b.set_debug_symbol(parts[1]) self.java_class_initialization_breakpoints[parts[1]] = b self.onAddJavaClassInitializationBreakpoint.emit(b) elif cmd == 'breakpoint_native_callback': b = Breakpoint(BREAKPOINT_NATIVE) b.set_target(int(parts[1], 16)) if len(parts) > 2: b.set_condition(parts[2]) self.breakpoints[b.get_target()] = b self.onAddNativeBreakpoint.emit(b) elif cmd == 'module_initialization_callback': b = Breakpoint(BREAKPOINT_INITIALIZATION) b.set_target(parts[1]) self.module_initialization_breakpoints[parts[1]] = b self.onAddModuleInitializationBreakpoint.emit(b) elif cmd == 'breakpoint_deleted': if parts[1] == 'java': self.java_breakpoints.pop(parts[2]) elif parts[1] == 'objc': self.objc_breakpoints.pop(":::".join(parts[2:])) elif parts[1] == 'module_initialization': if parts[2] in self.module_initialization_breakpoints: self.module_initialization_breakpoints.pop(parts[2]) elif parts[1] == 'java_class_initialization': if parts[2] in self.java_class_initialization_breakpoints: self.java_class_initialization_breakpoints.pop(parts[2]) else: self.breakpoints.pop(utils.parse_ptr(parts[2])) self.onDeleteBreakpoint.emit(parts) elif cmd == 'breakpoint_java_class_initialization_callback': str_fmt = ('Breakpoint java class initialization {0} @thread := {1}'.format(parts[1], parts[2])) self.log_event(str_fmt) self.onHitJavaClassInitializationBreakpoint.emit(parts[1]) elif cmd == 'java_trace': self.onJavaTraceEvent.emit(parts) elif cmd == 'log': self.log(parts[1]) elif cmd == 'breakpoint_module_initialization_callback': data = json.loads(parts[2]) str_fmt = ('Breakpoint module initialization {0} @thread := {1}'.format(data['module'], parts[1])) self.log_event(str_fmt) self.onHitModuleInitializationBreakpoint.emit([parts[1], data]) elif cmd == 'module_initialized': module = json.loads(parts[2]) if module is not None: str_fmt = ('@thread {0} loading module := {1}'.format(parts[1], module['name'])) self.log_event(str_fmt) module_info = ModuleInfo.build_module_info_with_data(module) self.database.put_module_info(module_info.base, module_info) self.onModuleLoaded.emit([module]) elif cmd == 'new_thread': str_fmt = ('@thread {0} starting new thread with target fn := {1}'.format(parts[1], parts[2])) self.log_event(str_fmt) elif cmd == 'release': reason = 0 if len(parts) > 1: reason = int(parts[2]) p = 'releasing' if reason is not 3 else 'stepping' str_fmt = (p + ' := {0}'.format(parts[1])) self.log_event(str_fmt) if parts[1] in self.contexts: del self.contexts[parts[1]] self.onThreadResumed.emit(int(parts[1])) elif cmd == 'resume': if not self.resumed: self.resume_proc() elif cmd == 'release_js': # releasing the thread must be done by calling py funct dwarf_api('release') # there are cases in which we want to release the thread from a js api so we need to call this self.onRequestJsThreadResume.emit(int(parts[1])) elif cmd == 'set_context': #data = json.loads(parts[1]) # WORKAROUND: Some ObjC Methods have multiple ':' in name. Restoring ':::' data = json.loads(":::".join(parts[1:])) if 'modules' in data: self.onSetModules.emit(data['modules']) if 'ranges' in data: self.onSetRanges.emit(data['ranges']) if 'backtrace' in data: self.onBackTrace.emit(data['backtrace']) self.onApplyContext.emit(data) elif cmd == 'set_context_value': context_property = parts[1] value = parts[2] self.onContextChanged.emit(str(context_property), value) elif cmd == 'set_data': if data is not None: self.onSetData.emit(['raw', parts[1], data]) else: self.onSetData.emit(['plain', parts[1], str(parts[2])]) elif cmd == 'unhandled_exception': # todo pass elif cmd == 'update_modules': modules = json.loads(parts[2]) self.onSetModules.emit(modules) elif cmd == 'update_ranges': self.onSetRanges.emit(json.loads(parts[2])) elif cmd == 'update_searchable_ranges': self.onSearchableRanges.emit(json.loads(parts[2])) elif cmd == 'watchpoint': exception = json.loads(parts[1]) self.log_event('watchpoint hit op %s address %s @thread := %s' % (exception['memory']['operation'], exception['memory']['address'], parts[2])) elif cmd == 'watchpoint_added': ptr = utils.parse_ptr(parts[1]) hex_ptr = hex(ptr) flags = int(parts[2]) w = Watchpoint(ptr, flags) w.set_debug_symbol(json.loads(parts[3])) self.watchpoints[hex_ptr] = w self.onWatchpointAdded.emit(w) elif cmd == 'watchpoint_removed': hex_ptr = hex(utils.parse_ptr(parts[1])) self.watchpoints.pop(hex_ptr) self.onWatchpointRemoved.emit(hex_ptr) elif cmd == 'memoryscan_result': if parts[1] == '': self.onMemoryScanResult.emit([]) else: self.onMemoryScanResult.emit(json.loads(parts[1]))
def _on_message(self, message, data): QApplication.processEvents() if 'payload' not in message: print('payload: ' + str(message)) return self.onReceiveCmd.emit([message, data]) what = message['payload'] parts = what.split(':::') if len(parts) < 2: return cmd = parts[0] if cmd == 'api_ping_timeout': self._script.post({"type": str(parts[1])}) elif cmd == 'backtrace': self.onBackTrace.emit(json.loads(parts[1])) elif cmd == 'class_loader_loading_class': str_fmt = ('@thread {0} loading class := {1}'.format( parts[1], parts[2])) self.log_event(str_fmt) elif cmd == 'enumerate_java_classes_start': self.onEnumerateJavaClassesStart.emit() elif cmd == 'enumerate_java_classes_match': self.onEnumerateJavaClassesMatch.emit(parts[1]) elif cmd == 'enumerate_java_classes_complete': self.onEnumerateJavaClassesComplete.emit() elif cmd == 'enumerate_java_methods_complete': self.onEnumerateJavaMethodsComplete.emit( [parts[1], json.loads(parts[2])]) elif cmd == 'ftrace': if self.app.get_ftrace_panel() is not None: self.app.get_ftrace_panel().append_data(parts[1]) elif cmd == 'enable_kernel': self._app_window.get_menu().enable_kernel_menu() elif cmd == 'hook_java_callback': h = Hook(HOOK_JAVA) h.set_ptr(1) h.set_input(parts[1]) if self.java_pending_args: h.set_condition(self.java_pending_args['condition']) h.set_logic(self.java_pending_args['logic']) self.java_pending_args = None self.java_hooks[h.get_input()] = h self.onAddJavaHook.emit(h) elif cmd == 'hook_java_on_load_callback': h = Hook(HOOK_JAVA) h.set_ptr(0) h.set_input(parts[1]) self.java_on_loads[parts[1]] = h self.onAddJavaOnLoadHook.emit(h) elif cmd == 'hook_native_callback': h = Hook(HOOK_NATIVE) h.set_ptr(int(parts[1], 16)) h.set_input(self.temporary_input) h.set_bytes(binascii.unhexlify(parts[2])) self.temporary_input = '' h.set_condition(parts[4]) h.set_logic(parts[3]) h.internalHook = parts[5] == 'true' h.set_debug_symbol(json.loads(parts[6])) self.native_pending_args = None if not h.internal_hook: self.hooks[h.get_ptr()] = h self.onAddNativeHook.emit(h) elif cmd == 'hook_native_on_load_callback': h = Hook(HOOK_ONLOAD) h.set_ptr(0) h.set_input(parts[1]) self.native_on_loads[parts[1]] = h self.onAddNativeOnLoadHook.emit(h) elif cmd == 'hook_deleted': if parts[1] == 'java': self.java_hooks.pop(parts[2]) elif parts[1] == 'native_on_load': self.native_on_loads.pop(parts[2]) elif parts[1] == 'java_on_load': self.java_on_loads.pop(parts[2]) else: self.hooks.pop(utils.parse_ptr(parts[2])) self.onDeleteHook.emit(parts) elif cmd == 'java_on_load_callback': str_fmt = ('Hook java onload {0} @thread := {1}'.format( parts[1], parts[2])) self.log_event(str_fmt) self.onHitJavaOnLoad.emit(parts[1]) elif cmd == 'java_trace': self.onJavaTraceEvent.emit(parts) elif cmd == 'log': self.log(parts[1]) elif cmd == 'native_on_load_callback': data = json.loads(parts[2]) str_fmt = ('Hook native onload {0} @thread := {1}'.format( data['module'], parts[1])) self.log_event(str_fmt) self.onHitNativeOnLoad.emit([parts[1], data]) elif cmd == 'native_on_load_module_loading': module = json.loads(parts[2]) if module is not None: str_fmt = ('@thread {0} loading module := {1}'.format( parts[1], module['name'])) self.log_event(str_fmt) module_info = ModuleInfo.build_module_info_with_data(module) self.database.put_module_info(module_info.base, module_info) self.onModuleLoaded.emit([module]) elif cmd == 'new_thread': str_fmt = ( '@thread {0} starting new thread with target fn := {1}'.format( parts[1], parts[2])) self.log_event(str_fmt) elif cmd == 'release': reason = 0 if len(parts) > 1: reason = int(parts[2]) p = 'releasing' if reason is not 3 else 'stepping' str_fmt = (p + ' := {0}'.format(parts[1])) self.log_event(str_fmt) if parts[1] in self.contexts: del self.contexts[parts[1]] self.onThreadResumed.emit(int(parts[1])) elif cmd == 'resume': if not self.resumed: self.resume_proc() elif cmd == 'release_js': # releasing the thread must be done by calling py funct dwarf_api('release') # there are cases in which we want to release the thread from a js api so we need to call this self.onRequestJsThreadResume.emit(int(parts[1])) elif cmd == 'set_context': data = json.loads(parts[1]) if 'modules' in data: self.onSetModules.emit(data['modules']) if 'ranges' in data: self.onSetRanges.emit(data['ranges']) if 'backtrace' in data: self.onBackTrace.emit(data['backtrace']) self.onApplyContext.emit(data) elif cmd == 'set_context_value': context_property = parts[1] value = parts[2] self.onContextChanged.emit(str(context_property), value) elif cmd == 'set_data': import capstone if data is not None: self.onSetData.emit(['raw', parts[1], data]) else: self.onSetData.emit(['plain', parts[1], str(parts[2])]) elif cmd == 'unhandled_exception': # todo pass elif cmd == 'update_modules': modules = json.loads(parts[2]) # todo update onloads bases self.onSetModules.emit(modules) elif cmd == 'update_ranges': self.onSetRanges.emit(json.loads(parts[2])) elif cmd == 'update_searchable_ranges': self.onSearchableRanges.emit(json.loads(parts[2])) elif cmd == 'watcher': exception = json.loads(parts[1]) self.log_event('watcher hit op %s address %s @thread := %s' % (exception['memory']['operation'], exception['memory']['address'], parts[2])) elif cmd == 'watcher_added': ptr = utils.parse_ptr(parts[1]) hex_ptr = hex(ptr) flags = int(parts[2]) h = Hook(HOOK_WATCHER) h.set_ptr(ptr) h.set_logic(flags) h.set_debug_symbol(json.loads(parts[3])) self.watchers[hex_ptr] = h self.onWatcherAdded.emit(hex_ptr, flags) elif cmd == 'watcher_removed': hex_ptr = hex(utils.parse_ptr(parts[1])) self.watchers.pop(hex_ptr) self.onWatcherRemoved.emit(hex_ptr) elif cmd == 'memoryscan_result': if parts[1] == '': self.onMemoryScanResult.emit([]) else: self.onMemoryScanResult.emit(json.loads(parts[1]))