Esempio n. 1
0
    def build_left_column(self):
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)

        self.hooks_panel = HooksPanel(self)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self, 0, 3)
        splitter.addWidget(self.contexts_panel)

        self.vars_panel = VarsPanel(self)
        splitter.addWidget(self.vars_panel)

        return splitter
Esempio n. 2
0
    def build_right_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        from ui.panel_contexts import ContextsPanel
        self.contexts_panel = ContextsPanel(self.app)
        splitter.addWidget(self.contexts_panel)

        from ui.panel_backtrace import BacktracePanel
        self.backtrace_panel = BacktracePanel(self.app)
        splitter.addWidget(self.backtrace_panel)

        return splitter
Esempio n. 3
0
    def build_left_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        self.hooks_panel = HooksPanel(self.app)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self.app)
        splitter.addWidget(self.contexts_panel)

        self.backtrace_panel = BacktracePanel(self.app)
        splitter.addWidget(self.backtrace_panel)

        return splitter
Esempio n. 4
0
class SessionUi(QTabWidget):
    TAB_MODULES = 0
    TAB_RANGES = 1
    TAB_DATA = 2
    TAB_ASM = 3
    TAB_JAVA_CLASSES = 4

    def __init__(self, app, *__args):
        super().__init__(*__args)

        self.app = app

        self.setTabsClosable(True)
        self.setMovable(True)
        self.tabCloseRequested.connect(self.removeTab)
        self.setContentsMargins(2, 2, 2, 2)
        self.setStyleSheet("""
            QListWidget:hover,
            QTableWidget:hover {
                border: 1px solid transparent;
            }
            QTabWidget QFrame{
                border: 0;
            }
            
            QTabWidget::pane {
                border: 0px solid transparent;
                border-radius: 0px;
                padding: 0px;
                margin: 0px;
            }
            
            QTabWidget::pane:selected {
                background-color: transparent;
                border: 0px solid transparent;
            }
            
            QWidget {
                padding: 0;
                margin-top: 2px;
                margin-right: 2px;
                margin-left: 1px;
            }
        """)

        self.session_panel = QSplitter()

        self.modules_panel = None
        self.ranges_panel = None
        self.registers_panel = None
        self.memory_panel = None
        self.log_panel = None
        self.backtrace_panel = None
        self.hooks_panel = None
        self.contexts_panel = None

        self.session_panel.addWidget(self.build_left_column())
        self.session_panel.addWidget(self.build_central_content())

        self.session_panel.setHandleWidth(1)
        self.session_panel.setStretchFactor(0, 2)
        self.session_panel.setStretchFactor(1, 6)
        self.session_panel.setContentsMargins(0, 0, 0, 0)

        self.modules_panel = ModulesPanel(self.app)
        self.ranges_panel = RangesPanel(self.app)
        self.data_panel = DataPanel(self.app)
        self.asm_panel = AsmPanel(self.app)
        self.java_class_panel = None

        self.addTab(self.session_panel, 'session')
        bt = self.tabBar().tabButton(0, QTabBar.LeftSide)
        if not bt:
            bt = self.tabBar().tabButton(0, QTabBar.RightSide)
        if bt:
            bt.resize(0, 0)

    def add_main_tabs(self):
        self.add_dwarf_tab(SessionUi.TAB_MODULES)
        self.add_dwarf_tab(SessionUi.TAB_RANGES)

    def build_left_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        self.hooks_panel = HooksPanel(self.app)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self.app)
        splitter.addWidget(self.contexts_panel)

        self.backtrace_panel = BacktracePanel(self.app)
        splitter.addWidget(self.backtrace_panel)

        return splitter

    def build_central_content(self):
        main_panel = QSplitter(self)
        main_panel.setHandleWidth(1)
        main_panel.setOrientation(Qt.Vertical)
        main_panel.setContentsMargins(0, 0, 0, 0)

        self.registers_panel = RegistersPanel(self.app, 0, 0)
        main_panel.addWidget(self.registers_panel)

        self.memory_panel = MemoryPanel(self.app)
        main_panel.addWidget(self.memory_panel)

        self.log_panel = LogPanel(self.app)
        main_panel.addWidget(self.log_panel)

        main_panel.setStretchFactor(0, 1)
        main_panel.setStretchFactor(1, 3)
        main_panel.setStretchFactor(2, 1)
        return main_panel

    def on_script_loaded(self):
        self.add_main_tabs()

    def on_script_destroyed(self):
        for i in range(0, self.count()):
            if i > 0:
                self.removeTab(i)

        self.log_panel.clear()
        self.data_panel.clear()

        self.asm_panel.range = None

        self.hooks_panel.setRowCount(0)
        self.hooks_panel.setColumnCount(0)
        self.hooks_panel.resizeColumnsToContents()
        self.hooks_panel.horizontalHeader().setStretchLastSection(True)

        self.ranges_panel.setRowCount(0)
        self.ranges_panel.resizeColumnsToContents()
        self.ranges_panel.horizontalHeader().setStretchLastSection(True)

        self.modules_panel.setRowCount(0)
        self.modules_panel.resizeColumnsToContents()
        self.modules_panel.horizontalHeader().setStretchLastSection(True)

        self.contexts_panel.setRowCount(0)
        self.hooks_panel.setColumnCount(0)
        self.contexts_panel.resizeColumnsToContents()
        self.contexts_panel.horizontalHeader().setStretchLastSection(True)

        self.backtrace_panel.setRowCount(0)
        self.hooks_panel.setColumnCount(0)
        self.backtrace_panel.resizeColumnsToContents()
        self.backtrace_panel.horizontalHeader().setStretchLastSection(True)

        self.registers_panel.setRowCount(0)
        self.hooks_panel.setColumnCount(0)
        self.registers_panel.resizeColumnsToContents()
        self.registers_panel.horizontalHeader().setStretchLastSection(True)

        self.memory_panel.on_script_destroyed()

        self.java_class_panel = None

    def close_tab(self, index):
        self.removeTab(index)

    def add_dwarf_tab(self, tab_id, request_focus=False):
        if tab_id == SessionUi.TAB_DATA:
            self.addTab(self.data_panel, 'data')
            if request_focus:
                self.setCurrentWidget(self.hooks_panel)
        elif tab_id == SessionUi.TAB_MODULES:
            self.addTab(self.modules_panel, 'modules')
            if request_focus:
                self.setCurrentWidget(self.modules_panel)
        elif tab_id == SessionUi.TAB_RANGES:
            self.addTab(self.ranges_panel, 'ranges')
            if request_focus:
                self.setCurrentWidget(self.ranges_panel)
        elif tab_id == SessionUi.TAB_ASM:
            self.addTab(self.asm_panel, 'asm')
            if request_focus:
                self.setCurrentWidget(self.asm_panel)
        elif tab_id == SessionUi.TAB_JAVA_CLASSES:
            if self.java_class_panel is None:
                self.java_class_panel = JavaClassesPanel(self.app)
            if self.java_class_panel.parent() is None:
                self.addTab(self.java_class_panel, 'Java Classes')
            if request_focus:
                self.setCurrentWidget(self.java_class_panel)

    def add_tab(self, tab_widget, tab_label):
        self.addTab(tab_widget, tab_label)
        self.setCurrentWidget(tab_widget)

    def disasm(self, ptr=0, _range=None):
        self.add_dwarf_tab(SessionUi.TAB_ASM, True)
        if _range:
            self.asm_panel.disasm(_range=_range)
        else:
            self.asm_panel.read_memory(ptr)

    def request_session_ui_focus(self):
        self.setCurrentWidget(self.session_panel)
