예제 #1
0
    def do_pathcount(self, line):
        '''
        Mostly for testing the graph stuff... this will likely be removed.

        (does not count paths with loops currently...)

        Usage: pathcount <func_expr>
        '''
        if not line:
            return self.do_help('pathcount')
        try:
            fva = self.parseExpression(line)
            if not self.isFunction(fva):
                self.vprint('Not a function!')
                return

        except Exception as e:
            self.vprint(str(e))
            return

        g = v_t_graph.buildFunctionGraph(self, fva)
        pathcnt = 0
        for path in v_t_graph.getCodePaths(g):
            self.vprint('Path through 0x%.8x: %s' %
                        (fva, [hex(p[0]) for p in path]))
            pathcnt += 1
        self.vprint('Total Paths: %d' % pathcnt)
예제 #2
0
    def renderSymbolikPaths(self):
        try:

            self.memcanvas.clearCanvas()
            exprtxt = str(self.exprtext.text())
            if not exprtxt:
                return

            exprparts = exprtxt.split(';')
            expr = exprparts[0]

            preeff = []
            precons = []
            for e in exprparts[1:]:
                s = self.symexpr.parseExpression(e)

                if isinstance(s, viv_sym_constraints.Constraint):
                    precons.append(s)
                    continue

                if isinstance(s, viv_sym_effects.SymbolikEffect):
                    preeff.append(s)
                    continue

                raise Exception('Unhandled Symbolik Expression: %s' % e)

            self.symctx.setSymPreEffects(preeff)
            self.symctx.setSymPreConstraints(precons)

            va = self.vw.parseExpression(expr)
            self.fva = self.vw.getFunction(va)
            if self.fva == None:
                raise Exception('Invalid Address: 0x%.8x' % va)

            # check the constraints
            codepaths = None
            codegraph = self.symctx.getSymbolikGraph(self.fva)
            cexpr = str(self.constraintext.text())
            if cexpr:
                cva = self.vw.parseExpression(cexpr)
                ccb = self.vw.getCodeBlock(cva)
                if ccb != None and ccb in self.vw.getFunctionBlocks(self.fva):
                    codepaths = viv_graph.getCodePathsThru(
                        codegraph, ccb[0], loopcnt=3
                    )  #FIXME: allow the GUI-setting of loopcnt, instead of hard-coding

            if codepaths == None:
                codepaths = viv_graph.getCodePaths(codegraph, 3)

            #paths = self.symctx.getSymbolikPaths(self.fva, paths=codepaths, maxpath=100)
            paths = self.symctx.walkSymbolikPaths(self.fva, maxpath=100)
            self.pathview.loadSymbolikPaths(paths)

        except Exception, e:
            traceback.print_exc()
            self.memcanvas.addText('ERROR: %s' % e)
예제 #3
0
    def renderSymbolikPaths(self):
        try:

            self.memcanvas.clearCanvas()
            exprtxt = str(self.exprtext.text())
            if not exprtxt:
                return

            exprparts = exprtxt.split(';')
            expr = exprparts[0]

            preeff = []
            precons = []
            for e in exprparts[1:]:
                s = self.symexpr.parseExpression(e)

                if isinstance(s, viv_sym_constraints.Constraint):
                    precons.append(s)
                    continue

                if isinstance(s, viv_sym_effects.SymbolikEffect):
                    preeff.append(s)
                    continue

                raise Exception('Unhandled Symbolik Expression: %s' % e)

            self.symctx.setSymPreEffects(preeff)
            self.symctx.setSymPreConstraints(precons)

            va = self.vw.parseExpression(expr)
            self.fva = self.vw.getFunction(va)
            if self.fva == None:
                raise Exception('Invalid Address: 0x%.8x' % va )

            # check the constraints
            codepaths = None
            codegraph = self.symctx.getSymbolikGraph(self.fva)
            cexpr = str(self.constraintext.text())
            if cexpr:
                cva = self.vw.parseExpression(cexpr)
                ccb = self.vw.getCodeBlock(cva)
                if ccb != None and ccb in self.vw.getFunctionBlocks(self.fva):
                    codepaths = viv_graph.getCodePathsThru(codegraph, ccb[0], loopcnt=3)   #FIXME: allow the GUI-setting of loopcnt, instead of hard-coding

            if codepaths == None:
                codepaths = viv_graph.getCodePaths(codegraph, 3)
                    
            #paths = self.symctx.getSymbolikPaths(self.fva, paths=codepaths, maxpath=100)
            paths = self.symctx.walkSymbolikPaths(self.fva, maxpath=100)
            self.pathview.loadSymbolikPaths(paths)

        except Exception, e:
            traceback.print_exc()
            self.memcanvas.addText('ERROR: %s' % e)
