Пример #1
0
def offs_expr_const (addr_expr, sp_expr, rep, hyps, extra_defs = {},
		cache = None):
	"""if the offset between a stack addr and the initial stack pointer
	is a constant offset, try to compute it."""
	addr_x = solver.parse_s_expression (addr_expr)
	sp_x = solver.parse_s_expression (sp_expr)
	vs = [(addr_x, 1), (sp_x, -1)]
	const = 0

	while True:
		start_vs = list (vs)
		new_vs = {}
		for (x, mult) in vs:
			(var, c) = split_sum_s_expr (x, rep.solv, extra_defs)
			for v in var:
				new_vs.setdefault (v, 0)
				new_vs[v] += var[v] * mult
			const += c * mult
		vs = [(x, n) for (x, n) in new_vs.iteritems () if n != 0]
		if not vs:
			return const
		vs = [(simplify_expr_whyps (x, rep, hyps,
				cache = cache, extra_defs = extra_defs), n)
			for (x, n) in vs]
		if sorted (vs) == sorted (start_vs):
			trace ('offs_expr_const: not const')
			trace ('%s - %s' % (addr_expr, sp_expr))
			trace (str (vs))
			last_10_non_const.append ((addr_expr, sp_expr, vs))
			del last_10_non_const[:-10]
			return None
Пример #2
0
def investigate_funcall_pair(rep,
                             m,
                             l_n_vc,
                             r_n_vc,
                             verbose=False,
                             verbose_imp=False,
                             simplify=True):

    l_nm = "%s @ %s" % (rep.p.nodes[l_n_vc[0]].fname,
                        rep.node_count_name(l_n_vc))
    r_nm = "%s @ %s" % (rep.p.nodes[r_n_vc[0]].fname,
                        rep.node_count_name(r_n_vc))
    print 'Attempt match %s -> %s' % (l_nm, r_nm)
    imp = rep.get_func_assert(l_n_vc, r_n_vc)
    imp = logic.weaken_assert(imp)
    if verbose_imp:
        imp2 = solver.smt_expr(imp, {}, rep.solv)
        if simplify:
            imp2 = simplify_sexp(imp2, rep, m)
        print imp2
    assert imp.is_op('Implies'), imp
    [pred, concl] = imp.vals
    pred = solver.smt_expr(pred, {}, rep.solv)
    pred = solver.parse_s_expression(pred)
    bits = solver.split_hyp_sexpr(pred, [])
    xs = [eval_model_bool(m, v) for v in bits]
    print '  %s' % xs
    for (v, bit) in zip(xs, bits):
        if v != True or verbose:
            print '  %s: %s' % (v, bit)
            if bit[0] == 'word32-eq':
                vs = [model_sx_word(m, x) for x in bit[1:]]
                print '    (%s = %s)' % tuple(vs)
Пример #3
0
def investigate_funcall_pair(rep, m, l_n_vc, r_n_vc, verbose=False, verbose_imp=False, simplify=True):

    l_nm = "%s @ %s" % (rep.p.nodes[l_n_vc[0]].fname, rep.node_count_name(l_n_vc))
    r_nm = "%s @ %s" % (rep.p.nodes[r_n_vc[0]].fname, rep.node_count_name(r_n_vc))
    print "Attempt match %s -> %s" % (l_nm, r_nm)
    imp = rep.get_func_assert(l_n_vc, r_n_vc)
    if verbose_imp:
        imp2 = logic.weaken_assert(imp)
        imp2 = solver.smt_expr(imp2, {}, rep.solv)
        if simplify:
            imp2 = simplify_sexp(imp2, rep, m)
        print imp2
    assert imp.is_op("Implies"), imp
    [pred, concl] = imp.vals
    pred = solver.smt_expr(pred, {}, rep.solv)
    pred = solver.parse_s_expression(pred)
    bits = solver.split_hyp_sexpr(pred, [])
    xs = [eval_model_bool(m, v) for v in bits]
    print "  %s" % xs
    for (v, bit) in zip(xs, bits):
        if v != True or verbose:
            print "  %s: %s" % (v, bit)
            if bit[0] == "word32-eq":
                vs = [model_sx_word(m, x) for x in bit[1:]]
                print "    (%s = %s)" % tuple(vs)