Esempio n. 5
0
class SessionUi(QTabWidget):
    TAB_MODULES = 'modules'
    TAB_RANGES = 'ranges'
    TAB_DATA = 'data'
    TAB_ASM = 'asm'
    TAB_JAVA_CLASSES = 'java'
    TAB_TRACE = 'trace'
    TAB_FTRACE = 'ftrace'

    def __init__(self, app, *__args):
        super().__init__(*__args)

        self.app = app

        self.setTabsClosable(True)
        self.setMovable(True)
        self.tabCloseRequested.connect(self.close_tab)
        self.setContentsMargins(2, 2, 2, 2)
        self.setStyleSheet("""
            QListWidget:hover,
            QTableWidget:hover {
                border: 1px solid transparent;
            }
            QTabWidget QFrame{
                border: 0;
            }
            
            QTabWidget::pane {
                border: 0px solid transparent;
                border-radius: 0px;
                padding: 0px;
                margin: 0px;
            }
            
            QTabWidget::pane:selected {
                background-color: transparent;
                border: 0px solid transparent;
            }
            
            QWidget {
                padding: 0;
                margin-top: 2px;
                margin-right: 2px;
                margin-left: 1px;
            }
        """)

        self.session_panel = QSplitter()

        self.asm_panel = None
        self.backtrace_panel = None
        self.contexts_panel = None
        self.data_panel = None
        self.ftrace_panel = None
        self.hooks_panel = None
        self.java_class_panel = None
        self.java_explorer_panel = None
        self.log_panel = None
        self.memory_panel = None
        self.modules_panel = None
        self.ranges_panel = None
        self.registers_panel = None
        self.trace_panel = None
        self.watchers_panel = None

        self.session_panel.addWidget(self.build_left_column())
        self.session_panel.addWidget(self.build_central_content())
        self.session_panel.addWidget(self.build_right_column())

        self.session_panel.setHandleWidth(1)
        self.session_panel.setStretchFactor(0, 2)
        self.session_panel.setStretchFactor(1, 6)
        self.session_panel.setStretchFactor(2, 2)
        self.session_panel.setContentsMargins(0, 0, 0, 0)

        self.addTab(self.session_panel, 'session')
        bt = self.tabBar().tabButton(0, QTabBar.LeftSide)
        if not bt:
            bt = self.tabBar().tabButton(0, QTabBar.RightSide)
        if bt:
            bt.resize(0, 0)
        self.add_main_tabs()

    def add_main_tabs(self):
        self.add_dwarf_tab(SessionUi.TAB_MODULES)
        self.add_dwarf_tab(SessionUi.TAB_RANGES)

    def build_left_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        from ui.panel_hooks import HooksPanel
        self.hooks_panel = HooksPanel(self.app)
        splitter.addWidget(self.hooks_panel)

        from ui.panel_watchers import WatchersPanel
        self.watchers_panel = WatchersPanel(self.app)
        splitter.addWidget(self.watchers_panel)

        return splitter

    def build_central_content(self):
        main_panel = QSplitter(self)
        main_panel.setHandleWidth(1)
        main_panel.setOrientation(Qt.Vertical)
        main_panel.setContentsMargins(0, 0, 0, 0)

        from ui.panel_registers import RegistersPanel
        self.registers_panel = RegistersPanel(self.app, 0, 0)
        main_panel.addWidget(self.registers_panel)

        box = QVBoxLayout()
        box.setContentsMargins(0, 0, 0, 0)
        from ui.panel_memory import MemoryPanel
        self.memory_panel = MemoryPanel(self.app)
        box.addWidget(self.memory_panel)

        from ui.panel_java_explorer import JavaExplorerPanel
        self.java_explorer_panel = JavaExplorerPanel(self.app)
        self.java_explorer_panel.hide()
        box.addWidget(self.java_explorer_panel)

        q = QWidget()
        q.setLayout(box)
        main_panel.addWidget(q)

        from ui.panel_log import LogPanel
        self.log_panel = LogPanel(self.app)
        main_panel.addWidget(self.log_panel)

        main_panel.setStretchFactor(0, 1)
        main_panel.setStretchFactor(1, 3)
        main_panel.setStretchFactor(2, 1)
        return main_panel

    def build_right_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        from ui.panel_contexts import ContextsPanel
        self.contexts_panel = ContextsPanel(self.app)
        splitter.addWidget(self.contexts_panel)

        from ui.panel_backtrace import BacktracePanel
        self.backtrace_panel = BacktracePanel(self.app)
        splitter.addWidget(self.backtrace_panel)

        return splitter

    def on_script_loaded(self):
        pass

    def on_script_destroyed(self):
        for i in range(0, self.count()):
            if i > 0:
                self.removeTab(i)

        self.contexts_panel.clear()
        self.log_panel.clear()
        if self.data_panel is not None:
            self.data_panel.clear()
        if self.watchers_panel is not None:
            self.watchers_panel.clear()

        if self.asm_panel is not None:
            self.asm_panel.clear()

        self.hooks_panel.setRowCount(0)
        self.hooks_panel.setColumnCount(0)

        if self.ranges_panel is not None:
            self.ranges_panel.setRowCount(0)

        if self.modules_panel is not None:
            self.modules_panel.setRowCount(0)

        self.backtrace_panel.setRowCount(0)
        self.backtrace_panel.setColumnCount(0)

        self.registers_panel.setRowCount(0)
        self.registers_panel.setColumnCount(0)

        self.memory_panel.on_script_destroyed()

        self.java_class_panel = None
        self.trace_panel = None
        self.ftrace_panel = None

    def close_tab(self, index):
        w = self.widget(index)

        try:
            w.on_tab_closed()
        except:
            pass

        # invalidate the object in the current session
        # this is the fastest way i can think to achieve this
        v = vars(self)
        for obj in v:
            if v[obj] is not None and v[obj] == w:
                try:
                    v[obj].clear()
                except:
                    pass
                v[obj] = None
        self.removeTab(index)

    def add_dwarf_tab(self, tab_id, request_focus=False):
        if tab_id == SessionUi.TAB_DATA:
            if self.data_panel is None:
                from ui.panel_data import DataPanel
                self.data_panel = DataPanel(self.app)
            self.addTab(self.data_panel, 'data')
            if request_focus:
                self.setCurrentWidget(self.data_panel)
            return self.hooks_panel
        elif tab_id == SessionUi.TAB_MODULES:
            if self.modules_panel is None:
                from ui.panel_modules import ModulesPanel
                self.modules_panel = ModulesPanel(self.app)
            self.addTab(self.modules_panel, 'modules')
            if request_focus:
                self.setCurrentWidget(self.modules_panel)
            return self.modules_panel
        elif tab_id == SessionUi.TAB_RANGES:
            if self.ranges_panel is None:
                from ui.panel_ranges import RangesPanel
                self.ranges_panel = RangesPanel(self.app)
            self.addTab(self.ranges_panel, 'ranges')
            if request_focus:
                self.setCurrentWidget(self.ranges_panel)
            return self.ranges_panel
        elif tab_id == SessionUi.TAB_ASM:
            if self.asm_panel is None:
                from ui.panel_asm import AsmPanel
                self.asm_panel = AsmPanel(self.app)
            self.addTab(self.asm_panel, 'asm')
            if request_focus:
                self.setCurrentWidget(self.asm_panel)
            return self.asm_panel
        elif tab_id == SessionUi.TAB_JAVA_CLASSES:
            if self.java_class_panel is None:
                from ui.panel_java_classes import JavaClassesPanel
                self.java_class_panel = JavaClassesPanel(self.app)
            if self.java_class_panel.parent() is None:
                self.addTab(self.java_class_panel, 'Java Classes')
            if request_focus:
                self.setCurrentWidget(self.java_class_panel)
            return self.java_class_panel
        elif tab_id == SessionUi.TAB_TRACE:
            if self.trace_panel is None:
                from ui.panel_trace import TracePanel
                self.trace_panel = TracePanel(self.app)
            if self.trace_panel.parent() is None:
                self.addTab(self.trace_panel, 'Trace')
            if request_focus:
                self.setCurrentWidget(self.trace_panel)
            return self.trace_panel
        elif tab_id == SessionUi.TAB_FTRACE:
            if self.ftrace_panel is None:
                from ui.panel_ftrace import FTracePanel
                self.ftrace_panel = FTracePanel(self.app)
            if self.ftrace_panel.parent() is None:
                self.addTab(self.ftrace_panel, 'ftrace')
            if request_focus:
                self.setCurrentWidget(self.ftrace_panel)
            return self.trace_panel

    def add_tab(self, tab_widget, tab_label):
        self.addTab(tab_widget, tab_label)
        self.setCurrentWidget(tab_widget)

    def disasm(self, ptr=0, _range=None):
        self.add_dwarf_tab(SessionUi.TAB_ASM, True)
        if _range:
            self.asm_panel.disasm(_range=_range)
        else:
            self.asm_panel.read_memory(ptr)

    def request_session_ui_focus(self):
        self.setCurrentWidget(self.session_panel)

    def show_java_panel(self):
        self.memory_panel.hide()
        self.java_explorer_panel.show()

    def show_memory_panel(self):
        self.java_explorer_panel.hide()
        self.memory_panel.show()
