Exemple #1
0
    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
Exemple #2
0
    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)
Exemple #3
0
    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
Exemple #4
0
    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
Exemple #5
0
    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]))
Exemple #6
0
    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]))