Пример #1
0
    def PopulateModel(self, trace):
        self.CleanModel()

        w = NotifyProgress()
        w.show()
        ctr = 0
        max = len(trace)

        for line in trace:

            assert isinstance(line, Traceline)
            tid = QtGui.QStandardItem('%s' % line.thread_id)
            addr = QtGui.QStandardItem('%x' % line.addr)
            disasm = QtGui.QStandardItem(line.disasm_str())
            comment = QtGui.QStandardItem(''.join(c for c in line.comment
                                                  if line.comment is not None))
            context = QtGui.QStandardItem(''.join('%s:%s ' % (c, line.ctx[c])
                                                  for c in line.ctx.keys()
                                                  if line.ctx is not None))

            ctr += 1
            w.pbar_set(int(float(ctr) / float(max) * 100))

            self.sim.appendRow([tid, addr, disasm, comment, context])

        w.close()

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)
Пример #2
0
    def PopulateForm(self):
        ### init widgets
        # model
        self.sim = QtGui.QStandardItemModel()

        # tree view
        self.treeView = QtGui.QTreeView()
        self.treeView.setExpandsOnDoubleClick(True)
        self.treeView.setSortingEnabled(False)
        self.treeView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.treeView.setToolTip(
            'Filter instructions/clusters/basic blocks from trace by double clicking on them.'
        )
        # Context menus
        self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.treeView.customContextMenuRequested.connect(
            self.OnCustomContextMenu)

        self.treeView.doubleClicked.connect(self.ItemDoubleClickSlot)
        self.treeView.setModel(self.sim)

        ### populate widgets
        # fill model with data
        self.PopulateModel()

        # self.treeView.setFirstColumnSpanned(0, self.treeView.rootIndex(), True)
        # finalize layout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.treeView)

        self.parent.setLayout(layout)
Пример #3
0
    def PopulateForm(self):
        ### init widgets
        # model
        self.sim = QtGui.QStandardItemModel()
        self.sim.setHorizontalHeaderLabels(
            ['ThreadId', 'Address', 'Disasm', 'Stack Comment', 'CPU Context'])

        # toolbar
        self.utb = QtGui.QToolBar()
        self.ltb = QtGui.QToolBar()
        # tree view
        self.treeView = QtGui.QTreeView()
        self.treeView.setExpandsOnDoubleClick(True)
        self.treeView.setSortingEnabled(False)
        self.treeView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.treeView.setToolTip(
            'Highlights:\n Rust red - Input\n Violet - Output\n Olive - Both')

        ### populate widgets
        # fill model with data
        self.PopulateModel()
        # fill toolbar with data
        self.PopulateUpperToolbar()
        self.PopulateLowerToolbar()
        self.treeView.setModel(self.sim)
        # finalize layout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.utb)
        layout.addWidget(self.treeView)
        layout.addWidget(self.ltb)

        self.parent.setLayout(layout)
Пример #4
0
    def PopulateForm(self):
        ### init widgets
        # model
        self.sim = QtGui.QStandardItemModel()
        self.sim.setHorizontalHeaderLabels(
            ['ThreadId', 'Address', 'Disasm', 'Stack Comment', 'CPU Context'])

        # toolbar
        self.ftb = QtGui.QToolBar()
        self.stb = QtGui.QToolBar()

        # tree view
        self.treeView = QtGui.QTreeView()
        self.treeView.setToolTip('Double click a grade to filter')
        self.treeView.setExpandsOnDoubleClick(True)
        self.treeView.setSortingEnabled(False)
        self.treeView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        # Context menus
        self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.treeView.customContextMenuRequested.connect(
            self.OnCustomContextMenu)

        self.treeView.doubleClicked.connect(self.ItemDoubleClickSlot)
        self.treeView.setModel(self.sim)

        ### populate widgets
        # fill model with data
        self.PopulateModel(0)
        # finalize layout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.treeView)

        self.parent.setLayout(layout)
