Ejemplo n.º 1
0
class JavaTracePanel(QWidget):
    def __init__(self, app, *__args):
        super().__init__(app)
        self.app = app

        self.app.dwarf.onJavaTraceEvent.connect(self.on_event)
        self.app.dwarf.onEnumerateJavaClassesStart.connect(
            self.on_enumeration_start)
        self.app.dwarf.onEnumerateJavaClassesMatch.connect(
            self.on_enumeration_match)
        self.app.dwarf.onEnumerateJavaClassesComplete.connect(
            self.on_enumeration_complete)

        self.tracing = False
        self.trace_classes = []
        self.trace_depth = 0

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        self._record_icon = QIcon(
            utils.resource_path('assets/icons/record.png'))
        self._pause_icon = QIcon(utils.resource_path('assets/icons/pause.png'))
        self._stop_icon = QIcon(utils.resource_path('assets/icons/stop.png'))

        self._tool_bar = QToolBar()
        self._tool_bar.addAction('Start', self.start_trace)
        self._tool_bar.addAction('Pause', self.pause_trace)
        self._tool_bar.addAction('Stop', self.stop_trace)
        self._tool_bar.addSeparator()
        self._entries_lbl = QLabel('Entries: 0')
        self._entries_lbl.setStyleSheet('color: #ef5350;')
        self._entries_lbl.setContentsMargins(10, 0, 10, 2)
        self._entries_lbl.setAttribute(Qt.WA_TranslucentBackground,
                                       True)  # keep this
        self._entries_lbl.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self._entries_lbl.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Preferred)
        self._tool_bar.addWidget(self._entries_lbl)

        layout.addWidget(self._tool_bar)

        self.setup_splitter = QSplitter()
        self.events_list = JavaTraceView(self)
        self.events_list.setVisible(False)

        self.trace_list = DwarfListView()
        self.trace_list_model = QStandardItemModel(0, 1)
        self.trace_list_model.setHeaderData(0, Qt.Horizontal, 'Traced')
        self.trace_list.setModel(self.trace_list_model)

        self.trace_list.doubleClicked.connect(self.trace_list_double_click)

        self.class_list = DwarfListView()
        self.class_list_model = QStandardItemModel(0, 1)
        self.class_list_model.setHeaderData(0, Qt.Horizontal, 'Classes')
        self.class_list.setModel(self.class_list_model)

        self.class_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.class_list.customContextMenuRequested.connect(
            self.show_class_list_menu)
        self.class_list.doubleClicked.connect(self.class_list_double_click)

        self.current_class_search = ''

        bar = QScrollBar()
        bar.setFixedWidth(0)
        bar.setFixedHeight(0)
        self.trace_list.setHorizontalScrollBar(bar)
        bar = QScrollBar()
        bar.setFixedWidth(0)
        bar.setFixedHeight(0)
        self.class_list.setHorizontalScrollBar(bar)

        self.setup_splitter.addWidget(self.trace_list)
        self.setup_splitter.addWidget(self.class_list)

        layout.addWidget(self.setup_splitter)
        layout.addWidget(self.events_list)

        self.setLayout(layout)

    def class_list_double_click(self, item):
        item = self.class_list_model.itemFromIndex(item)
        try:
            if self.trace_classes.index(item.text()) >= 0:
                return
        except:
            pass
        self.trace_classes.append(item.text())
        self.trace_list_model.appendRow([QStandardItem(item.text())])
        self.trace_list_model.sort(0, Qt.AscendingOrder)

    def on_enumeration_start(self):
        self.class_list_model.setRowCount(0)

    def on_enumeration_match(self, java_class):
        try:
            if PREFIXED_CLASS.index(java_class) >= 0:
                try:
                    if self.trace_classes.index(java_class) >= 0:
                        return
                except:
                    pass
                self.trace_list_model.appendRow(QStandardItem(java_class))
                self.trace_classes.append(java_class)
        except:
            pass

        self.class_list_model.appendRow([QStandardItem(java_class)])

    def on_enumeration_complete(self):
        self.class_list_model.sort(0, Qt.AscendingOrder)
        self.trace_list_model.sort(0, Qt.AscendingOrder)

    def on_event(self, data):
        trace, event, clazz, data = data
        if trace == 'java_trace':
            self.events_list.add_event({
                'event': event,
                'class': clazz,
                'data': data.replace(',', ', ')
            })
            self._entries_lbl.setText('Events: %d' %
                                      len(self.events_list.data))

    def pause_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False

    def show_class_list_menu(self, pos):
        menu = QMenu()
        search = menu.addAction('Search')
        action = menu.exec_(self.class_list.mapToGlobal(pos))
        if action:
            if action == search:
                self.class_list._on_cm_search()

    def start_trace(self):
        self.app.dwarf.dwarf_api('startJavaTracer', [self.trace_classes])
        self.trace_depth = 0
        self.tracing = True
        self.setup_splitter.setVisible(False)
        self.events_list.setVisible(True)

    def stop_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False
        self.setup_splitter.setVisible(True)
        self.events_list.setVisible(False)
        self.events_list.clear()

    def trace_list_double_click(self, model_index):
        row = self.trace_list_model.itemFromIndex(model_index).row()
        if row != -1:
            trace_entry = self.trace_list_model.item(row, 0).text()

            if not trace_entry:
                return

            try:
                index = self.trace_classes.index(trace_entry)
                self.trace_classes.pop(index)
                self.trace_list_model.removeRow(row)
            except ValueError:
                pass

    def keyPressEvent(self, event):
        if event.modifiers() & Qt.ControlModifier:
            if event.key() == Qt.Key_F:
                self.search()
        super(JavaTracePanel, self).keyPressEvent(event)
