def _on_message(self, message, data): QApplication.processEvents() if 'payload' not in message: print('payload: ' + str(message)) return what = message['payload'] parts = what.split(':::') if len(parts) < 2: print(what) return cmd = parts[0] if 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(str_fmt) elif cmd == 'emulator': self.onEmulator.emit(parts[1:]) 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.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.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.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' self.native_pending_args = None if not h.internalHook: self.hooks[h.get_ptr()] = h self.onAddNativeHook.emit(h) elif cmd == 'hook_native_on_load_callback': h = Hook(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(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': str_fmt = ('Hook native onload {0} @thread := {1}'.format( parts[1], parts[3])) self.log(str_fmt) self.onHitNativeOnLoad.emit([parts[1], parts[2]]) elif cmd == 'native_on_load_module_loading': str_fmt = ('@thread {0} loading module := {1}'.format( parts[1], parts[2])) self.log(str_fmt) elif cmd == 'release': 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': if data: self.onSetData.emit(['raw', parts[1], data]) else: self.onSetData.emit(['plain', parts[1], str(parts[2])]) elif cmd == 'tracer': self.onTraceData.emit(parts[1]) 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 == 'watcher': exception = json.loads(parts[1]) self.log('watcher hit op %s address %s @thread := %s' % (exception['memory']['operation'], exception['memory']['address'], parts[2])) elif cmd == 'watcher_added': self._watchers.append(utils.parse_ptr(parts[1])) self.onWatcherAdded.emit(parts[1], int(parts[2])) elif cmd == 'watcher_removed': self._watchers.remove(utils.parse_ptr(parts[1])) self.onWatcherRemoved.emit(parts[1]) elif cmd == 'memoryscan_result': if parts[1] == '': self.onMemoryScanResult.emit([]) else: self.onMemoryScanResult.emit(json.loads(parts[1])) else: print('unknown message: ' + what)
def _on_hook_removed(self, ptr): ptr = utils.parse_ptr(ptr) self.memory_panel.remove_highlight(ptr)
def is_address_watched(self, ptr): ptr = utils.parse_ptr(ptr) if ptr in self._watchers: return True return False
def _range_dblclicked(self, ptr): """ Range in RangesPanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.memory_panel.read_memory(ptr=ptr) self.show_main_tab('Memory')
def _on_modulefunc_dblclicked(self, ptr): """ Function in ModulePanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.memory_panel.read_memory(ptr=ptr) self.show_main_tab('Memory')
def emulate(self, until=0): if self.isRunning(): raise self.EmulatorAlreadyRunningError() if isinstance(until, str): try: until = int(until, 16) except ValueError: until = 0 if until and isinstance(until, int): self.end_ptr = utils.parse_ptr(until) if self.end_ptr == 0: # invalid end pointer raise self.EmulatorSetupFailedError('Invalid EndPtr') if self.context is None: err = self.setup() if err > 0: # make sure context is None if setup failed for any reason. we want a clean setup later self.context = None err_msg = 'unhandled error' if err == self.ERR_INVALID_TID: err_msg = 'invalid thread id' elif err == self.ERR_INVALID_CONTEXT: err_msg = 'invalid context' raise self.EmulatorSetupFailedError('Setup failed: %s' % err_msg) # calculate the start address address = self._current_instruction if address == 0: if self.uc._arch == unicorn.UC_ARCH_ARM: address = self.uc.reg_read(unicorn.arm_const.UC_ARM_REG_PC) elif self.uc._arch == unicorn.UC_ARCH_ARM64: address = self.uc.reg_read(unicorn.arm64_const.UC_ARM64_REG_PC) elif self.uc._arch == unicorn.UC_ARCH_X86 and self.uc._mode == unicorn.UC_MODE_32: address = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_EIP) elif self.uc._arch == unicorn.UC_ARCH_X86 and self.uc._mode == unicorn.UC_MODE_64: address = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_RIP) else: raise self.EmulatorSetupFailedError('Unsupported arch') if until > 0: self.log_to_ui('[*] start emulation from %s to %s' % (hex(address), hex(self.end_ptr))) else: self.log_to_ui('[*] stepping %s' % hex(address)) self.onEmulatorStart.emit() if self.thumb: address = address | 1 # invalidate prefs before start self.invalida_configurations() # load callbacks if needed if self.callbacks_path is not None and self.callbacks_path != '': try: spec = spec_from_loader( "callbacks", SourceFileLoader("callbacks", self.callbacks_path)) self.callbacks = module_from_spec(spec) spec.loader.exec_module(self.callbacks) except Exception as e: self.log_to_ui('[*] failed to load callbacks: %s' % str(e)) # reset callbacks path self._prefs.put(prefs.EMULATOR_CALLBACKS_PATH, '') self.callbacks_path = '' self.callbacks = None else: self.callbacks = None # until is 0 (i.e we are stepping) if until == 0: self.stepping = [True, False] # self.end_ptr = address + (self.dwarf.pointer_size * 2) stupid else: self.stepping = [False, False] self._start_address = address self._end_address = self.end_ptr self._setup_done = True self.start()
def set_base_address(self, address): self.base_address = utils.parse_ptr(address)
def _on_message(self, message, data): QApplication.processEvents() if 'payload' not in message: print('payload: ' + str(message)) return what = message['payload'] parts = what.split(':::') if len(parts) < 2: print(what) return cmd = parts[0] if cmd == 'backtrace': try: self._app_window.backtrace_panel.set_backtrace( json.loads(parts[1])) except: pass elif cmd == 'emulator': self.onEmulator.emit(parts[1:]) 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.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_native_callback': h = Hook(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]) self.native_pending_args = None self.hooks[h.get_ptr()] = h self.onAddNativeHook.emit(h) elif cmd == 'hook_onload_callback': h = Hook(Hook.HOOK_ONLOAD) h.set_ptr(0) h.set_input(parts[1]) self.on_loads[parts[1]] = h self.onAddOnLoadHook.emit(h) elif cmd == 'java_trace': self.onJavaTraceEvent.emit(parts) elif cmd == 'log': self.log(parts[1]) elif cmd == 'memory_scan_match': self.onMemoryScanMatch.emit( [parts[1], parts[2], json.loads(parts[3])]) elif cmd == 'memory_scan_complete': self._app_window.get_menu().on_bytes_search_complete() self.onMemoryScanComplete.emit([parts[1] + ' complete', 0, 0]) elif cmd == 'onload_callback': self.loading_library = parts[1] str_fmt = ('Hook onload {0} @thread := {1}'.format( parts[1], parts[3])) self.log(str_fmt) self.onHitOnLoad.emit([parts[1], parts[2]]) elif cmd == 'release': if parts[1] in self.contexts: del self.contexts[parts[1]] self.onThreadResumed.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']) self.onApplyContext.emit(data) elif cmd == 'set_data': if data: self.onSetData.emit(['raw', parts[1], data]) else: self.onSetData.emit(['plain', parts[1], str(parts[2])]) elif cmd == 'tracer': self.onTraceData.emit(parts[1]) 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 == 'watcher': exception = json.loads(parts[1]) self.log('watcher hit op %s address %s @thread := %s' % (exception['memory']['operation'], exception['memory']['address'], parts[2])) elif cmd == 'watcher_added': self._watchers.append(utils.parse_ptr(parts[1])) self.onWatcherAdded.emit(parts[1], int(parts[2])) elif cmd == 'watcher_removed': self._watchers.remove(utils.parse_ptr(parts[1])) self.onWatcherRemoved.emit(parts[1]) else: print('unknown message: ' + what)