Пример #5
0
    def OnCustomContextMenu(self, point):
        menu = QtGui.QMenu()

        # Actions
        action_set_t = QtGui.QAction('Set grade threshold...',
                                     self.treeView,
                                     triggered=lambda: self.SetThreshold())
        action_restore = QtGui.QAction('Show All',
                                       self.treeView,
                                       triggered=lambda: self.Restore())
        action_export_trace = QtGui.QAction('Export this trace...',
                                            self.treeView,
                                            triggered=lambda: self.SaveTrace())
        action_close_viewer = QtGui.QAction('Close Viewer',
                                            self.treeView,
                                            triggered=lambda: self.Close(4))

        # add actions to menu
        menu.addAction(action_set_t)
        menu.addAction(action_restore)
        menu.addAction(action_export_trace)
        menu.addSeparator()
        menu.addAction(action_close_viewer)

        menu.exec_(self.treeView.viewport().mapToGlobal(point))
Пример #6
0
    def PopulateForm(self):
        ### init widgets
        # model
        self.sim = QtGui.QStandardItemModel()
        self.sim.setHorizontalHeaderLabels([
            'Stack Address', 'Address Mapped to CPU Reg',
            'Value Changes during Execution'
        ])

        # tree view
        self.treeView = QtGui.QTreeView()
        self.treeView.setExpandsOnDoubleClick(True)
        self.treeView.setSortingEnabled(False)
        self.treeView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)

        ### populate widgets
        # fill model with data
        self.PopulateModel()

        self.treeView.setModel(self.sim)
        # finalize layout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.treeView)

        self.parent.setLayout(layout)
Пример #7
0
 def PopulateUpperToolbar(self):
     assert isinstance(self.input, set)
     self.utb.addWidget(
         QtGui.QLabel('Input values found (check to highlight in trace): '))
     for value in self.input:
         self.ucb_map.append(QtGui.QCheckBox(value))
         self.ucb_map[-1].stateChanged.connect(
             lambda: self.OnValueChecked())
         self.utb.addWidget(self.ucb_map[-1])
         self.utb.addSeparator()
Пример #8
0
    def PopulateModel(self):
        for key in self.sorted:
            sa = QtGui.QStandardItem('%s' % key)
            chg = QtGui.QStandardItem('%s' % self.stack_changes[key])

            if key in self.vr.values():
                reg = QtGui.QStandardItem(
                    '%s' % [k for k in self.vr.keys() if self.vr[k] == key][0])
            else:
                reg = QtGui.QStandardItem(' ')
            self.sim.appendRow([sa, reg, chg])

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
Пример #9
0
def save(trace):
    """
    保存到trace文件
    """
    try:
        fd = QtGui.QFileDialog()
        fd.setFileMode(QtGui.QFileDialog.AnyFile)
        fd.setFilter('JSON Files (*.json)')
        fd.setWindowTitle('Save Trace ...')
        if fd.exec_():
            path = fd.selectedFiles()[0]
        else:
            path = None
    except:
        path = os.getcwd() + get_root_filename(
        ) + '_trace_%s.json' % time.time()

    if path is not None:
        if path.endswith('.json'):
            path = path[:-5]
        with open(path + '.json', 'w') as f:
            if trace:
                obj = {
                    i: [
                        '%x' % trace[i].thread_id,
                        '%x' % trace[i].addr, trace[i].disasm, trace[i].ctx,
                        trace[i].comment, trace[i].grade
                    ]
                    for i in range(len(trace))
                }
                f.write(json.dumps(obj))
                msg('[*] Trace saved!\n')
            else:
                raise Exception("[*] Trace seems to be None:\n %s" % trace)
Пример #10
0
 def PopulateSelectiveRegsToolbar(self):
     self.stb.addWidget(QtGui.QLabel('Selective Register Folding: '))
     assert isinstance(self.trace, Trace)
     if self.trace.ctx_reg_size == 32:
         for i in range(8):
             self.foldable_regs.append(
                 QtGui.QCheckBox(get_reg_by_size(i,
                                                 self.trace.ctx_reg_size)))
             self.foldable_regs[-1].stateChanged.connect(
                 lambda: self.FoldRegs())
             self.stb.addWidget(self.foldable_regs[-1])
             self.stb.addSeparator()
     elif self.trace.ctx_reg_size == 64:
         for i in range(16):
             self.foldable_regs.append(
                 QtGui.QCheckBox(get_reg_by_size(i,
                                                 self.trace.ctx_reg_size)))
             self.foldable_regs[-1].stateChanged.connect(
                 lambda: self.FoldRegs())
             self.stb.addWidget(self.foldable_regs[-1])
             self.stb.addSeparator()
