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)
def getEmuAtVa(vw, va, maxhit=None): """ Build and run an emulator to the given virtual address from the function entry point. (most useful for state analysis. kinda heavy though...) """ fva = vw.getFunction(va) if fva == None: return None cbva,cbsize,cbfva = vw.getCodeBlock(va) fgraph = v_graphutil.buildFunctionGraph(vw, fva) # Just take the first one off the iterator... for path in v_graphutil.getCodePathsTo(fgraph, cbva): emu = vw.getEmulator() opcodes = v_graphutil.getOpsFromPath(vw, fgraph, path) for op in opcodes: if op.va == va: break emu.executeOpcode(op) return emu
def getSymbolikPathsTo(self, fva, tova, args=None, maxpath=1000): ''' For each path from the function start to tova, run all symbolik effects in an emulator instance and yield emu, effects tuples. Differs from getSymbolikPaths() in that it stops at tova rather than continuing to a ret or loop path. ''' graph = self.getSymbolikGraph(fva) tocb = self.vw.getCodeBlock(tova) if tocb == None: raise Exception("No codeblock for 'tova': 0x%x" % tova) paths = viv_graph.getCodePathsTo(graph, tocb[0]) spaths = self.getSymbolikPaths(fva, paths=paths, args=args, maxpath=maxpath, graph=graph) for emu, effs in spaths: # we have symboliks up to the codeblock, but not into it. seffs = graph.getNodeProps(tocb[0]).get('symbolik_effects') for idx in range(len(seffs)): if tova == seffs[idx].va: break effs.extend(emu.applyEffects(seffs[:idx + 1])) yield emu, effs
def getEmuAtVa(vw, va, maxhit=None): """ Build and run an emulator to the given virtual address from the function entry point. (most useful for state analysis. kinda heavy though...) """ fva = vw.getFunction(va) if fva is None: return None cbva, cbsize, cbfva = vw.getCodeBlock(va) fgraph = v_graphutil.buildFunctionGraph(vw, fva) # Just take the first one off the iterator... for path in v_graphutil.getCodePathsTo(fgraph, cbva): emu = vw.getEmulator() opcodes = v_graphutil.getOpsFromPath(vw, fgraph, path) for op in opcodes: if op.va == va: break emu.executeOpcode(op) return emu
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)
def checkGetCodePathsTo(self, vw, fva, cbva): graph = viv_graph.buildFunctionGraph(vw, fva) paths = [path for path in viv_graph.getCodePathsTo(graph, cbva)] self.codepathsto = paths self.assertGreater(len(self.codepaths), len(self.codepathsto)) paths = [path for path in graph.getHierPathsTo((cbva, ))] self.hierpathsto = paths self.assertGreater(len(self.codepaths), len(self.hierpathsto))
def checkGetCodePathsTo(self, vw, fva, cbva): graph = viv_graph.buildFunctionGraph(vw, fva ) paths = [ path for path in viv_graph.getCodePathsTo(graph, cbva) ] self.codepathsto = paths self.assertGreater(len(self.codepaths), len(self.codepathsto)) paths = [ path for path in graph.getHierPathsTo((cbva,)) ] self.hierpathsto = paths self.assertGreater(len(self.codepaths), len(self.hierpathsto))
def getSymbolikPathsTo(self, fva, tova, args=None, maxpath=1000): ''' For each path from the function start to tova, run all symbolik effects in an emulator instance and yield emu, effects tuples. Differs from getSymbolikPaths() in that it stops at tova rather than continuing to a ret or loop path. ''' graph = self.getSymbolikGraph(fva) tocb = self.vw.getCodeBlock(tova) if tocb == None: raise Exception("No codeblock for 'tova': 0x%x" % tova) paths = viv_graph.getCodePathsTo(graph, tocb[0]) spaths = self.getSymbolikPaths(fva, paths=paths, args=args, maxpath=maxpath) for emu, effs in spaths: # we have symboliks up to the codeblock, but not into it. seffs = graph.getNodeProps(tocb[0]).get('symbolik_effects') for idx in range(len(seffs)): if tova == seffs[idx].va: break effs.extend(emu.applyEffects(seffs[:idx+1])) yield emu,effs
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)