def _cconv_test(self, caller, callee, argc, retn): # some setup and other fun things vw = self.i386_vw # Note: The function itself isn't important, we just need a real Symbolik emulator # instance that we can pass to setSymbolikArgs so that we can monkey with things # from there fva = 0x08051e10 ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True) argv = [Var('arg%d' % i, 4) for i in range(argc)] emu = ctx.getFuncEmu(fva) callee.setSymbolikArgs(emu, argv) caller.setSymbolikArgs(emu, argv) emu.setSymVariable('eax', retn) self.assertEqual(caller.getSymbolikReturn(emu), retn) self.assertEqual(caller.getSymbolikReturn(emu), callee.getSymbolikReturn(emu)) # if the callee cleans it up, the stack point is automatically assumed to be # delta'd by 20 bytes for bfastcall (argc == 7, 3 are registers, so 4 stack args # plus the return address makes 5 dwords to clean up for 20 bytes bytes_cleaned = (1 + callee.getNumStackArgs(emu, argc)) * 4 self.assertEqual( callee.deallocateCallSpace(emu, argc).reduce(), Const(bytes_cleaned, 4)) # if the caller cleans things up, the instructions after are going to do it # (since we're currently looking at things from a precall perspective), and so # the only thing that is going to get cleaned up is the return address self.assertEqual( caller.deallocateCallSpace(emu, argc).reduce(), Const(4, 4))
def __init__(self, vw, parent=None): self.vw = vw self.fva = None self.vwgui = vw.getVivGui() self.symctx = viv_sym_analysis.getSymbolikAnalysisContext(vw) if self.symctx == None: raise Exception('No Symboliks For: %s (yet)' % vw.getMeta('Architecture')) self.symctx.consolve = True QtGui.QWidget.__init__(self, parent=parent) e_q_memory.EnviNavMixin.__init__(self) self.setEnviNavName('Symboliks%d' % self.viewidx.next()) self.exprtext = QtGui.QLineEdit(parent=self) self.pathview = VivSymbolikPathsView(vw, parent=self) self.memcanvas = e_q_memcanvas.VQMemoryCanvas(vw, syms=vw, parent=self) self.pathview.pathSelected.connect(self.symPathSelected) self.exprtext.returnPressed.connect(self.renderSymbolikPaths) mainbox = VBox(self.exprtext, self.pathview, self.memcanvas) self.setLayout(mainbox) self.updateWindowTitle()
def __init__(self, vw, parent=None): self.vw = vw self.fva = None self.vwgui = vw.getVivGui() self.symctx = viv_sym_analysis.getSymbolikAnalysisContext(vw) if self.symctx == None: raise Exception('No Symboliks For: %s (yet)' % vw.getMeta('Architecture')) self.symctx.consolve = True QtGui.QWidget.__init__(self, parent=parent) e_q_memory.EnviNavMixin.__init__(self) self.setEnviNavName('Symboliks%d' % self.viewidx.next()) self.exprtext = QtGui.QLineEdit(parent=self) self.pathview = VivSymbolikPathsView(vw, parent=self) self.memcanvas = e_q_memcanvas.VQMemoryCanvas(vw, syms=vw, parent=self) self.pathview.pathSelected.connect(self.symPathSelected) self.exprtext.returnPressed.connect(self.renderSymbolikPaths) mainbox = VBox( self.exprtext, self.pathview, self.memcanvas ) self.setLayout(mainbox) self.updateWindowTitle()
def test_constraints(self): fva = 0x080509e0 vw = self.i386_vw ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True) g = ctx.getSymbolikGraph(fva) constraints = { 0x080509e0: { 0x8050a42: ConstrainPath(0x080509ef, Const(0x08050a42, 4), Var("eflags_eq", width=4)), 0x80509f1: ConstrainPath(0x080509ef, Const(0x080509f1, 4), cnot(Var("eflags_eq", width=4))), }, 0x8050a20: { 0x8050a26: ConstrainPath(0x08050a24, Const(0x08050a26, 4), cnot(Var("eflags_eq", width=4))), 0x8050a42: ConstrainPath(0x08050a24, Const(0x08050a42, 4), Var("eflags_eq", width=4)), }, 0x8050a26: { 0x8050a20: ConstrainPath(0x08050a3e, Const(0x08050a20, 4), cnot(Var("eflags_eq", width=4))), 0x8050a40: ConstrainPath(0x08050a3e, Const(0x08050a40, 4), cnot(cnot(Var("eflags_eq", width=4)))), }, 0x80509f1: { 0x8050a44: ConstrainPath(0x08050a0c, Const(0x08050a44, 4), Var("eflags_eq", width=4)), 0x8050a0e: ConstrainPath(0x08050a0c, Const(0x08050a0e, 4), cnot(Var("eflags_eq", width=4))) }, } for eid, xfrom, xto, props in g.getEdges(): if xfrom not in constraints: self.assertEqual(0, len(props)) continue self.assertTrue('symbolik_constraints' in props) self.assertEqual(1, len(props['symbolik_constraints'])) pcon = props['symbolik_constraints'][0] self.assertEqual(pcon, constraints[xfrom][xto])
def test_symbolik_paths_to(self): vw = self.i386_vw fva = 0x80569d0 tova = 0x08056b14 sctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=False) paths = [x for x in sctx.getSymbolikPathsTo(fva, tova)] self.assertEqual(6, len(paths))
def do_symboliks(self, line): ''' Use the new symboliks subsystem. (NOTE: i386 only for a bit...) Usage: symboliks [ options ] -A Run the emu and show the state of the machine for all found paths to the given address ''' if not line: return self.do_help("symboliks") watchaddr = None argv = e_cli.splitargs(line) try: opts, argv = getopt(argv, 'A:') except Exception: return self.do_help('symboliks') for opt, optarg in opts: if opt == '-A': # TODO: USE THIS watchaddr = self.parseExpression(optarg) va = self.parseExpression(argv[0]) fva = self.getFunction(va) import vivisect.symboliks as viv_symboliks import vivisect.symboliks.common as sym_common import vivisect.symboliks.effects as viv_sym_effects import vivisect.symboliks.analysis as vsym_analysis symctx = vsym_analysis.getSymbolikAnalysisContext(self) for emu, effects in symctx.getSymbolikPaths(fva): self.vprint('PATH %s' % ('=' * 60)) for eff in effects: eff.reduce(emu) if eff.efftype in (EFFTYPE_CONSTRAIN, EFFTYPE_CALLFUNC): self.vprint(str(eff)) for addrsym, valsym in emu._sym_mem.values(): addrsym = addrsym.reduce(emu=emu) valsym = valsym.reduce(emu=emu) if emu.isLocalMemory(addrsym): continue self.vprint('[ %s ] = %s' % (addrsym, valsym)) self.vprint('RETURN %r' % emu.getFunctionReturn().reduce())
def __init__(self, vw, parent=None): self.vw = vw self.fva = None self.vwgui = vw.getVivGui() self.curemu = None self.cureffects = None self.symctx = viv_sym_analysis.getSymbolikAnalysisContext(vw) self.symexpr = viv_sym_expression.SymbolikExpressionParser( defwidth=vw.psize) if self.symctx == None: raise Exception('No Symboliks For: %s (yet)' % vw.getMeta('Architecture')) self.symctx.consolve = True QtGui.QWidget.__init__(self, parent=parent) e_q_memory.EnviNavMixin.__init__(self) self.setEnviNavName('Symboliks%d' % self.viewidx.next()) self.exprtext = QtGui.QLineEdit(parent=self) self.constraintext = QtGui.QLineEdit(parent=self) self.alleffs = QtGui.QCheckBox('all effects', parent=self) self.alleffs.stateChanged.connect(self.rendSymbolikPath) self.loop_count = QtGui.QSpinBox(parent=self) looplabel = QtGui.QLabel(QtCore.QString("Max Loops:"), parent=self) self.pathview = VivSymbolikPathsView(vw, parent=self) self.memcanvas = e_q_memcanvas.VQMemoryCanvas(vw, syms=vw, parent=self) self.pathview.pathSelected.connect(self.symPathSelected) self.exprtext.returnPressed.connect(self.renderSymbolikPaths) self.constraintext.returnPressed.connect(self.renderSymbolikPaths) fvalabel = QtGui.QLabel(QtCore.QString("Function VA:"), parent=self) inccblabel = QtGui.QLabel(QtCore.QString("Must Include VA:"), parent=self) navbox = HBox(fvalabel, self.exprtext, inccblabel, self.constraintext, looplabel, self.loop_count, self.alleffs) mainbox = VBox() mainbox.addLayout(navbox) mainbox.addWidget(self.pathview) mainbox.addWidget(self.memcanvas) self.setLayout(mainbox) self.updateWindowTitle()
def test_symbolik_outputs(self): vw = self.i386_vw fva = 0x804cda0 # a deliberately simple function sctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True) out = [ (Var("eax", 4), []), # literally just a ret (Arg(0, 4), [ WriteMemory(0x0804cdae, Const(0x08061404, 4), Const(0x00000004, 4), Arg(0, 4)) ]), ] for ret, effects in sctx.getSymbolikOutputs(fva): self.assertTrue( (ret, effects) in out, msg='(%s, %s) is not in the symbolik outputs' % (ret, effects))
def test_symbolik_paths(self): vw = self.i386_vw fva = 0x80569d0 # quote_n_options paths = [ [0x80569d0, 0x8056b34], [0x80569d0, 0x80569ea, 0x8056a07, 0x8056b39], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a44, 0x8056a51, 0x8056a7b, 0x8056ac0, 0x8056ad7, 0x8056ae3, 0x8056b20 ], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a51, 0x8056a7b, 0x8056ac0, 0x8056ad7, 0x8056ae3, 0x8056b20 ], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a44, 0x8056a51, 0x8056a7b, 0x8056ac0, 0x8056ae3, 0x8056b20 ], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a51, 0x8056a7b, 0x8056ac0, 0x8056ae3, 0x8056b20 ], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a44, 0x8056a51, 0x8056a7b, 0x8056b20 ], [ 0x80569d0, 0x80569ea, 0x8056a07, 0x8056a13, 0x8056a51, 0x8056a7b, 0x8056b20 ], [0x80569d0, 0x80569ea, 0x8056a7b, 0x8056b20], [0x80569d0, 0x80569ea, 0x8056a7b, 0x8056ac0, 0x8056ae3, 0x8056b20], [ 0x80569d0, 0x80569ea, 0x8056a7b, 0x8056ac0, 0x8056ad7, 0x8056ae3, 0x8056b20 ], ] cnt = 0 sctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=False) for emu, effects in sctx.getSymbolikPaths(fva): cnt += 1 blks = getPathFromOpcodes(vw, emu.getMeta('opcodes')) self.assertTrue(blks in paths) self.assertEqual(cnt, len(paths))
def __init__(self, vw, parent=None): self.vw = vw self.fva = None self.vwgui = vw.getVivGui() self.curemu = None self.cureffects = None self.symctx = viv_sym_analysis.getSymbolikAnalysisContext(vw) self.symexpr = viv_sym_expression.SymbolikExpressionParser(defwidth=vw.psize) if self.symctx is None: raise Exception('No Symboliks For: %s (yet)' % vw.getMeta('Architecture')) self.symctx.consolve = True QtGui.QWidget.__init__(self, parent=parent) e_q_memory.EnviNavMixin.__init__(self) self.setEnviNavName('Symboliks%d' % next(self.viewidx)) self.exprtext = QtGui.QLineEdit(parent=self) self.constraintext = QtGui.QLineEdit(parent=self) self.alleffs = QtGui.QCheckBox('all effects', parent=self) self.alleffs.stateChanged.connect(self.rendSymbolikPath) self.loop_count = QtGui.QSpinBox(parent=self) looplabel = QtGui.QLabel("Max Loops:", parent=self) self.pathview = VivSymbolikPathsView(vw, parent=self) self.memcanvas = e_q_memcanvas.VQMemoryCanvas(vw, syms=vw, parent=self) self.pathview.pathSelected.connect(self.symPathSelected) self.exprtext.returnPressed.connect(self.renderSymbolikPaths) self.constraintext.returnPressed.connect(self.renderSymbolikPaths) fvalabel = QtGui.QLabel("Function VA:", parent=self) inccblabel = QtGui.QLabel("Must Include VA:", parent=self) navbox = HBox(fvalabel, self.exprtext, inccblabel, self.constraintext, looplabel, self.loop_count, self.alleffs) mainbox = VBox() mainbox.addLayout(navbox) mainbox.addWidget(self.pathview) mainbox.addWidget(self.memcanvas) self.setLayout(mainbox) self.updateWindowTitle()
def test_emulator(self): fva = 0x08051e10 vw = self.i386_vw ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True) retn = [ '((mem[(arg0 + 24):4](edx,mem[(arg0 + 8):4],mem[0xbfbfefec:4],mem[0xbfbfeff0:4]) * 8) + mem[arg0:4])', '0x08049a80()', ] esps = [ Const(0xbfbfeff4, 4), Const(0xbfbff004, 4), ] for emu, effects in ctx.walkSymbolikPaths(fva): self.assertTrue(str(emu.getFunctionReturn().reduce(foo=True)) in retn) esp = emu.getSymVariable('esp').reduce(foo=True) self.assertTrue(esp in esps) self.assertEqual(emu.getSymVariable('ecx'), Var('arg0', 4))
def walkTreeDoer(vw): sctx = vsym_analysis.getSymbolikAnalysisContext(vw) count = 0 for fva in vw.getFunctions(): ctx = {'depth':0, 'count':0} count += 1 #print "(%d) 0x%x done" % (count, fva) #raw_input("============================================================") for spath in sctx.getSymbolikPaths(fva, maxpath=1): effs = spath[-1] if not len(effs): continue eff = effs[-1] #print "=====\n %r \n=====" % (eff) # this is ugly symast = getattr(eff, 'symobj', None) if symast == None: symast = getattr(eff, 'addrsym', None) if symast == None: symast = getattr(eff, 'cons', None) if symast == None: symast = getattr(eff, 'funcsym', None) if symast == None: symast = getattr(eff, 'argsyms', None) if symast == None: symast = getattr(eff, 'symaddr', None) if symast == None: symast = getattr(eff, 'symval', None) if symast == None: #print "CRAP! skipping" continue eff.walkTree(cb_astNodeCount, ctx); ctx
def walkTreeDoer(vw): sctx = vsym_analysis.getSymbolikAnalysisContext(vw) count = 0 for fva in vw.getFunctions(): ctx = {'depth': 0, 'count': 0} count += 1 #print "(%d) 0x%x done" % (count, fva) #raw_input("============================================================") for spath in sctx.getSymbolikPaths(fva, maxpath=1): effs = spath[-1] if not len(effs): continue eff = effs[-1] # print("=====\n %r \n=====" % (eff)) # this is ugly symast = getattr(eff, 'symobj', None) if symast is None: symast = getattr(eff, 'addrsym', None) if symast is None: symast = getattr(eff, 'cons', None) if symast is None: symast = getattr(eff, 'funcsym', None) if symast is None: symast = getattr(eff, 'argsyms', None) if symast is None: symast = getattr(eff, 'symaddr', None) if symast is None: symast = getattr(eff, 'symval', None) if symast == None: #print "CRAP! skipping" continue eff.walkTree(cb_astNodeCount, ctx) ctx
def SKIPtest_symbolik_gcc_subchildren(self): ''' So before intify in vivisect/symboliks/common.py, this would bomb out on int has no attribute "kids" because the dellocate callspace function wasn't properly marshalling argc dellocation as Const() (and instead as raw ints) This is here mostly for codification purposes, since actually running this consumes more RAM than CI can handle. ''' vw = self.gcc_vw fva = 0x00406ad6 sctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True) graph = sctx.getSymbolikGraph(fva) for path in v_t_graph.getLongPath(graph): for emu, effects in sctx.getSymbolikPaths(fva, paths=[ path, ], graph=graph): break calls = [x for x in effects if x.efftype == v_const.EFFTYPE_CALLFUNC] self.assertEqual(len(calls), 26)
class VivCli(e_cli.EnviCli, vivisect.VivWorkspace): def __init__(self): e_cli.EnviCli.__init__(self, self, symobj=self) vivisect.VivWorkspace.__init__(self) self.canvas.addRenderer("bytes", e_render.ByteRend()) self.canvas.addRenderer("u_int_16", e_render.ShortRend()) self.canvas.addRenderer("u_int_32", e_render.LongRend()) self.canvas.addRenderer("u_int_64", e_render.QuadRend()) import vivisect.renderers as viv_rend self.canvas.addRenderer("viv", viv_rend.WorkspaceRenderer(self)) self.prompt = "viv> " self.addScriptPathEnvVar('VIV_SCRIPT_PATH') def getExpressionLocals(self): l = e_cli.EnviCli.getExpressionLocals(self) l['vw'] = self l['vprint'] = self.vprint l['vivisect'] = vivisect return l def do_report(self, line): """ Fire a report module by python path name. Usage: report <python.path.to.report.module> """ if not line: self.vprint("Report Modules") for descr,modname in viv_reports.listReportModules(): self.vprint("%32s %s" % (modname, descr)) return mod = self.loadModule(line) cols, results = mod.report(self) for row in results: for i in range(len(cols)+1): val = row[i] if i == 0: name = self.arch.pointerString(val) self.canvas.addVaText(name, val) else: self.canvas.addText(": %s" % val) for va, pri, info in mod.report(self): name = self.getName(va) if name == None: name = self.arch.pointerString(va) self.canvas.addVaText(name, va) self.canvas.addText(": %s\n" % info) 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> ''' fva = self.parseExpression(line) if not self.isFunction(fva): self.vprint('Not a function!') return g = v_t_graph.buildFunctionGraph(self, fva) # Lets find the "bottom" nodes... endblocks = [] for nid,ninfo in g.getNodes(): if len(g.getRefsFrom(nid)) == 0: endblocks.append((nid,ninfo)) for nid,ninfo in endblocks: paths = list(g.pathSearch(0, toid=nid)) self.vprint('paths to 0x%.8x: %d' % (ninfo.get('cbva'), len(paths))) def do_symboliks(self, line): ''' Use the new symboliks subsystem. (NOTE: i386 only for a bit...) Usage: symboliks [ options ] -A Run the emu and show the state of the machine for all found paths to the given address ''' watchaddr = None argv = e_cli.splitargs(line) try: opts,argv = getopt(argv, 'A:') except Exception, e: return self.do_help('symboliks') for opt,optarg in opts: if opt == '-A': watchaddr = self.parseExpression(optarg) va = self.parseExpression(argv[0]) fva = self.getFunction(va) import vivisect.symboliks as viv_symboliks import vivisect.symboliks.common as sym_common import vivisect.symboliks.effects as viv_sym_effects import vivisect.symboliks.analysis as vsym_analysis symctx = vsym_analysis.getSymbolikAnalysisContext(self) for emu, effects in symctx.getSymbolikPaths(fva): self.vprint('PATH %s' % ('='*60)) #esp = emu.solveExpression('esp', update=False) for eff in effects: eff.reduce(emu) if eff.efftype in (EFFTYPE_CONSTRAIN,EFFTYPE_CALLFUNC): self.vprint(str(eff)) #for reg in ['eax','ebx','ecx','edx','esi','edi','ebp','esp','eip']: #regobj = emu.getSymVariable(reg) #if regobj == None: #continue #regobj = regobj.reduce() #regval = regobj.solve(emu=emu) #if regval == emu.solveExpression(reg, update=False): #continue #self.vprint('%s: %s 0x%.8x' % (reg, regobj.reduce(), regobj.solve(emu))) for addrsym,valsym in emu._sym_mem.values(): addrsym = addrsym.reduce(emu=emu) valsym = valsym.reduce(emu=emu) if emu.isLocalMemory(addrsym): continue self.vprint('[ %s ] = %s' % (addrsym, valsym)) #print 'SPDELTA: %d' % (emu.solveExpression('esp')-esp) #print 'RETURN',emu.parseExpression('eax').reduce() self.vprint('RETURN',emu.getFunctionReturn().reduce())
Mem(Const(0x56560020, 4), Const(4, 4)) - (Var('arg0', 4) + Var('ecx', 4)) * (Var('ebx', 4) + Var('ebx', 4)) + Const(8888, 4), Mem(Const(0x56560020, 4), Const(4, 4)) - (Var('arg0', 4) + Var('ecx', 4)) * (Var('ebx', 4) + Var('ebx', 4)) + Const(0x56560020, 4), Mem(Const(0x56560020, 4), Const(4, 4)) - (Var('arg0', 4) + Var('ecx', 4)) * (Var('ebx', 4) + Var('ebx', 4)) + Const(0x56560040, 4), ] vw = vivisect.VivWorkspace() vw.addMemoryMap(0x56560000, 7, 'woot', 'A' * 8192) vw.setMeta('Architecture', 'i386') symctx = v_sym_analysis.getSymbolikAnalysisContext(vw) print('Before...') print('BASE: %s' % str(base)) for i in xrange(len(eqs)): print('EQ%d: %s' % (i, str(eqs[i]))) for i in xrange(len(nes)): print('NE%d: %s' % (i, str(nes[i]))) base = wipeAstArch(symctx, [ base, ], wipeva=True)[0] eqs = [ wipeAstArch(symctx, [
def test_basic(self): vw = viv.VivWorkspace() vw.addMemoryMap(0x56560000, 7, 'woot', b'A' * 8192) vw.setMeta('Architecture', 'i386') symctx = vsym_analysis.getSymbolikAnalysisContext(vw) base = vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const( 4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * ( vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(9999, 4) eqs = [ vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ebx', 4)) * (vsc.Var('ecx', 4) + vsc.Var('ecx', 4)) + vsc.Const(9999, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('eax', 4) + vsc.Var('eax', 4)) * (vsc.Var('edx', 4) + vsc.Var('arg0', 4)) + vsc.Const(9999, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(9999, 4), vsc.Mem(vsc.Const(0x56560056, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(9999, 4), ] nes = [ vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ebx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ecx', 4)) + vsc.Const(9999, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('eax', 4) + vsc.Var('arg1', 4)) * (vsc.Var('edx', 4) + vsc.Var('arg0', 4)) + vsc.Const(9999, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(8888, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(0x56560020, 4), vsc.Mem(vsc.Const(0x56560020, 4), vsc.Const(4, 4)) - (vsc.Var('arg0', 4) + vsc.Var('ecx', 4)) * (vsc.Var('ebx', 4) + vsc.Var('ebx', 4)) + vsc.Const(0x56560040, 4), ] post_eqs = [ '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 0x0000270f)', '((mem[0archindva:4] - ((1indreg + 1indreg) * (0indreg + arg0))) + 0x0000270f)', '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 0x0000270f)', '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 0x0000270f)', ] post_nes = [ '((mem[0archindva:4] - ((arg0 + 0indreg) * (0indreg + 1indreg))) + 0x0000270f)', '((mem[0archindva:4] - ((1indreg + arg1) * (0indreg + arg0))) + 0x0000270f)', '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 0x000022b8)', '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 0archindva)', '((mem[0archindva:4] - ((arg0 + 0indreg) * (1indreg + 1indreg))) + 1archindva)', ] for i in range(len(post_eqs)): eq = vsym_archind.wipeAstArch(symctx, [eqs[i]], wipeva=True)[0] self.assertEqual(post_eqs[i], str(eq)) for i in range(len(post_nes)): ne = vsym_archind.wipeAstArch(symctx, [nes[i]], wipeva=True)[0] self.assertEqual(post_nes[i], str(ne)) base = vsym_archind.wipeAstArch(symctx, [ base, ], wipeva=True)[0] baseval = base.solve(emu=None) for match in eqs: self.assertEqual(match.solve(emu=None), baseval) for nonmatch in nes: self.assertNotEqual(nonmatch.solve(emu=None), baseval)
Mem(Const(0x56560056,4),Const(4,4)) - ( Var('arg0',4) + Var('ecx',4) ) * ( Var('ebx',4) + Var('ebx',4) ) + Const(9999,4), ] nes = [ Mem(Const(0x56560020,4),Const(4,4)) - ( Var('arg0',4) + Var('ebx',4) ) * ( Var('ebx',4) + Var('ecx',4) ) + Const(9999,4) , Mem(Const(0x56560020,4),Const(4,4)) - ( Var('eax',4) + Var('arg1',4) ) * ( Var('edx',4) + Var('arg0',4) ) + Const(9999,4) , Mem(Const(0x56560020,4),Const(4,4)) - ( Var('arg0',4) + Var('ecx',4) ) * ( Var('ebx',4) + Var('ebx',4) ) + Const(8888,4) , Mem(Const(0x56560020,4),Const(4,4)) - ( Var('arg0',4) + Var('ecx',4) ) * ( Var('ebx',4) + Var('ebx',4) ) + Const(0x56560020,4) , Mem(Const(0x56560020,4),Const(4,4)) - ( Var('arg0',4) + Var('ecx',4) ) * ( Var('ebx',4) + Var('ebx',4) ) + Const(0x56560040,4) , ] vw = vivisect.VivWorkspace() vw.addMemoryMap(0x56560000, 7, 'woot', 'A'*8192) vw.setMeta('Architecture','i386') symctx = v_sym_analysis.getSymbolikAnalysisContext(vw) print('Before...') print(('BASE: %s' % str(base))) for i in range(len(eqs)): print(('EQ%d: %s' % (i,str(eqs[i])))) for i in range(len(nes)): print(('NE%d: %s' % (i,str(nes[i])))) base = wipeAstArch(symctx, [base,], wipeva=True)[0] eqs = [ wipeAstArch(symctx, [eqs[i],], wipeva=True)[0] for i in range(len(eqs)) ] nes = [ wipeAstArch(symctx, [nes[i],], wipeva=True)[0] for i in range(len(nes)) ] print('After...')
def do_symboliks(self, line): ''' Use the new symboliks subsystem. (NOTE: i386 only for a bit...) Usage: symboliks [ options ] -A Run the emu and show the state of the machine for all found paths to the given address ''' watchaddr = None argv = e_cli.splitargs(line) try: opts,argv = getopt(argv, 'A:') except Exception as e: return self.do_help('symboliks') for opt,optarg in opts: if opt == '-A': watchaddr = self.parseExpression(optarg) va = self.parseExpression(argv[0]) fva = self.getFunction(va) import vivisect.symboliks as viv_symboliks import vivisect.symboliks.common as sym_common import vivisect.symboliks.effects as viv_sym_effects import vivisect.symboliks.analysis as vsym_analysis import vivisect.symboliks.archs.i386 as viv_sym_i386 symctx = vsym_analysis.getSymbolikAnalysisContext(self) #xlate = viv_sym_i386.i386SymbolikTranslator(self) #graph = viv_symboliks.getSymbolikGraph(self, fva, xlate) for emu, effects in symctx.getSymbolikPaths(fva): self.vprint('PATH %s' % ('='*60)) #esp = emu.solveExpression('esp', update=False) for eff in effects: eff.reduce(emu) if eff.efftype in (EFFTYPE_CONSTRAIN,EFFTYPE_CALLFUNC): self.vprint(str(eff)) #for reg in ['eax','ebx','ecx','edx','esi','edi','ebp','esp','eip']: #regobj = emu.getSymVariable(reg) #if regobj == None: #continue #regobj = regobj.reduce() #regval = regobj.solve(emu=emu) #if regval == emu.solveExpression(reg, update=False): #continue #self.vprint('%s: %s 0x%.8x' % (reg, regobj.reduce(), regobj.solve(emu))) for addrsym,valsym in list(emu._sym_mem.values()): addrsym = addrsym.reduce(emu=emu) valsym = valsym.reduce(emu=emu) if emu.isLocalMemory(addrsym): continue self.vprint('[ %s ] = %s' % (addrsym, valsym)) #print 'SPDELTA: %d' % (emu.solveExpression('esp')-esp) #print 'RETURN',emu.parseExpression('eax').reduce() self.vprint('RETURN',emu.getFunctionReturn().reduce())