예제 #4
0
    def test_graphutil_getcodepaths(self):
        '''
        In this function, order doesn't matter
        '''
        vw = self.gcc_vw
        g = v_t_graphutil.buildFunctionGraph(vw, 0x456190)
        paths = [
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x45621c, 0x456240, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x45621c, 0x40aa97, 0x4561ea, 0x4561ef, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x45621c, 0x40aa97, 0x4561ea, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x4561c2, 0x4561d0, 0x4561ea, 0x4561ef, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x4561c2, 0x4561d0, 0x4561ea, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x4561c2, 0x40aa85, 0x40aa8d, 0x4561d0, 0x4561ea, 0x4561ef, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x4561c2, 0x40aa85, 0x40aa8d, 0x4561d0, 0x4561ea, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x456216, 0x4561c2, 0x40aa85, 0x40aab9, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x45621c, 0x456240, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x45621c, 0x40aa97, 0x4561ea, 0x4561ef, 0x4561fa, 0x456242]),
            set([0x456190, 0x4561ba, 0x456202, 0x45621c, 0x40aa97, 0x4561ea, 0x4561fa, 0x456242]),
            set([0x456190, 0x456242]),
        ]

        pathcount = 0
        genr = v_t_graphutil.getCodePaths(g, loopcnt=0, maxpath=None)
        for path in genr:
            p = set(map(lambda k: k[0], path))
            self.assertIn(p, paths)
            pathcount += 1

        self.assertEqual(12, pathcount)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x0041a766))
        thruCnt = glen(v_t_graphutil.getCodePathsThru(g, 0x0041a766))
        self.assertEqual(2, thruCnt)
        thruCnt = glen(v_t_graphutil.getCodePathsThru(g, 0x0041a766, maxpath=1))
        self.assertEqual(1, thruCnt)

        # this will not be true for all examples, but for this function it is
        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x0041a77d))
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x0041a77d))
        self.assertEqual(2, toCnt)
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x0041a77d, maxpath=99))
        self.assertEqual(2, toCnt)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x004042eb))
        fromCnt = glen(v_t_graphutil.getCodePathsFrom(g, 0x004042eb))
        self.assertEqual(8, fromCnt)
        fromCnt = glen(v_t_graphutil.getCodePathsFrom(g, 0x004042eb, maxpath=3))
        self.assertEqual(3, fromCnt)