Esempio n. 6
0
class App(QWidget):
    def __init__(self, qtapp, flags=None, *args, **kwargs):
        super().__init__(flags, *args, **kwargs)

        self.qtapp = qtapp

        self.script = None
        self.arch = ''
        self.pointer_size = 0

        self.modules_panel = None
        self.ranges_panel = None
        self.main_panel = None
        self.hooks_panel = None
        self.contexts_panel = None
        self.vars_panel = None

        self.loading_library = False

        self.contexts = []

        box = QVBoxLayout()

        main_splitter = Layout(self)
        main_splitter.addWidget(self.build_left_column())
        main_splitter.addWidget(self.build_central_content())
        main_splitter.setStretchFactor(0, 2)
        main_splitter.setStretchFactor(1, 5)

        box.addWidget(main_splitter)
        self.setLayout(box)

    def build_left_column(self):
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)

        self.hooks_panel = HooksPanel(self)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self, 0, 3)
        splitter.addWidget(self.contexts_panel)

        self.vars_panel = VarsPanel(self)
        splitter.addWidget(self.vars_panel)

        return splitter

    def build_central_content(self):
        q = QWidget()
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        splitter = QSplitter()

        self.main_panel = MainPanel(self)
        splitter.addWidget(self.main_panel)

        right_splitter = QSplitter()
        right_splitter.setOrientation(Qt.Vertical)

        self.modules_panel = ModulesPanel(self, 0, 3)
        right_splitter.addWidget(self.modules_panel)

        self.ranges_panel = RangesPanel(self, 0, 4)
        right_splitter.addWidget(self.ranges_panel)

        splitter.addWidget(right_splitter)

        splitter.setStretchFactor(0, 6)
        splitter.setStretchFactor(1, 2)

        layout.addWidget(splitter)

        bq = QWidget()
        buttons = QHBoxLayout()
        buttons.setContentsMargins(0, 0, 0, 0)

        bt = QPushButton('release')
        bt.clicked.connect(self.release_target)
        buttons.addWidget(bt)

        bt = QPushButton('restart')
        bt.clicked.connect(self.restart_target)
        buttons.addWidget(bt)

        buttons.addWidget(QPushButton('tools'))
        buttons.addWidget(QPushButton('options'))

        bq.setLayout(buttons)
        bq.setMaximumHeight(50)
        bq.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(bq)

        q.setLayout(layout)
        q.setContentsMargins(0, 0, 0, 0)

        return q

    def set_modules(self, modules):
        self.modules_panel.set_modules(modules)

    def set_ranges(self, ranges):
        self.ranges_panel.set_ranges(ranges)

    def initialize_with_script(self, script):
        self.script = script
        self.script.on('message', self.on_message)
        self.script.on('destroyed', self.on_destroyed)
        self.showMaximized()

    def on_message(self, message, data):
        if 'payload' not in message:
            print(message)
            return

        what = message['payload']
        parts = what.split(':::')
        if len(parts) < 2:
            print(what)
            return

        if parts[0] == '0':
            self.main_panel.add_to_main_content_content(parts[1], scroll=True)
        elif parts[0] == '1':
            data = json.loads(parts[1])
            self.contexts.append(data)

            if len(data['context']) > 0:
                self.hooks_panel.increment_hook_count(int(data['context']['pc'], 16))
                if 'moduleName' in data['symbol']:
                    sym = '%s - %s' % (data['symbol']['moduleName'], data['symbol']['name'])
                else:
                    sym = self.hooks_panel.get_hooks()[int(data['context']['pc'], 16)]['input']
                self.contexts_panel.add_context(data, library_onload=self.loading_library)
                if self.loading_library is None:
                    self.main_panel.add_to_main_content_content('hook %s (%s) @thread := %d' % (
                        data['context']['pc'], sym, data['tid']), scroll=True)
                if len(self.contexts) > 1:
                    return
            else:
                self.arch = data['arch']
                if self.get_arch() == 'arm':
                    self.pointer_size = 4
                else:
                    self.pointer_size = 8
                self.main_panel.add_to_main_content_content('injected into := ' + str(data['pid']))

            self.apply_context(data)
            if self.loading_library is not None:
               self.loading_library = None
        elif parts[0] == '2':
            print(parts)
            self.loading_library = parts[1]
            self.main_panel.add_to_main_content_content('hook onload %s @thread := %s' % (
                parts[1], parts[3]), scroll=True)
            self.hooks_panel.hit_onload(parts[1], parts[2])
        else:
            print(what)

    def get_arch(self):
        return self.arch

    def get_script(self):
        return self.script

    def get_memory_panel(self):
        return self.main_panel.get_memory_panel()

    def get_pointer_size(self):
        return self.pointer_size

    def release_target(self, tid=0):
        if tid > 0:
            self.get_script().exports.release(tid)
        else:
            self.contexts_panel.setRowCount(0)
            self.contexts.clear()
            self.main_panel.release_target()

            self.get_script().exports.release()

    def restart_target(self):
        self.script.exports.restart()
        self.release_target()
        self.hooks_panel.reset_hook_count()
        self.contexts_panel.setRowCount(0)

    def _apply_context(self, context):
        if 'modules' in context:
            self.set_modules(context['modules'])
        if 'ranges' in context:
            self.set_ranges(context['ranges'])
        if 'context' in context:
            self.main_panel.set_context(context['context'])

    def apply_context(self, context):
        threading.Thread(target=self._apply_context, args=(context,)).start()

    def on_destroyed(self):
        print('[*] script destroyed')
        self.qtapp.exit()