Пример #11
0
    def PopulateOptimizationsToolbar(self):
        self.ftb.addWidget(
            QtGui.QLabel('Available Optimizations (check to run on trace): '))
        self.cpcb = QtGui.QCheckBox(optimization_names[0])
        self.cpcb.stateChanged.connect(lambda: self.OptimizeTrace(self.cpcb))
        self.ftb.addWidget(self.cpcb)
        self.ftb.addSeparator()

        self.sacb = QtGui.QCheckBox(optimization_names[1])
        self.sacb.stateChanged.connect(lambda: self.OptimizeTrace(self.sacb))
        self.ftb.addWidget(self.sacb)
        self.ftb.addSeparator()

        self.oscb = QtGui.QCheckBox(optimization_names[2])
        self.oscb.stateChanged.connect(lambda: self.OptimizeTrace(self.oscb))
        self.ftb.addWidget(self.oscb)
        self.ftb.addSeparator()

        self.uocb = QtGui.QCheckBox(optimization_names[3])
        self.uocb.stateChanged.connect(lambda: self.OptimizeTrace(self.uocb))
        self.ftb.addWidget(self.uocb)
        self.ftb.addSeparator()

        self.pcb = QtGui.QCheckBox(optimization_names[4])
        self.pcb.stateChanged.connect(lambda: self.OptimizeTrace(self.pcb))
        self.ftb.addWidget(self.pcb)
        self.ftb.addSeparator()
Пример #12
0
    def OnCustomContextMenu(self, point):
        menu = QtGui.QMenu()
        # Actions
        action_undo = QtGui.QAction('Undo',
                                    self.treeView,
                                    triggered=lambda: self.Undo())
        action_restore = QtGui.QAction('Restore original trace',
                                       self.treeView,
                                       triggered=lambda: self.Restore())
        action_forward_to_clustering = QtGui.QAction(
            "Open in Clustering Analysis",
            self.treeView,
            triggered=lambda: self.ClusterForward())
        action_export_trace = QtGui.QAction('Export this trace...',
                                            self.treeView,
                                            triggered=lambda: self.SaveTrace())
        action_close_viewer = QtGui.QAction('Close Viewer',
                                            self.treeView,
                                            triggered=lambda: self.Close(4))

        # add actions to menu
        menu.addAction(action_undo)
        menu.addAction(action_restore)
        menu.addAction(action_forward_to_clustering)
        menu.addAction(action_export_trace)
        menu.addSeparator()
        menu.addAction(action_close_viewer)

        menu.exec_(self.treeView.viewport().mapToGlobal(point))
Пример #13
0
    def OnCustomContextMenu(self, point):
        menu = QtGui.QMenu()
        init_index = self.treeView.indexAt(point)
        index = self.treeView.indexAt(point)
        level = 0
        while index.parent().isValid():
            index = index.parent()
            level += 1

        text = 'Remove Line'

        if level == 0:
            text = "Remove Cluster / Line"
        elif level == 1 and get_vmr().bb:
            text = "Remove Basic Block"
        elif level == 2:
            text = "Remove Line"
        try:
            action_remove = QtGui.QAction(
                text,
                self.treeView,
                triggered=lambda: self.ItemDoubleClickSlot(init_index))
            menu.addAction(action_remove)
            menu.addSeparator()
        except:
            print '[*] An Exception occured, remove action could not be added to the menu!'
        # Actions
        action_remove_threshold = QtGui.QAction(
            'Remove several clusters...',
            self.treeView,
            triggered=lambda: self.ClusterRemoval())

        action_undo = QtGui.QAction('Undo',
                                    self.treeView,
                                    triggered=lambda: self.Undo())
        action_restore = QtGui.QAction('Restore original trace',
                                       self.treeView,
                                       triggered=lambda: self.Restore())
        action_export_trace = QtGui.QAction('Export this trace ...',
                                            self.treeView,
                                            triggered=lambda: self.SaveTrace())
        action_close_viewer = QtGui.QAction('Close Viewer',
                                            self.treeView,
                                            triggered=lambda: self.Close(4))

        # add actions to menu
        menu.addAction(action_remove_threshold)
        menu.addAction(action_undo)
        menu.addAction(action_restore)
        menu.addAction(action_export_trace)
        menu.addSeparator()
        menu.addAction(action_close_viewer)

        menu.exec_(self.treeView.viewport().mapToGlobal(point))