예제 #5
0
    def test_graphutil_getcodepaths(self):
        '''
        In this function, order doesn't matter
        '''
        vw = self.firefox_vw
        g = v_t_graphutil.buildFunctionGraph(vw, 0x140010e60)
        paths = [
            set([5368778336, 5368778350, 5368778362, 5368778366, 5368778394, 5368778400]),
            set([5368778336, 5368778350, 5368778362, 5368778366, 5368778498, 5368778515, 5368778394, 5368778400]),
            set([5368778336, 5368778350, 5368778362, 5368778366, 5368778498, 5368778520, 5368778544, 5368778549]),
            set([5368778336, 5368778350, 5368778362, 5368778366, 5368778498, 5368778520, 5368778544, 5368778601, 5368778603]),
            set([5368778336, 5368778350, 5368778362, 5368778366, 5368778498, 5368778520, 5368778560, 5368778603]),
            set([5368778336, 5368778350, 5368778482, 5368778366, 5368778394, 5368778400]),
            set([5368778336, 5368778350, 5368778482, 5368778366, 5368778498, 5368778515, 5368778394, 5368778400]),
            set([5368778336, 5368778350, 5368778482, 5368778366, 5368778498, 5368778520, 5368778544, 5368778549]),
            set([5368778336, 5368778350, 5368778482, 5368778366, 5368778498, 5368778520, 5368778544, 5368778601, 5368778603]),
            set([5368778336, 5368778350, 5368778482, 5368778366, 5368778498, 5368778520, 5368778560, 5368778603]),
            set([5368778336, 5368778400]),
        ]

        pathcount = 0
        genr = v_t_graphutil.getCodePaths(g, loopcnt=0, maxpath=None)
        for path in genr:
            p = set([k[0] for k in path])
            self.assertIn(p, paths)
            pathcount += 1

        self.assertEqual(11, pathcount)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x1400110a0))
        thruCnt = glen(v_t_graphutil.getCodePathsThru(g, 0x1400110a0))
        self.assertEqual(23, thruCnt)
        thruCnt = glen(v_t_graphutil.getCodePathsThru(g, 0x1400110a0, maxpath=2))
        self.assertEqual(2, thruCnt)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x14001ead0))
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x14001ec2a))
        self.assertEqual(2, toCnt)
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x14001ec2a, maxpath=99))
        self.assertEqual(2, toCnt)


        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x1400019ab))
        fromCnt = glen(v_t_graphutil.getCodePathsFrom(g, 0x1400019ab))
        self.assertEqual(2, fromCnt)
        fromCnt = glen(v_t_graphutil.getCodePathsFrom(g, 0x1400019ab, maxpath=1))
        self.assertEqual(1, fromCnt)
예제 #6
0
    def getSymbolikPaths(self, fva, paths=None, args=None, maxpath=1000, graph=None):
        '''
        For each path through the function, run all symbolik
        effects in an emulator instance and yield
        emu, effects tuples...
        '''
        if graph is None:
            graph = self.getSymbolikGraph(fva)

        if args is None:
            argdef = self.vw.getFunctionArgs(fva)
            args = [Arg(i, width=self.vw.psize) for i in range(len(argdef))]

        if paths is None:
            paths = viv_graph.getCodePaths(graph, maxpath=maxpath)

        pcnt = 0
        for path in paths:
            if pcnt > maxpath:
                break

            pcnt += 1
            skippath = False
            emu = self.getFuncEmu(fva, fargs=args)

            for fname, funccb in self.funccb.items():
                emu.addFunctionCallback(fname, funccb)

            opcodes = []

            patheffects = emu.applyEffects(self.preeffects)

            for nid, eid in path:
                # This is the edge that *got us here* so it has to
                # be processed first!
                if eid is not None:
                    constraints = graph.getEdgeProps(eid).get('symbolik_constraints', ())
                    constraints = emu.applyEffects(constraints)

                    # print 'EDGE GOT CONSTRAINTS',[ str(c) for c in constraints]
                    # FIXME check if constraints are discrete, and possibly skip path!
                    # FIXME: if constraints are Const vs Const, and one Const is a loop var, don't skip!

                    if self.consolve:
                        # If any of the constraints are discrete and false we skip the path
                        [c.reduce() for c in constraints]
                        discs = [c.cons._solve() for c in constraints if c.cons.isDiscrete()]
                        # print 'CONS',constraints
                        # print 'DISCS',discs
                        if not all(discs):  # emtpy discs is True...
                            # print('SKIP: %s %s' % (repr(discs),[str(c) for c in constraints ]))
                            skippath = True
                            break

                        # reduce/remove constraints that were discrete and passed
                        constraints = [c for c in constraints if not c.cons.isDiscrete()]

                    patheffects += constraints

                if skippath:
                    break

                patheffects += emu.applyEffects(graph.getNodeProps(nid).get('symbolik_effects', ()))

                opcodes += graph.getNodeProps(nid).get('opcodes', ())

            if not skippath:
                # Store off some info into emu meta for analysis to use
                emu.setMeta('opcodes', opcodes)
                yield emu, patheffects