Ejemplo n.º 2
0
class JavaTracePanel(QtWidgets.QWidget):
    def __init__(self, app, *__args):
        super().__init__(app)
        self.app = app

        self.app.dwarf.onJavaTraceEvent.connect(self.on_event)
        self.app.dwarf.onEnumerateJavaClassesStart.connect(
            self.on_enumeration_start)
        self.app.dwarf.onEnumerateJavaClassesMatch.connect(
            self.on_enumeration_match)
        self.app.dwarf.onEnumerateJavaClassesComplete.connect(
            self.on_enumeration_complete)

        self.tracing = False
        self.trace_depth = 0

        # a list of classes you generally want to trace
        self._prefixed_classes = [
            'android.util.Base64', 'java.security.MessageDigest',
            'java.util.zip.GZIPOutputStream'
        ]

        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        self._record_icon = QtGui.QIcon(
            utils.resource_path('assets/icons/record.png'))
        self._pause_icon = QtGui.QIcon(
            utils.resource_path('assets/icons/pause.png'))
        self._stop_icon = QtGui.QIcon(
            utils.resource_path('assets/icons/stop.png'))

        self._tool_bar = QtWidgets.QToolBar()
        self._tool_bar.addAction('Start', self.start_trace)
        self._tool_bar.addAction('Pause', self.pause_trace)
        self._tool_bar.addAction('Stop', self.stop_trace)
        self._tool_bar.addSeparator()
        self._entries_lbl = QtWidgets.QLabel('Events: 0')
        self._entries_lbl.setStyleSheet('color: #ef5350;')
        self._entries_lbl.setContentsMargins(10, 0, 10, 2)
        self._entries_lbl.setAttribute(QtCore.Qt.WA_TranslucentBackground,
                                       True)  # keep this
        self._entries_lbl.setAlignment(QtCore.Qt.AlignRight
                                       | QtCore.Qt.AlignVCenter)
        self._entries_lbl.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                        QtWidgets.QSizePolicy.Preferred)
        self._tool_bar.addWidget(self._entries_lbl)

        layout.addWidget(self._tool_bar)

        self.setup_splitter = QtWidgets.QSplitter()
        self.events_list = JavaTraceView(self)
        self.events_list.setVisible(False)

        self.trace_list = DwarfListView()
        self.trace_list_model = QtGui.QStandardItemModel(0, 1)
        self.trace_list_model.setHeaderData(0, QtCore.Qt.Horizontal, 'Traced')
        self.trace_list.setModel(self.trace_list_model)

        self.trace_list.doubleClicked.connect(self.trace_list_double_click)

        self.class_list = DwarfListView()
        self.class_list_model = QtGui.QStandardItemModel(0, 1)
        self.class_list_model.setHeaderData(0, QtCore.Qt.Horizontal, 'Classes')
        self.class_list.setModel(self.class_list_model)

        self.class_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.class_list.customContextMenuRequested.connect(
            self.show_class_list_menu)
        self.class_list.doubleClicked.connect(self.class_list_double_click)

        self.current_class_search = ''

        self.setup_splitter.addWidget(self.trace_list)
        self.setup_splitter.addWidget(self.class_list)

        layout.addWidget(self.setup_splitter)
        layout.addWidget(self.events_list)

        self.setLayout(layout)

    def class_list_double_click(self, model_index):
        class_name = self.class_list_model.item(model_index.row(), 0).text()
        if class_name:
            for i in range(self.trace_list_model.rowCount()):
                if self.trace_list_model.item(i, 0).text() == class_name:
                    return

            self.trace_list_model.appendRow([QtGui.QStandardItem(class_name)])
            self.trace_list_model.sort(0, QtCore.Qt.AscendingOrder)

    def on_enumeration_start(self):
        self.class_list.clear()

    def on_enumeration_match(self, java_class):
        self.class_list_model.appendRow([QtGui.QStandardItem(java_class)])

        if java_class in self._prefixed_classes:
            for i in range(self.trace_list_model.rowCount()):
                if self.trace_list_model.item(i, 0).text() == java_class:
                    return

            self.trace_list_model.appendRow(QtGui.QStandardItem(java_class))

    def on_enumeration_complete(self):
        self.class_list_model.sort(0, QtCore.Qt.AscendingOrder)
        self.trace_list_model.sort(0, QtCore.Qt.AscendingOrder)

    def on_event(self, data):
        trace, event, clazz, data = data
        if trace == 'java_trace':
            self.events_list.add_event({
                'event': event,
                'class': clazz,
                'data': data.replace(',', ', ')
            })
            self._entries_lbl.setText('Events: %d' %
                                      len(self.events_list.data))

    def pause_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False

    def show_class_list_menu(self, pos):
        menu = QtWidgets.QMenu()
        search = menu.addAction('Search')
        action = menu.exec_(self.class_list.mapToGlobal(pos))
        if action:
            if action == search:
                self.class_list._on_cm_search()

    def start_trace(self):
        trace_classes = []
        for i in range(self.trace_list_model.rowCount()):
            trace_classes.append(self.trace_list_model.item(i, 0).text())

        if not trace_classes:
            return

        self.app.dwarf.dwarf_api('startJavaTracer', [trace_classes])
        self.trace_depth = 0
        self.tracing = True
        self.setup_splitter.setVisible(False)
        self.events_list.setVisible(True)

    def stop_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False
        self.setup_splitter.setVisible(True)
        self.events_list.setVisible(False)
        self.events_list.clear()

    def trace_list_double_click(self, model_index):
        self.trace_list_model.removeRow(model_index.row())

    def keyPressEvent(self, event):
        if event.modifiers() & QtCore.Qt.ControlModifier:
            if event.key() == QtCore.Qt.Key_F:
                self.search()
        super(JavaTracePanel, self).keyPressEvent(event)