Пример #14
0
    def PopulateModel(self):
        self.CleanModel()
        assert isinstance(self.ctx, dict)
        for key in self.ctx.keys():
            if get_reg_class(key) is not None:
                node = QtGui.QStandardItem('Register %s' % key)
                node_brush = set()
                for line in self.ctx[key]:
                    assert isinstance(line, Traceline)
                    tid = QtGui.QStandardItem('%s' % line.thread_id)
                    addr = QtGui.QStandardItem('%x' % line.addr)
                    disasm = QtGui.QStandardItem(line.disasm_str())
                    comment = QtGui.QStandardItem(''.join(
                        c for c in line.comment if line.comment is not None))
                    context = QtGui.QStandardItem(''.join(
                        '%s:%s ' % (c, line.ctx[c]) for c in line.ctx.keys()
                        if line.ctx is not None))
                    ci = 0
                    co = 0
                    for selector in self.selection[
                            'upper']:  # check input values
                        if line.to_str_line().__contains__(
                                selector) or line.to_str_line().__contains__(
                                    selector.lower()):
                            ci = 1

                    for selector in self.selection[
                            'lower']:  # check output values
                        if line.to_str_line().__contains__(
                                selector) or line.to_str_line().__contains__(
                                    selector.lower()):
                            co = 2

                    node_brush.add(ci + co)
                    tid.setBackground(self.brush_map[ci + co])
                    addr.setBackground(self.brush_map[ci + co])
                    disasm.setBackground(self.brush_map[ci + co])
                    comment.setBackground(self.brush_map[ci + co])
                    context.setBackground(self.brush_map[ci + co])

                    node.appendRow([tid, addr, disasm, comment, context])
                try:
                    if len(node_brush) == 3:
                        color = 3
                    else:
                        color = max(node_brush)
                    node.setBackground(self.brush_map[color])
                except:
                    pass
                self.sim.appendRow(node)

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)
Пример #15
0
 def __init__(self,
              input_set,
              output_set,
              output_ctx,
              title='Input/Output Analysis (legacy)'):
     # context should be a dictionary containing the backward traced result of each relevant register
     super(VMInputOuputViewer, self).__init__(title)
     self.input = input_set
     self.output = output_set
     self.ctx = output_ctx
     self.selection = {'upper': [], 'lower': []}
     self.ucb_map = []
     self.lcb_map = []
     # brush map
     self.brush_map = {
         0: QtGui.QBrush(QtCore.Qt.white),  # unselected values
         1: QtGui.QBrush(QtGui.QColor(228, 153, 105)),  # input values color
         2: QtGui.QBrush(QtGui.QColor(183, 166,
                                      173)),  # output values color
         3: QtGui.QBrush(QtGui.QColor(157, 151, 84))
     }  # BOTH values, mix of both colors
