def main(): buf = assemble_text(test_code, [("L_MAIN", 0)]) mdis = dis_engine(buf) disasm = mdis.dis_multibloc(0) ir = ir_a_x86_64(mdis.symbol_pool) for bbl in disasm: ir.add_bloc(bbl) symbols_init = {} for i, r in enumerate(all_regs_ids): symbols_init[r] = all_regs_ids_init[i] conds = find_goal(ir, 0, symbols_init, rax_is_one) if conds == None: print "Goal was not found" sys.exit(-1) solver = z3.Solver() for lval, rval in conds: z3_cond = Translator.to_language("z3").from_expr(lval) solver.add(z3_cond == int(rval.arg)) rslt = solver.check() if rslt == z3.sat: m = solver.model() for var in m: print "%s: %d" % (var.name(), m[var].as_long()) else: print "No solution" sys.exit(-1)
def test_ExprSlice_strcst(self): from miasm2.expression.expression import ExprInt, ExprOp from miasm2.ir.translators.translator import Translator translator_smt2 = Translator.to_language("smt2") args = [ExprInt(i, 32) for i in xrange(9)] self.assertEqual(translator_smt2.from_expr(args[0][1:2]), r'((_ extract 1 1) (_ bv0 32))') self.assertRaises(ValueError, args[0].__getitem__, slice(1, 7, 2))
def test_ExprOp_strcst(self): from miasm2.expression.expression import ExprInt, ExprOp from miasm2.ir.translators.translator import Translator translator_smt2 = Translator.to_language("smt2") args = [ExprInt(i, 32) for i in xrange(9)] self.assertEqual(translator_smt2.from_expr(ExprOp('|', *args[:2])), r'(bvor (_ bv0 32) (_ bv1 32))') self.assertEqual(translator_smt2.from_expr(ExprOp('-', *args[:2])), r'(bvsub (_ bv0 32) (_ bv1 32))') self.assertEqual(translator_smt2.from_expr(ExprOp('+', *args[:3])), r'(bvadd (bvadd (_ bv0 32) (_ bv1 32)) (_ bv2 32))') self.assertRaises(NotImplementedError, translator_smt2.from_expr, ExprOp('X', *args[:1]))
def from_ExprInt(self, expr): return "ExprInt(0x%x, %d)" % (int(expr), expr.size) def from_ExprCond(self, expr): return "ExprCond(%s, %s, %s)" % (self.from_expr( expr.cond), self.from_expr(expr.src1), self.from_expr(expr.src2)) def from_ExprSlice(self, expr): return "ExprSlice(%s, %d, %d)" % (self.from_expr( expr.arg), expr.start, expr.stop) def from_ExprOp(self, expr): return "ExprOp(%s, %s)" % (repr(expr.op), ", ".join( map(self.from_expr, expr.args))) def from_ExprCompose(self, expr): args = ["%s" % self.from_expr(arg) for arg in expr.args] return "ExprCompose(%s)" % ", ".join(args) def from_ExprAff(self, expr): return "ExprAff(%s, %s)" % (self.from_expr( expr.dst), self.from_expr(expr.src)) def from_ExprMem(self, expr): return "ExprMem(%s, size=%d)" % (self.from_expr(expr.arg), expr.size) # Register the class Translator.register(TranslatorMiasm)
""" ret = "" ret += "(set-logic {})\n".format(logic) # define bit vectors for bv in self._bitvectors: size = self._bitvectors[bv] ret += "{}\n".format(declare_bv(bv, size)) # define memory arrays for size in self._mem.mems: mem = self._mem.mems[size] ret += "{}\n".format(declare_array(mem, bit_vec(size), bit_vec(8))) # merge SMT2 expressions for expr in exprs: ret += expr + "\n" # define action ret += "(check-sat)\n" # enable model generation if model: ret += "(get-model)\n" return ret # Register the class Translator.register(TranslatorSMT2)
self._size2mask(expr.stop - expr.start) ) def from_ExprCompose(self, expr): out = [] # XXX check mask for 64 bit & 32 bit compat if expr.size in [8, 16, 32, 64, 128]: size = expr.size else: # Uncommon expression size size = expr.size next_power = 1 while next_power <= size: next_power <<= 1 size = next_power dst_cast = "uint%d_t" % size for index, arg in expr.iter_args(): out.append("(((%s)(%s & %s)) << %d)" % ( dst_cast, self.from_expr(arg), self._size2mask(arg.size), index) ) out = ' | '.join(out) return '(' + out + ')' # Register the class Translator.register(TranslatorC)
# @16[EAX+2] . @16[EAX] z3.Concat(mem.get(eax+2, 16), mem.get(eax, 16))) # -------------------------------------------------------------------------- ax = z3.BitVec('AX', 16) assert not equiv( # @16[EAX] with EAX = ZeroExtend(AX) mem.get(z3.ZeroExt(16, ax), 16), # @16[AX] mem.get(ax, 16)) # TranslatorZ3 tests # -------------------------------------------------------------------------- e = ExprId('x', 32) ez3 = Translator.to_language('z3').from_expr(e) z3_e = z3.BitVec('x', 32) assert equiv(ez3, z3_e) # -------------------------------------------------------------------------- four = ExprInt(4, 32) five = ExprInt(5, 32) e2 = (e + five + four) * five ez3 = Translator.to_language('z3').from_expr(e2) z3_four = z3.BitVecVal(4, 32) z3_five = z3.BitVecVal(5, 32) z3_e2 = (z3_e + z3_five + z3_four) * z3_five assert equiv(ez3, z3_e2)
# @16[EAX+2] . @16[EAX] z3.Concat(mem.get(eax+2, 16), mem.get(eax, 16))) # -------------------------------------------------------------------------- ax = z3.BitVec('AX', 16) assert not equiv( # @16[EAX] with EAX = ZeroExtend(AX) mem.get(z3.ZeroExt(16, ax), 16), # @16[AX] mem.get(ax, 16)) # TranslatorZ3 tests # -------------------------------------------------------------------------- e = ExprId('x', 32) ez3 = Translator.to_language('z3').from_expr(e) z3_e = z3.BitVec('x', 32) assert equiv(ez3, z3_e) # -------------------------------------------------------------------------- four = ExprInt32(4) five = ExprInt32(5) e2 = (e + five + four) * five ez3 = Translator.to_language('z3').from_expr(e2) z3_four = z3.BitVecVal(4, 32) z3_five = z3.BitVecVal(5, 32) z3_e2 = (z3_e + z3_five + z3_four) * z3_five assert equiv(ez3, z3_e2)
dst_cast = "uint%d_t" % size for index, arg in expr.iter_args(): out.append("(((%s)(%s & %s)) << %d)" % (dst_cast, self.from_expr(arg), self._size2mask(arg.size), index)) out = ' | '.join(out) return '(' + out + ')' else: # Convert all parts to bignum args = [] for index, arg in expr.iter_args(): arg_str = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: arg_str = '((%s) & %s)' % (arg_str, self._size2mask(arg.size)) arg_str = 'bignum_from_uint64(%s)' % arg_str else: arg_str = 'bignum_mask(%s, %d)' % (arg_str, arg.size) arg_str = 'bignum_lshift(%s, %d)' % (arg_str, index) args.append(arg_str) out = args.pop() while args: arg = args.pop() out = "bignum_or(%s, %s)" % (out, arg) return out # Register the class Translator.register(TranslatorC)
if len(expr.args) == 1: return "((%s %s) & 0x%x)" % (expr.op, args[0], (1 << expr.size) - 1) else: return "((%s) & 0x%x)" % ((" %s " % expr.op).join(args), (1 << expr.size) - 1) elif expr.op == "parity": return "(%s & 0x1)" % self.from_expr(expr.args[0]) elif expr.op in ["<<<", ">>>"]: amount_raw = expr.args[1] amount = expr.args[1] % ExprInt(amount_raw.size, expr.size) amount_inv = ExprInt(expr.size, expr.size) - amount if expr.op == "<<<": amount, amount_inv = amount_inv, amount part1 = "(%s >> %s)" % (self.from_expr( expr.args[0]), self.from_expr(amount)) part2 = "(%s << %s)" % (self.from_expr( expr.args[0]), self.from_expr(amount_inv)) return "((%s | %s) &0x%x)" % (part1, part2, int(expr.mask)) raise NotImplementedError("Unknown operator: %s" % expr.op) def from_ExprAff(self, expr): return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src))) # Register the class Translator.register(TranslatorPython)
mem.get(eax, 32), # @16[EAX+2] . @16[EAX] z3.Concat(mem.get(eax + 2, 16), mem.get(eax, 16))) # -------------------------------------------------------------------------- ax = z3.BitVec('AX', 16) assert not equiv( # @16[EAX] with EAX = ZeroExtend(AX) mem.get(z3.ZeroExt(16, ax), 16), # @16[AX] mem.get(ax, 16)) # TranslatorZ3 tests # -------------------------------------------------------------------------- e = ExprId('x', 32) ez3 = Translator.to_language('z3').from_expr(e) z3_e = z3.BitVec('x', 32) assert equiv(ez3, z3_e) # -------------------------------------------------------------------------- four = ExprInt32(4) five = ExprInt32(5) e2 = (e + five + four) * five ez3 = Translator.to_language('z3').from_expr(e2) z3_four = z3.BitVecVal(4, 32) z3_five = z3.BitVecVal(5, 32) z3_e2 = (z3_e + z3_five + z3_four) * z3_five assert equiv(ez3, z3_e2)
return "((%s %s) & 0x%x)" % (expr.op, args[0], (1 << expr.size) - 1) else: return "((%s) & 0x%x)" % ((" %s " % expr.op).join(args), (1 << expr.size) - 1) elif expr.op == "parity": return "(%s & 0x1)" % self.from_expr(expr.args[0]) elif expr.op in ["<<<", ">>>"]: amount_raw = expr.args[1] amount = expr.args[1] % ExprInt(amount_raw.size, expr.size) amount_inv = ExprInt(expr.size, expr.size) - amount if expr.op == "<<<": amount, amount_inv = amount_inv, amount part1 = "(%s >> %s)"% (self.from_expr(expr.args[0]), self.from_expr(amount)) part2 = "(%s << %s)"% (self.from_expr(expr.args[0]), self.from_expr(amount_inv)) return "((%s | %s) &0x%x)" % (part1, part2, int(expr.mask)) raise NotImplementedError("Unknown operator: %s" % expr.op) def from_ExprAff(self, expr): return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src))) # Register the class Translator.register(TranslatorPython)
@classmethod def from_expr(cls, expr, endianness="<"): # This mess is just to handle cache and Z3Mem instance management # Might be improved in the future del_cache = False del_mem = False if cls._cache is None: cls._cache = {} del_cache = True if cls._mem is None: cls._mem = Z3Mem(endianness) del_mem = True try: if expr in cls._cache: return cls._cache[expr] else: ret = super(TranslatorZ3, cls).from_expr(expr) cls._cache[expr] = ret return ret finally: # Clean cache and Z3Mem if this call is the root call if del_cache: cls._cache = None if del_mem: cls._mem = None # Register the class Translator.register(TranslatorZ3)
mem.get(eax, 32), # @16[EAX+2] . @16[EAX] z3.Concat(mem.get(eax + 2, 16), mem.get(eax, 16))) # -------------------------------------------------------------------------- ax = z3.BitVec('AX', 16) assert not equiv( # @16[EAX] with EAX = ZeroExtend(AX) mem.get(z3.ZeroExt(16, ax), 16), # @16[AX] mem.get(ax, 16)) # TranslatorZ3 tests # -------------------------------------------------------------------------- e = ExprId('x', 32) ez3 = Translator.to_language('z3').from_expr(e) z3_e = z3.BitVec('x', 32) assert equiv(ez3, z3_e) # -------------------------------------------------------------------------- four = ExprInt(4, 32) five = ExprInt(5, 32) e2 = (e + five + four) * five ez3 = Translator.to_language('z3').from_expr(e2) z3_four = z3.BitVecVal(4, 32) z3_five = z3.BitVecVal(5, 32) z3_e2 = (z3_e + z3_five + z3_four) * z3_five assert equiv(ez3, z3_e2)
states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items()))) elif addr == ret_addr: print 'Return address reached' continue elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination") if __name__ == '__main__': translator_smt2 = Translator.to_language("smt2") data = open(args[0]).read() bs = bin_stream_str(data) mdis = dis_engine(bs) addr = int(options.address, 16) ir_arch = machine.ir(mdis.loc_db) ircfg = ir_arch.new_ircfg() symbexec = SymbolicExecutionEngine(ir_arch) asmcfg, loc_db = parse_asm.parse_txt(machine.mn, 32, ''' init: PUSH argv
def from_ExprCond(self, expr): return "ExprCond(%s, %s, %s)" % (self.from_expr(expr.cond), self.from_expr(expr.src1), self.from_expr(expr.src2)) def from_ExprSlice(self, expr): return "ExprSlice(%s, %d, %d)" % (self.from_expr(expr.arg), expr.start, expr.stop) def from_ExprOp(self, expr): return "ExprOp(%s, %s)" % (repr(expr.op), ", ".join(map(self.from_expr, expr.args))) def from_ExprCompose(self, expr): args = ["(%s, %d, %d)" % (self.from_expr(arg), start, stop) for arg, start, stop in expr.args] return "ExprCompose([%s])" % ", ".join(args) def from_ExprAff(self, expr): return "ExprAff(%s, %s)" % (self.from_expr(expr.dst), self.from_expr(expr.src)) def from_ExprMem(self, expr): return "ExprMem(%s, size=%d)" % (self.from_expr(expr.arg), expr.size) # Register the class Translator.register(TranslatorMiasm)
for i in xrange(8): res = res ^ z3.Extract(i, i, arg) elif expr.op == '-': res = -res elif expr.op == "bsf": size = expr.size src = res res = z3.If((src & (1 << (size - 1))) != 0, size - 1, src) for i in xrange(size - 2, -1, -1): res = z3.If((src & (1 << i)) != 0, i, res) elif expr.op == "bsr": size = expr.size src = res res = z3.If((src & 1) != 0, 0, src) for i in xrange(size - 1, 0, -1): index = - i % size res = z3.If((src & (1 << index)) != 0, index, res) else: raise NotImplementedError("Unsupported OP yet: %s" % expr.op) return res def from_ExprAff(self, expr): src = self.from_expr(expr.src) dst = self.from_expr(expr.dst) return (src == dst) # Register the class Translator.register(TranslatorZ3)
tuple(list(conds) + cond_group_b.items()))) elif addr == ret_addr: print 'Return address reached' continue elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination") if __name__ == '__main__': translator_smt2 = Translator.to_language("smt2") addr = int(options.address, 16) cont = Container.from_stream(open(args[0])) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ir_arch = machine.ir(mdis.loc_db) ircfg = ir_arch.new_ircfg() symbexec = SymbolicExecutionEngine(ir_arch) asmcfg, loc_db = parse_asm.parse_txt(machine.mn, 32, ''' init: PUSH argv PUSH argc