Пример #4
0
 def eval(expr, env):
     try:
         s = solver.smt_expr(expr, env, rep.solv)
         s_x = solver.parse_s_expression(s)
         ev = search.eval_model(m, s_x)
         return (s, solver.smt_expr(ev, {}, None))
     except solver.EnvMiss, e:
         return None
Пример #5
0
def get_extra_sp_defs (rep, tag):
	"""all functions will keep the stack pointer equal, whether they have
	pairing partners or not. add these extra defs/equalities for the
	purposes of stack depth analysis."""
	# FIXME how to parametrise this?
	sp = mk_var ('r13', syntax.word32T)
	defs = {}
	items = [(n_vc, x) for (n_vc, x) in rep.funcs.iteritems ()
		if logic.is_int (n_vc[0])]
	for ((n, vc), (inputs, outputs, _)) in items:
		if rep.p.node_tags[n][0] == tag:
			inp_sp = solver.smt_expr (sp, inputs, rep.solv)
			inp_sp = solver.parse_s_expression (inp_sp)
			out_sp = solver.smt_expr (sp, outputs, rep.solv)
			out_sp = solver.parse_s_expression (out_sp)
			if inp_sp != out_sp:
				defs[out_sp] = inp_sp
	return defs
Пример #6
0
def eval_model_bool(m, x):
    if hasattr(x, "typ"):
        x = solver.smt_expr(x, {}, None)
        x = solver.parse_s_expression(x)
    try:
        r = search.eval_model(m, x)
        assert r in [syntax.true_term, syntax.false_term], r
        return r == syntax.true_term
    except:
        return "EXCEPT"
Пример #7
0
def eval_model_bool(m, x):
    if hasattr(x, 'typ'):
        x = solver.smt_expr(x, {}, None)
        x = solver.parse_s_expression(x)
    try:
        r = search.eval_model(m, x)
        assert r in [syntax.true_term, syntax.false_term], r
        return r == syntax.true_term
    except:
        return 'EXCEPT'
Пример #8
0
def offs_expr_const(addr_expr,
                    sp_expr,
                    rep,
                    hyps,
                    extra_defs={},
                    cache=None,
                    typ=syntax.word32T):
    """if the offset between a stack addr and the initial stack pointer
	is a constant offset, try to compute it."""
    addr_x = solver.parse_s_expression(addr_expr)
    sp_x = solver.parse_s_expression(sp_expr)
    vs = [(addr_x, 1), (sp_x, -1)]
    const = 0

    while True:
        start_vs = list(vs)
        new_vs = {}
        for (x, mult) in vs:
            (var, c) = split_sum_s_expr(x, rep.solv, extra_defs, typ=typ)
            for v in var:
                new_vs.setdefault(v, 0)
                new_vs[v] += var[v] * mult
            const += c * mult
        vs = [(x, n) for (x, n) in new_vs.iteritems() if n % (2**typ.num) != 0]
        if not vs:
            return const
        vs = [(simplify_expr_whyps(x,
                                   rep,
                                   hyps,
                                   cache=cache,
                                   extra_defs=extra_defs), n) for (x, n) in vs]
        if sorted(vs) == sorted(start_vs):
            pass  # vs = split_merge_ite_sum_sexpr (vs)
        if sorted(vs) == sorted(start_vs):
            trace('offs_expr_const: not const')
            trace('%s - %s' % (addr_expr, sp_expr))
            trace(str(vs))
            trace(str(hyps))
            last_10_non_const.append((addr_expr, sp_expr, vs, hyps))
            del last_10_non_const[:-10]
            return None
