Beispiel #1
0
    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)
Beispiel #2
0
 def _on_hook_removed(self, ptr):
     ptr = utils.parse_ptr(ptr)
     self.memory_panel.remove_highlight(ptr)
Beispiel #3
0
    def is_address_watched(self, ptr):
        ptr = utils.parse_ptr(ptr)
        if ptr in self._watchers:
            return True

        return False
Beispiel #4
0
 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')
Beispiel #5
0
 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')
Beispiel #6
0
    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()
Beispiel #7
0
 def set_base_address(self, address):
     self.base_address = utils.parse_ptr(address)
Beispiel #8
0
    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)