Пример #16
0
def load():
    """
    从文件加载trace
    Load a trace from file. Supported are IDAs txt trace files and VMAttacks json files. Further OllyDBG and ImmunityDBG traces are supported but have slightly limited analysis capabilities.
    :param path: system path to trace file
    :return: trace object
    """
    path = ''
    try:
        fd = QtGui.QFileDialog()
        fd.setFileMode(QtGui.QFileDialog.AnyFile)
        fd.setFilters(["Text files (*.txt)", "JSON files (*.json)"])
        fd.setWindowTitle('Load Trace ...')
        if fd.exec_():
            path = fd.selectedFiles()[0]
        else:
            path = None
    except:
        msg('A Problem occured with the file selector dialog, first *.txt file in the current working directory was choosen!'
            )
        for f in os.listdir(os.getcwd()):
            if f.endswith('txt'):
                path = f
        if path == '':
            path = asktext(40, '',
                           'Please provide the full path to the trace file: ')

    if path is not None:
        get_log().log('[TRC] Loaded the trace at %s\n' % path)
        if path.endswith('.txt'):
            with open(path, 'r') as f:
                lines = f.readlines()
        elif path.endswith('.json'):
            with open(path) as f:
                lines = json.load(f)
        else:
            return None
        trace = Trace()

        functions = {
            SegName(addr): {
                GetFunctionName(ea): ea
                for ea in Functions(SegStart(addr), SegEnd(addr))
            }
            for addr in Segments()
        }

        try:
            context = defaultdict(lambda: False)

            # framework json trace
            if isinstance(lines, dict) or path.endswith('.json'):
                get_log().log('[TRC] The trace seems to be a VMAttack trace\n')
                for index in range(len(lines.keys())):
                    line = lines[str(index)]
                    t = Traceline(thread_id=line[0],
                                  addr=line[1],
                                  disasm=line[2],
                                  ctx=line[3],
                                  comment=line[4])
                    t.grade = line[5]
                    trace.append(t)

            # ida trace via Win32Dbg
            elif lines[0].startswith('Thread '):
                for i in lines[3:]:
                    if i.startswith('Thread'):
                        break
                    values = i.split('\t')
                    # thread id
                    thread_id = int(values[0], 16)

                    # addr
                    addr = BADADDR
                    func_name = values[1].strip(' ').split(':')
                    if len(func_name) == 2:
                        try:  # .segment:addr
                            addr = int(func_name[1], 16)
                        except:
                            try:  # .segment:func_name+offset
                                offset = int(func_name[1].split('+')[1], 16)
                                name = func_name[1].split('+')[0]
                                addr = functions[func_name[0]][name] + offset
                            except:
                                try:  # .segment:func_name-offset
                                    offset = int(
                                        i.split('-')[1].split(' ')[0], 16)
                                    name = func_name[1].split('-')[0]
                                    addr = functions[
                                        func_name[0]][name] - offset
                                except:
                                    if not func_name[1].startswith(
                                            'loc_'):  # .segment:func_name
                                        addr = functions[func_name[0]][
                                            func_name[1]]
                                    else:  # .segment:jmp_location
                                        addr = int(func_name[1][4:], 16)
                    elif len(func_name) == 3:
                        addr = int(func_name[2][4:], 16)

                    # disasm
                    disasm = values[2].strip(' ').lower()
                    disasm = disasm.split('  ')
                    disasm = [x.lstrip() for x in disasm]
                    disasm = filter(None, disasm)
                    if len(disasm) > 1 and disasm[1].__contains__(', '):
                        temp = disasm.pop(1)
                        for elem in temp.split(', '):
                            disasm.append(
                                elem.lstrip().lstrip('0').rstrip('h'))

                    # remove [ebp+0]
                    for dis in disasm:
                        if dis.__contains__('[ebp+0]'):
                            dis.replace('[ebp+0]', '[ebp]')

                    # context
                    ida_ctx = values[3].strip(' ').split(' ')
                    for value in ida_ctx:
                        try:
                            a, b = value.split('=')
                            if len(b) > 1:
                                b = ''.join(
                                    c.rstrip('\r\n') for c in b.lstrip('0'))
                            if b == '':
                                b = '0'
                            context[a.lower()] = b
                        except:
                            pass

                    trace.append(
                        Traceline(thread_id=thread_id,
                                  addr=addr,
                                  disasm=disasm,
                                  ctx=deepcopy(context)))
            # immunity trace
            elif lines[0].startswith('Address	'):
                for i in lines[1:]:
                    if i.__contains__('Run trace closed') or i.__contains__(
                            'Process terminated'):
                        break
                    values = i.split('\t')
                    try:
                        # thread_id
                        thread_id = sum(
                            ord(c) for c in
                            values[1])  # immunity uses names, e.g. main
                        # addr
                        try:
                            addr = int(values[0], 16)
                        except:
                            addr = BADADDR
                        # disasm
                        disasm = values[2].lower().rstrip('\r\n')
                        disasm = disasm.split(' ', 1)
                        if len(disasm) > 1 and disasm[1].__contains__(','):
                            temp = disasm.pop(1)
                            for elem in temp.split(','):
                                disasm.append(elem.lstrip('0'))
                        disasm = [
                            x.split('dword ptr ')[1]
                            if x.__contains__('dword ptr ') else x
                            for x in disasm
                        ]
                        if len(disasm) == 2 and len(
                                re.findall(r'.*\[.*[\+\-\*].*[\+\-\*].*\].*',
                                           disasm[1])) > 0:
                            disasm[1] = ida_offset(disasm[1])
                        # context
                        if len(values) > 3:
                            olly_ctx = values[3].lstrip(' ').rstrip(
                                '\r\n').split(',')
                            for value in olly_ctx:
                                try:
                                    a, b = value.split('=')
                                    if len(b) > 1:
                                        b = ''.join(c for c in b.lstrip('0')
                                                    if c not in '\n\r\t')
                                    if b == '':
                                        b = '0'
                                    context[a.lower()] = b
                                except:
                                    pass
                        trace.append(
                            Traceline(thread_id=thread_id,
                                      addr=addr,
                                      disasm=disasm,
                                      ctx=deepcopy(context)))
                    except:
                        if i.__contains__('terminated') or i.__contains__(
                                'entry point'):
                            pass

            # olly trace
            elif lines[1].startswith('main	'):
                for i in lines[1:]:
                    if i.__contains__('Logging stopped'):
                        break
                    values = i.split('\t')
                    # thread_id
                    thread_id = sum(
                        ord(c)
                        for c in values[0])  # olly uses names, e.g. main
                    # addr
                    try:
                        addr = int(values[1], 16)
                    except:
                        addr = BADADDR
                    # disasm
                    disasm = values[2].lower().rstrip('\r\n')
                    disasm = disasm.split(' ', 1)
                    if len(disasm) > 1 and disasm[1].__contains__(','):
                        temp = disasm.pop(1)
                        for elem in temp.split(','):
                            disasm.append(elem.lstrip('0'))

                    disasm = [
                        x.split('dword ptr ')[1]
                        if x.__contains__('dword ptr ') else x for x in disasm
                    ]
                    if len(disasm) == 2 and len(
                            re.findall(r'.*\[.*[\+\-\*].*[\+\-\*].*\].*',
                                       disasm[1])) > 0:
                        disasm[1] = ida_offset(disasm[1])
                    # context
                    if len(values) > 3:
                        olly_ctx = values[3].lstrip(' ').rstrip('\r\n').split(
                            ',')
                        for value in olly_ctx:
                            try:
                                a, b = value.split('=')
                                if len(b) > 1:
                                    b = ''.join(c for c in b.lstrip('0')
                                                if c not in '\n\r\t')
                                if b == '':
                                    b = '0'
                                context[a.lower()] = b
                            except:
                                pass
                    trace.append(
                        Traceline(thread_id=thread_id,
                                  addr=addr,
                                  disasm=disasm,
                                  ctx=deepcopy(context)))

            if 'rax' in trace[-1].ctx.keys():
                trace.ctx_reg_size = 64
            elif 'eax' in trace[-1].ctx.keys(
            ) and 'rax' not in trace[-1].ctx.keys():
                trace.ctx_reg_size = 32
            msg("[*] Trace Loaded!\n")
            return trace
        except Exception, e:
            raise Exception('[*] Exception occured: \n%s\n' % (e.message))