Пример #9
0
 def fetch((n, vc)):
     if n in vds and [(nm, typ)
                      for (nm, typ) in vs if (nm, typ) not in vds[n]]:
         return None
     try:
         (_, env) = rep.get_node_pc_env((n, vc), tag)
         s = solver.smt_expr(v, env, rep.solv)
         s_x = solver.parse_s_expression(s)
         ev = search.eval_model(m, s_x)
         return (s, solver.smt_expr(ev, {}, None))
     except solver.EnvMiss, e:
         return None
Пример #10
0
def get_extra_sp_defs(rep, tag):
    """add extra defs/equalities about stack pointer for the
	purposes of stack depth analysis."""
    # FIXME how to parametrise this?
    sp = mk_var('r13', syntax.word32T)
    defs = {}

    fcalls = [
        n_vc for n_vc in rep.funcs if logic.is_int(n_vc[0])
        if rep.p.node_tags[n_vc[0]][0] == tag
        if preserves_sp(rep.p.nodes[n_vc[0]].fname)
    ]
    for (n, vc) in fcalls:
        (inputs, outputs, _) = rep.funcs[(n, vc)]
        if (sp.name, sp.typ) not in outputs:
            continue
        inp_sp = solver.smt_expr(sp, inputs, rep.solv)
        inp_sp = solver.parse_s_expression(inp_sp)
        out_sp = solver.smt_expr(sp, outputs, rep.solv)
        out_sp = solver.parse_s_expression(out_sp)
        if inp_sp != out_sp:
            defs[out_sp] = inp_sp
    return defs
Пример #11
0
def simplify_sexp(smt_xp, rep, m, flatten=True):
    if type(smt_xp) == str:
        smt_xp = solver.parse_s_expression(smt_xp)
    if smt_xp[0] == "ite":
        (_, c, x, y) = smt_xp
        if eval_model_bool(m, c):
            return simplify_sexp(x, rep, m, flatten)
        else:
            return simplify_sexp(y, rep, m, flatten)
    if type(smt_xp) == tuple:
        smt_xp = tuple([simplify_sexp(x, rep, m, False) for x in smt_xp])
    if flatten:
        return solver.flat_s_expression(smt_xp)
    else:
        return smt_xp
Пример #12
0
def simplify_sexp(smt_xp, rep, m, flatten=True):
    if type(smt_xp) == str:
        smt_xp = solver.parse_s_expression(smt_xp)
    if smt_xp[0] == 'ite':
        (_, c, x, y) = smt_xp
        if eval_model_bool(m, c):
            return simplify_sexp(x, rep, m, flatten)
        else:
            return simplify_sexp(y, rep, m, flatten)
    if type(smt_xp) == tuple:
        smt_xp = tuple([simplify_sexp(x, rep, m, False) for x in smt_xp])
    if flatten:
        return solver.flat_s_expression(smt_xp)
    else:
        return smt_xp
Пример #13
0
def func_assert_premise_strength(rep, m, l_n_vc, r_n_vc):
    imp = rep.get_func_assert(l_n_vc, r_n_vc)
    assert imp.is_op('Implies'), imp
    [pred, concl] = imp.vals
    pred = solver.smt_expr(pred, {}, rep.solv)
    pred = solver.parse_s_expression(pred)
    bits = solver.split_hyp_sexpr(pred, [])
    assert bits, bits
    scores = []
    for bit in bits:
        try:
            res = eval_model_bool(m, bit)
            if res:
                scores.append(1.0)
            else:
                scores.append(0.0)
        except solver.EnvMiss, e:
            scores.append(0.5)
        except AssertionError, e:
            scores.append(0.5)
Пример #14
0
def unfold_defs(defs, hyp, depthlimit=-1):
    return solver.flat_s_expression(unfold_defs_sexpr(defs, solver.parse_s_expression(hyp), depthlimit))
Пример #15
0
def eval_model_expr (m, solv, v):
	s = solver.smt_expr (v, {}, solv)
	s_x = solver.parse_s_expression (s)

	return eval_model (m, s_x)
Пример #16
0
def unfold_defs(defs, hyp, depthlimit=-1):
    return solver.flat_s_expression(
        unfold_defs_sexpr(defs, solver.parse_s_expression(hyp), depthlimit))