Esempio n. 7
0
class App(QWidget):
    def __init__(self, app_window, flags=None, *args, **kwargs):
        super().__init__(flags, *args, **kwargs)

        self.app_window = app_window
        self.arch = ''
        self.pointer_size = 0

        self.modules_panel = None
        self.ranges_panel = None
        self.registers_panel = None
        self.memory_panel = None
        self.log_panel = None
        self.backtrace_panel = None
        self.hooks_panel = None
        self.contexts_panel = None

        self.contexts = []

    def setup_ui(self):
        box = QVBoxLayout()

        main_splitter = QSplitter(self)
        main_splitter.addWidget(self.build_left_column())
        main_splitter.addWidget(self.build_central_content())
        main_splitter.setStretchFactor(0, 3)
        main_splitter.setStretchFactor(1, 6)

        box.addWidget(main_splitter)
        self.setLayout(box)

    def build_left_column(self):
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)

        self.hooks_panel = HooksPanel(self)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self, 0, 3)
        splitter.addWidget(self.contexts_panel)

        self.backtrace_panel = BacktracePanel()
        splitter.addWidget(self.backtrace_panel)

        return splitter

    def build_central_content(self):
        q = QWidget()
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        splitter = QSplitter()

        main_panel = QSplitter(self)
        main_panel.setOrientation(Qt.Vertical)

        self.registers_panel = RegistersPanel(self, 0, 4)
        main_panel.addWidget(self.registers_panel)

        self.memory_panel = MemoryPanel(self)
        main_panel.addWidget(self.memory_panel)

        self.log_panel = LogPanel(self)
        main_panel.addWidget(self.log_panel)

        main_panel.setStretchFactor(0, 1)
        main_panel.setStretchFactor(1, 3)
        main_panel.setStretchFactor(2, 1)
        splitter.addWidget(main_panel)

        right_splitter = QSplitter()
        right_splitter.setOrientation(Qt.Vertical)

        self.modules_panel = ModulesPanel(self, 0, 3)
        right_splitter.addWidget(self.modules_panel)

        self.ranges_panel = RangesPanel(self, 0, 4)
        right_splitter.addWidget(self.ranges_panel)

        splitter.addWidget(right_splitter)

        splitter.setStretchFactor(0, 5)
        splitter.setStretchFactor(1, 2)

        layout.addWidget(splitter)

        q.setLayout(layout)
        q.setContentsMargins(0, 0, 0, 0)

        return q

    def restart(self):
        self.get_script().exports.restart()
        self.resume()
        self.get_hooks_panel().reset_hook_count()
        self.get_contexts_panel().setRowCount(0)

    def resume(self):
        self.contexts_panel.setRowCount(0)
        self.contexts.clear()
        self.registers_panel.setRowCount(0)
        self.backtrace_panel.setRowCount(0)
        self.get_script().exports.release()

    def set_modules(self, modules):
        self.modules_panel.set_modules(modules)

    def set_ranges(self, ranges):
        self.ranges_panel.set_ranges(ranges)

    def _apply_context(self, context):
        if 'modules' in context:
            self.set_modules(context['modules'])
        if 'ranges' in context:
            self.set_ranges(context['ranges'])
        if 'context' in context:
            self.registers_panel.set_context(context['ptr'],
                                             context['is_java'],
                                             context['context'])
        if 'backtrace' in context:
            self.backtrace_panel.set_backtrace(context['backtrace'])

    def apply_context(self, context):
        threading.Thread(target=self._apply_context, args=(context, )).start()

    def get_arch(self):
        return self.arch

    def get_contexts(self):
        return self.contexts

    def get_contexts_panel(self):
        return self.contexts_panel

    def get_dwarf(self):
        return self.app_window.get_dwarf()

    def get_hooks_panel(self):
        return self.hooks_panel

    def get_log_panel(self):
        return self.log_panel

    def get_memory_panel(self):
        return self.memory_panel

    def get_pointer_size(self):
        return self.pointer_size

    def get_registers_panel(self):
        return self.registers_panel

    def get_script(self):
        return self.app_window.get_dwarf().get_script()