Пример #17
0
    def PopulateModel(self, threshold):
        self.CleanModel()

        w = NotifyProgress()
        ctr = 0
        max = len(self.trace)
        prev = None
        for line in self.trace:
            assert isinstance(line, Traceline)
            if line.grade >= threshold:
                if prev is not None and threshold > 2:
                    grade = QtGui.QStandardItem(' ')
                    tid = QtGui.QStandardItem(' ')
                    addr = QtGui.QStandardItem(' ')
                    disasm = QtGui.QStandardItem('previous CPU context:')
                    comment = QtGui.QStandardItem(' ')
                    context = QtGui.QStandardItem(''.join(
                        '%s:%s ' % (c, prev.ctx[c]) for c in prev.ctx.keys()
                        if prev.ctx is not None))
                    self.sim.appendRow(
                        [grade, tid, addr, disasm, comment, context])
                grade = QtGui.QStandardItem('%s' % line.grade)
                tid = QtGui.QStandardItem('%s' % line.thread_id)
                addr = QtGui.QStandardItem('%x' % line.addr)
                disasm = QtGui.QStandardItem(line.disasm_str())
                comment = QtGui.QStandardItem(''.join(
                    c for c in line.comment if line.comment is not None))
                context = QtGui.QStandardItem(''.join(
                    '%s:%s ' % (c, line.ctx[c]) for c in line.ctx.keys()
                    if line.ctx is not None))

                self.sim.appendRow(
                    [grade, tid, addr, disasm, comment, context])

            ctr += 1
            w.pbar_set(int(float(ctr) / float(max) * 100))
            prev = line
        w.close()

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)
        self.treeView.resizeColumnToContents(5)