예제 #7
0
파일: analysis.py 프로젝트: d4nnyk/vivisect
    def getSymbolikPaths(self, fva, paths=None, args=None, maxpath=1000):
        '''
        For each path through the function, run all symbolik
        effects in an emulator instance and yield
        emu, effects tuples...
        '''
        graph = self.getSymbolikGraph(fva)

        if args == None:
            argdef = self.vw.getFunctionArgs( fva )
            args = [ Arg(i, width=self.vw.psize) for i in xrange(len(argdef)) ]

        if paths == None:
            paths = viv_graph.getCodePaths(graph, maxpath=maxpath)

        pcnt = 0
        for path in paths:
            if pcnt > maxpath:
                break

            pcnt+=1
            skippath = False
            emu = self.getFuncEmu(fva, fargs=args)

            for fname, funccb in self.funccb.items():
                emu.addFunctionCallback(fname, funccb)

            opcodes = []

            patheffects = emu.applyEffects(self.preeffects)
            pathconstraints = emu.applyEffects(self.preconstraints)

            for nid, eid in path:
                # This is the edge that *got us here* so it has to
                # be processed first!
                if eid != None:
                    constraints = graph.getEdgeProps(eid).get('symbolik_constraints', ())
                    constraints = emu.applyEffects(constraints)
                    #[ c.reduce() for c in constraints ]

                    #print 'EDGE GOT CONSTRAINTS',[ str(c) for c in constraints]
                    # FIXME check if constraints are discrete, and possibly skip path!
                    # FIXME: if constraints are Const vs Const, and one Const is a loop var, don't skip!
                
                    cons = [ c.cons for c in constraints ]
                    if self.consolve:
                        # If any of the constraints are discrete and false we skip the path
                        [ c.reduce() for c in constraints ]
                        discs = [ c.cons.prove() for c in constraints if c.cons.isDiscrete() ]
                        #print 'CONS',constraints
                        #print 'DISCS',discs
                        if not all( discs ): # emtpy discs is True...
                            #print('SKIP: %s %s' % (repr(discs),[str(c) for c in constraints ]))
                            skippath = True
                            break

                        # reduce/remove constraints that were discrete and passed
                        constraints = [ c for c in constraints if not c.cons.isDiscrete() ]
                        cons = [ c.cons for c in constraints ]

                    patheffects.extend(constraints)
                    pathconstraints.extend( cons )

                if skippath:
                    break

                effects = emu.applyEffects( graph.getNodeProps(nid).get('symbolik_effects',()) )
                patheffects.extend(effects)

                opcodes.extend( graph.getNodeProps(nid).get('opcodes',() ) )

            if not skippath:
                # Store off some info into emu meta for analysis to use
                emu.setMeta('opcodes', opcodes)
                yield emu, patheffects
예제 #8
0
 def checkGetCodePaths(self, vw, fva):
     graph = viv_graph.buildFunctionGraph(vw, fva)
     paths = [path for path in viv_graph.getCodePaths(graph)]
     self.codepaths = paths
     self.assertGreater(len(self.codepaths), 150)
예제 #9
0
    def test_graphutil_getcodepaths(self):
        '''
        In this function, order doesn't matter
        '''
        vw = self.firefox_vw
        g = v_t_graphutil.buildFunctionGraph(vw, 0x140010e60)
        paths = [
            set([
                0x140010e60, 0x140010e6e, 0x140010e7a, 0x140010e7e,
                0x140010e9a, 0x140010ea0
            ]),
            set([
                0x140010e60, 0x140010e6e, 0x140010e7a, 0x140010e7e,
                0x140010e9a, 0x140010ea0, 0x140010f02, 0x140010f13
            ]),
            set([
                0x140010e60, 0x140010e6e, 0x140010e7a, 0x140010e7e,
                0x140010f02, 0x140010f18
            ]),
            set([
                0x140010e60, 0x140010e6e, 0x140010e7e, 0x140010e9a,
                0x140010ea0, 0x140010ef2
            ]),
            set([
                0x140010e60, 0x140010e6e, 0x140010e7e, 0x140010e9a,
                0x140010ea0, 0x140010ef2, 0x140010f02, 0x140010f13
            ]),
            set([
                0x140010e60, 0x140010e6e, 0x140010e7e, 0x140010ef2,
                0x140010f02, 0x140010f18
            ]),
            set([0x140010e60, 0x140010ea0]),
        ]

        pathcount = 0
        genr = v_t_graphutil.getCodePaths(g, loopcnt=0, maxpath=None)
        for path in genr:
            p = set([k[0] for k in path])
            self.assertIn(p, paths)
            pathcount += 1

        self.assertEqual(7, pathcount)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x1400110a0))
        thruCnt = glen(v_t_graphutil.getCodePathsThru(g, 0x1400110a0))
        self.assertEqual(21, thruCnt)
        thruCnt = glen(
            v_t_graphutil.getCodePathsThru(g, 0x1400110a0, maxpath=2))
        self.assertEqual(2, thruCnt)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x14001ead0))
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x14001ec2a))
        self.assertEqual(2, toCnt)
        toCnt = glen(v_t_graphutil.getCodePathsTo(g, 0x14001ec2a, maxpath=99))
        self.assertEqual(2, toCnt)

        g = v_t_graphutil.buildFunctionGraph(vw, vw.getFunction(0x1400019ab))
        fromCnt = glen(v_t_graphutil.getCodePathsFrom(g, 0x1400019ab))
        self.assertEqual(2, fromCnt)
        fromCnt = glen(
            v_t_graphutil.getCodePathsFrom(g, 0x1400019ab, maxpath=1))
        self.assertEqual(1, fromCnt)