Пример #18
0
    def PopulateModel(self):
        self.Clean()
        vmr = get_vmr()
        w = NotifyProgress()
        w.show()
        ctr = 0
        max = len(self.trace)

        # present clustering analysis in viewer
        prev_ctx = defaultdict(lambda: 0)
        for line in self.trace:

            ctr += 1
            w.pbar_set(int(float(ctr) / float(max) * 100))

            if isinstance(line, Traceline):
                tid = QtGui.QStandardItem('%s' % line.thread_id)
                addr = QtGui.QStandardItem('%x' % line.addr)
                disasm = QtGui.QStandardItem(line.disasm_str())
                comment = QtGui.QStandardItem(''.join(
                    c for c in line.comment if line.comment is not None))
                context = QtGui.QStandardItem(''.join(
                    '%s:%s ' % (c, line.ctx[c]) for c in line.ctx
                    if line.ctx is not None))
                prev_ctx = line.ctx
                self.sim.appendRow([tid, addr, disasm, comment, context])
            else:
                cluster_node = QtGui.QStandardItem(
                    'Cluster %x-%x' % (line[0].addr, line[-1].addr))
                self.sim.appendRow(cluster_node)
                if vmr.bb:
                    cluster = line
                    bbs = []
                    bb = []
                    # subdivide the clusters by basic blocks
                    for line in cluster:
                        assert isinstance(line, Traceline)
                        if is_basic_block_end(line.addr):
                            bb.append(line)
                            bbs.append(bb)
                            bb = []
                        else:
                            bb.append(line)

                    for bb in bbs:

                        bb_sum = self.bb_func(bb, self.ctx_reg_size, prev_ctx)
                        bb_node = QtGui.QStandardItem(
                            'BB%s Summary %x-%x: %s\t%s\t%s' %
                            (bbs.index(bb), bb[0].addr, bb[-1].addr, ''.join(
                                '%s ; ' % (''.join('%s, ' % c for c in line))
                                for line in bb_sum.disasm), ''.join(
                                    '%s, ' % c
                                    for c in filter(None, bb_sum.comment)
                                    if bb_sum.comment is not None), ''.join(
                                        '%s:%s ' % (c, bb_sum.ctx[c])
                                        for c in bb_sum.ctx
                                        if bb_sum.ctx is not None)))
                        for line in bb:
                            tid = QtGui.QStandardItem('%s' % line.thread_id)
                            addr = QtGui.QStandardItem('%x' % line.addr)
                            disasm = QtGui.QStandardItem(line.disasm_str())
                            comment = QtGui.QStandardItem(''.join(
                                c for c in line.comment
                                if line.comment is not None))
                            context = QtGui.QStandardItem(''.join(
                                '%s:%s ' % (c, line.ctx[c]) for c in line.ctx
                                if line.ctx is not None))
                            bb_node.appendRow(
                                [tid, addr, disasm, comment, context])
                        cluster_node.appendRow(bb_node)
                        self.treeView.setFirstColumnSpanned(
                            bbs.index(bb), cluster_node.index(), True)

                        prev_ctx = bb[-1].ctx
                else:
                    for l in line:
                        tid = QtGui.QStandardItem('%s' % l.thread_id)
                        addr = QtGui.QStandardItem('%x' % l.addr)
                        disasm = QtGui.QStandardItem(l.disasm_str())
                        comment = QtGui.QStandardItem(''.join(
                            c for c in l.comment if l.comment is not None))
                        context = QtGui.QStandardItem(''.join(
                            '%s:%s ' % (c, l.ctx[c]) for c in l.ctx
                            if l.ctx is not None))
                        cluster_node.appendRow(
                            [tid, addr, disasm, comment, context])

        w.close()

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)