예제 #10
0
 def checkGetCodePaths(self, vw, fva):
     graph = viv_graph.buildFunctionGraph(vw, fva )
     paths = [ path for path in viv_graph.getCodePaths(graph) ]
     self.codepaths = paths
     self.assertGreater(len(self.codepaths), 150)
예제 #11
0
    def getSymbolikPaths(self, fva, paths=None, args=None, maxpath=1000):
        '''
        For each path through the function, run all symbolik
        effects in an emulator instance and yield
        emu, effects tuples...
        '''
        graph = self.getSymbolikGraph(fva)

        if args == None:
            argdef = self.vw.getFunctionArgs( fva )
            args = [ Arg(i, width=self.vw.psize) for i in xrange(len(argdef)) ]

        if paths == None:
            paths = viv_graph.getCodePaths(graph, maxpath=maxpath)

        #fva = graph.getMeta('fva')  # put in place by buildFunctionGraph...
        pcnt = 0
        for path in paths:
            if pcnt > maxpath:
                break

            pcnt+=1
            skippath = False
            emu = self.getFuncEmu(fva, fargs=args)

            for fname, funccb in self.funccb.items():
                emu.addFunctionCallback(fname, funccb)

            opcodes = []
            patheffects = []
            pathconstraints = []

            for node, edge in path:
                # This is the edge that *got us here* so it has to
                # be processed first!
                if edge != None:
                    constraints = graph.getEdgeInfo(edge, 'symbolik_constraints', ())
                    constraints = emu.applyEffects(constraints)
                    #[ c.reduce() for c in constraints ]

                    #print 'EDGE GOT CONSTRAINTS',[ str(c) for c in constraints]
                    # FIXME check if constraints are discrete, and possibly skip path!
                
                    cons = [ c.cons for c in constraints ]
                    if self.consolve:
                        # If any of the constraints are discrete and false we skip the path
                        discs = [ c.cons.prove() for c in constraints if c.cons.isDiscrete() ]
                        if not all( discs ): # emtpy discs is True...
                            #print('SKIP: %s %s' % (repr(discs),[str(c) for c in constraints ]))
                            skippath = True
                            break

                        #if not self._isSat( pathconstraints , cons):
                            #print('NON SAT: 0x%.8x %s %s' % (node, [ str(c) for c in pathconstraints ], [ str(c) for c in cons ] ))
                            #skippath = True
                            #break

                    patheffects.extend(constraints)
                    pathconstraints.extend( cons )

                if skippath:
                    break

                effects = graph.getNodeInfo(node, 'symbolik_effects', ())
                effects = emu.applyEffects(effects)
                patheffects.extend(effects)

                opcodes.extend( graph.getNodeInfo( node, 'opcodes' ) )

            if not skippath:
                # Store off some info into emu meta for analysis to use
                emu.setMeta('opcodes', opcodes)
                yield emu, patheffects