def emul(self, ctx=None, step=False): # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) solver = z3.Solver() symb_exec = symbexec(self._ira, ctx_init) history = self.history[::-1] history_size = len(history) translator = Translator.to_language("z3") size = self._ira.IRDst.size for hist_nb, label in enumerate(history): irb = self.irblock_slice(self._ira.blocs[label]) # Emul the block and get back destination dst = symb_exec.emulbloc(irb, step=step) # Add constraint if hist_nb + 1 < history_size: next_label = history[hist_nb + 1] expected = symb_exec.eval_expr(m2_expr.ExprId(next_label, size)) solver.add( self._gen_path_constraints(translator, dst, expected)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return {element: symb_exec.eval_expr(element) for element in self.inputs}
def __init__(self, expr): "@expr: Expr instance" # Init self.languages = list(Translator.available_languages()) self.expr = expr # Initial translation text = Translator.to_language(self.languages[0]).from_expr(self.expr) # Create the Form idaapi.Form.__init__( self, r"""STARTITEM 0 Python Expression {FormChangeCb} <Language:{cbLanguage}> <Translation:{result}> """, { 'result': idaapi.Form.MultiLineTextControl(text=text, flags=translatorForm.flags), 'cbLanguage': idaapi.Form.DropdownListControl( items=self.languages, readonly=True, selval=0), 'FormChangeCb': idaapi.Form.FormChangeCb(self.OnFormChange), })
def emul(self, ir_arch, ctx=None, step=False): # Init ctx_init = {} if ctx is not None: ctx_init.update(ctx) solver = z3.Solver() symb_exec = SymbolicExecutionEngine(ir_arch, ctx_init) history = self.history[::-1] history_size = len(history) translator = Translator.to_language("z3") size = self._ircfg.IRDst.size for hist_nb, loc_key in enumerate(history, 1): if hist_nb == history_size and loc_key == self.initial_state.loc_key: line_nb = self.initial_state.line_nb else: line_nb = None irb = self.irblock_slice(self._ircfg.blocks[loc_key], line_nb) # Emul the block and get back destination dst = symb_exec.eval_updt_irblock(irb, step=step) # Add constraint if hist_nb < history_size: next_loc_key = history[hist_nb] expected = symb_exec.eval_expr(ExprLoc(next_loc_key, size)) solver.add(self._gen_path_constraints(translator, dst, expected)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return {element: symb_exec.eval_expr(element) for element in self.inputs}
def emul(self, ctx=None, step=False): # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) solver = z3.Solver() symb_exec = SymbolicExecutionEngine(self._ira, ctx_init) history = self.history[::-1] history_size = len(history) translator = Translator.to_language("z3") size = self._ira.IRDst.size for hist_nb, label in enumerate(history, 1): if hist_nb == history_size and label == self.initial_state.label: line_nb = self.initial_state.line_nb else: line_nb = None irb = self.irblock_slice(self._ira.blocks[label], line_nb) # Emul the block and get back destination dst = symb_exec.emulbloc(irb, step=step) # Add constraint if hist_nb < history_size: next_label = history[hist_nb] expected = symb_exec.eval_expr(m2_expr.ExprId(next_label, size)) solver.add( self._gen_path_constraints(translator, dst, expected)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return {element: symb_exec.eval_expr(element) for element in self.inputs}
def __init__(self, expr): "@expr: Expr instance" # Init self.languages = list(Translator.available_languages()) self.expr = expr # Initial translation text = Translator.to_language(self.languages[0]).from_expr(self.expr) # Create the Form idaapi.Form.__init__(self, r"""STARTITEM 0 Python Expression {FormChangeCb} <Language:{cbLanguage}> <Translation:{result}> """, { 'result': idaapi.Form.MultiLineTextControl(text=text, flags=translatorForm.flags), 'cbLanguage': idaapi.Form.DropdownListControl( items=self.languages, readonly=True, selval=0), 'FormChangeCb': idaapi.Form.FormChangeCb(self.OnFormChange), })
def test_ExprOp_toC(self): from miasm2.expression.expression import ExprInt32, ExprOp from miasm2.ir.translators.C import Translator args = [ExprInt32(i) for i in xrange(9)] translator = Translator.to_language("C") # Unary operators self.translationTest( ExprOp('parity', *args[:1]), r'parity(0x0&0xffffffff)') self.translationTest( ExprOp('!', *args[:1]), r'(~ 0x0)&0xffffffff') self.translationTest( ExprOp('hex2bcd', *args[:1]), r'hex2bcd_32(0x0)') self.translationTest(ExprOp('fabs', *args[:1]), r'fabs(0x0)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:1])) # Binary operators self.translationTest( ExprOp('==', *args[:2]), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)') self.translationTest( ExprOp('%', *args[:2]), r'(((0x0&0xffffffff)%(0x1&0xffffffff))&0xffffffff)') self.translationTest( ExprOp('-', *args[:2]), r'(((0x0&0xffffffff) - (0x1&0xffffffff))&0xffffffff)') self.translationTest( ExprOp('bsr', *args[:1]), r'x86_bsr(0x0, 0x20)') self.translationTest( ExprOp('cpuid0', *args[:2]), r'cpuid0(0x0, 0x1)') self.translationTest( ExprOp('fcom0', *args[:2]), r'fcom0(0x0, 0x1)') self.translationTest( ExprOp('fadd', *args[:2]), r'fadd(0x0, 0x1)') self.translationTest( ExprOp('segm', *args[:2]), r'segm2addr(jitcpu, 0x0, 0x1)') self.translationTest( ExprOp('imod', *args[:2]), r'imod32((vm_cpu_t*)jitcpu->cpu, 0x0, 0x1)') self.translationTest( ExprOp('bcdadd', *args[:2]), r'bcdadd_32(0x0, 0x1)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:2])) # Ternary operators self.translationTest( ExprOp('div8', *args[:3]), r'(div_op(32, 0x0, 0x1, 0x2) &0xffffffff)') # Other cases self.translationTest( ExprOp('+', *args[:3]), r'(((0x0&0xffffffff)+(0x1&0xffffffff)+(0x2&0xffffffff))&0xffffffff)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:3]))
def test_ExprOp_toC(self): from miasm2.expression.expression import ExprInt32, ExprOp from miasm2.ir.translators.C import Translator args = [ExprInt32(i) for i in xrange(9)] translator = Translator.to_language("C") # Unary operators self.translationTest( ExprOp('parity', *args[:1]), r'parity(0x0&0xffffffff)') self.translationTest( ExprOp('!', *args[:1]), r'(~ 0x0)&0xffffffff') self.translationTest( ExprOp('hex2bcd', *args[:1]), r'hex2bcd_32(0x0)') self.translationTest(ExprOp('fabs', *args[:1]), r'fabs(0x0)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:1])) # Binary operators self.translationTest( ExprOp('==', *args[:2]), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)') self.translationTest( ExprOp('%', *args[:2]), r'(((0x0&0xffffffff)%(0x1&0xffffffff))&0xffffffff)') self.translationTest( ExprOp('-', *args[:2]), r'(((0x0&0xffffffff) - (0x1&0xffffffff))&0xffffffff)') self.translationTest( ExprOp('bsr', *args[:1]), r'x86_bsr(0x0, 0x20)') self.translationTest( ExprOp('cpuid0', *args[:2]), r'cpuid0(0x0, 0x1)') self.translationTest( ExprOp('fcom0', *args[:2]), r'fcom0(0x0, 0x1)') self.translationTest( ExprOp('fadd', *args[:2]), r'fadd(0x0, 0x1)') self.translationTest( ExprOp('segm', *args[:2]), r'segm2addr(jitcpu, 0x0, 0x1)') self.translationTest( ExprOp('imod', *args[:2]), r'imod32(jitcpu, 0x0, 0x1)') self.translationTest( ExprOp('bcdadd', *args[:2]), r'bcdadd_32(0x0, 0x1)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:2])) # Ternary operators self.translationTest( ExprOp('div8', *args[:3]), r'(div_op(32, 0x0, 0x1, 0x2) &0xffffffff)') # Other cases self.translationTest( ExprOp('+', *args[:3]), r'(((0x0&0xffffffff)+(0x1&0xffffffff)+(0x2&0xffffffff))&0xffffffff)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:3]))
def __init__(self, machine, produce_solution=True, **kwargs): """Init a DSEPathConstraint @machine: Machine of the targeted architecture instance @produce_solution: (optional) if set, new solutions will be computed""" super(DSEPathConstraint, self).__init__(machine, **kwargs) # Dependency check assert z3 is not None # Init PathConstraint specifics structures self.produce_solution = produce_solution self.cur_solver = z3.Solver() self.new_solutions = {} # destination -> set of model self.z3_trans = Translator.to_language("z3")
def test_ExprOp_toC(self): from miasm2.expression.expression import ExprInt, ExprOp from miasm2.ir.translators.C import Translator args = [ExprInt(i, 32) for i in xrange(9)] translator = Translator.to_language("C") # Unary operators self.translationTest(ExprOp('parity', *args[:1]), r'parity(0x0&0xffffffff)') self.translationTest(ExprOp('!', *args[:1]), r'(~ 0x0)&0xffffffff') self.translationTest(ExprOp('hex2bcd', *args[:1]), r'hex2bcd_32(0x0)') self.translationTest(ExprOp('fabs', *args[:1]), r'fabs(0x0)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:1])) # Binary operators self.translationTest(ExprOp(TOK_EQUAL, *args[:2]), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)') self.translationTest( ExprOp('%', *args[:2]), r'(((0x0&0xffffffff)%(0x1&0xffffffff))&0xffffffff)') self.translationTest( ExprOp('-', *args[:2]), r'(((0x0&0xffffffff) - (0x1&0xffffffff))&0xffffffff)') self.translationTest(ExprOp('cntleadzeros', *args[:1]), r'cntleadzeros(0x0, 0x20)') self.translationTest(ExprOp('x86_cpuid', *args[:2]), r'x86_cpuid(0x0, 0x1)') self.translationTest(ExprOp('fcom0', *args[:2]), r'fcom0(0x0, 0x1)') self.translationTest(ExprOp('fadd', *args[:2]), r'fadd(0x0, 0x1)') self.translationTest(ExprOp('segm', *args[:2]), r'segm2addr(jitcpu, 0x0, 0x1)') self.translationTest(ExprOp('imod', *args[:2]), r'imod32((vm_cpu_t*)jitcpu->cpu, 0x0, 0x1)') self.translationTest(ExprOp('bcdadd', *args[:2]), r'bcdadd_32(0x0, 0x1)') self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:2])) # Other cases self.translationTest( ExprOp('+', *args[:3]), r'(((0x0&0xffffffff)+(0x1&0xffffffff)+(0x2&0xffffffff))&0xffffffff)' ) self.assertRaises(NotImplementedError, translator.from_expr, ExprOp('X', *args[:3]))
def OnFormChange(self, fid): if fid == self.cbLanguage.id: # Display the Field (may be hide) self.ShowField(self.result, True) # Translate the expression dest_lang = self.languages[self.GetControlValue(self.cbLanguage)] try: text = Translator.to_language(dest_lang).from_expr(self.expr) except Exception, error: self.ShowField(self.result, False) return -1 # Update the form self.SetControlValue(self.result, idaapi.textctrl_info_t(text=str(text), flags=translatorForm.flags))
def OnFormChange(self, fid): if fid == self.cbLanguage.id: # Display the Field (may be hide) self.ShowField(self.result, True) # Translate the expression dest_lang = self.languages[self.GetControlValue(self.cbLanguage)] try: text = Translator.to_language(dest_lang).from_expr(self.expr) except Exception, error: self.ShowField(self.result, False) return -1 # Update the form self.SetControlValue( self.result, idaapi.textctrl_info_t(text=str(text), flags=translatorForm.flags))
def __init__(self, machine, produce_solution=PRODUCE_SOLUTION_CODE_COV, known_solutions=None, **kwargs): """Init a DSEPathConstraint @machine: Machine of the targeted architecture instance @produce_solution: (optional) if set, new solutions will be computed""" super(DSEPathConstraint, self).__init__(machine, **kwargs) # Dependency check assert z3 is not None # Init PathConstraint specifics structures self.cur_solver = z3.Solver() self.new_solutions = {} # solution identifier -> solution's model self._known_solutions = set() # set of solution identifiers self.z3_trans = Translator.to_language("z3") self._produce_solution_strategy = produce_solution self._previous_addr = None self._history = None if produce_solution == self.PRODUCE_SOLUTION_PATH_COV: self._history = [] # List of addresses in the current path
def emul(self, ctx=None, step=False): # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) depnodes = self.relevant_nodes solver = z3.Solver() symb_exec = symbexec(self._ira, ctx_init) temp_label = asm_label("Temp") history = self.relevant_labels[::-1] history_size = len(history) for hist_nb, label in enumerate(history): # Build block with relevant lines only affected_lines = set(depnode.line_nb for depnode in depnodes if depnode.label == label) irs = self._ira.blocs[label].irs affects = [] for line_nb in sorted(affected_lines): affects.append(irs[line_nb]) # Emul the block and get back destination dst = symb_exec.emulbloc(irbloc(temp_label, affects), step=step) # Add constraint if hist_nb + 1 < history_size: next_label = history[hist_nb + 1] expected = symb_exec.eval_expr(m2_expr.ExprId(next_label, 32)) constraint = m2_expr.ExprAff(dst, expected) solver.add(Translator.to_language("z3").from_expr(constraint)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return { depnode.element: symb_exec.symbols[depnode.element] for depnode in self.input }
def emul(self, ctx=None, step=False): # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) depnodes = self.relevant_nodes solver = z3.Solver() sb = symbexec(self._ira, ctx_init) temp_label = asm_label("Temp") history = self.relevant_labels[::-1] history_size = len(history) for hist_nb, label in enumerate(history): # Build block with relevant lines only affected_lines = set(depnode.line_nb for depnode in depnodes if depnode.label == label) irs = self._ira.blocs[label].irs affects = [] for line_nb in sorted(affected_lines): affects.append(irs[line_nb]) # Emul the block and get back destination dst = sb.emulbloc(irbloc(temp_label, affects), step=step) # Add constraint if hist_nb + 1 < history_size: next_label = history[hist_nb + 1] expected = sb.eval_expr(m2_expr.ExprId(next_label, 32)) constraint = m2_expr.ExprAff(dst, expected) solver.add(Translator.to_language("z3").from_expr(constraint)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return {depnode.element: sb.symbols[depnode.element] for depnode in self.input}
class ExprRandom_OpSubRange(ExprRandom): operations_by_args_number = {1: ["-"], 2: ["<<", ">>",], "2+": ["+", "*", "&", "|", "^"], } print "[+] Compute a random expression:" expr = ExprRandom_OpSubRange.get(depth=8) print "-> %s" % expr print target_exprs = {} for lang in Translator.available_languages(): target_exprs[lang] = Translator.to_language(lang).from_expr(expr) for target_lang, target_expr in target_exprs.iteritems(): print "[+] Translate in %s:" % target_lang print target_expr print print "[+] Eval in Python:" def memory(addr, size): ret = random.randint(0, (1 << size) - 1) print "Memory access: @0x%x -> 0x%x" % (addr, ret) return ret for expr_id in expr.get_r(mem_read=True): if isinstance(expr_id, ExprId): value = random.randint(0, (1 << expr_id.size) - 1)
def translationTest(self, expr, expected): from miasm2.ir.translators import Translator translator = Translator.to_language("C") self.assertEqual(translator.from_expr(expr), expected)
import miasm2.expression.expression as m2_expr from miasm2.expression.simplifications import expr_simp from miasm2.core import asmbloc from miasm2.ir.translators import Translator import logging log_to_c_h = logging.getLogger("ir_helper") console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log_to_c_h.addHandler(console_handler) log_to_c_h.setLevel(logging.WARN) # Miasm to C translator translator = Translator.to_language("C") prefetch_id = [] prefetch_id_size = {} for size in [8, 16, 32, 64]: prefetch_id_size[size] = [] for i in xrange(20): name = 'pfmem%.2d_%d' % (size, i) c = m2_expr.ExprId(name, size) globals()[name] = c prefetch_id.append(c) prefetch_id_size[size].append(c) def init_arch_C(arch): arch.id2Cid = {} for x in arch.regs.all_regs_ids + prefetch_id: arch.id2Cid[x] = m2_expr.ExprId('((vm_cpu_t*)jitcpu->cpu)->' + str(x), x.size)
random.seed(0) class ExprRandom_OpSubRange(ExprRandom): operations_by_args_number = {1: ["-"], 2: ["<<", ">>",], "2+": ["+", "*", "&", "|", "^"], } print "[+] Compute a random expression:" expr = ExprRandom_OpSubRange.get(depth=8) print "-> %s" % expr print target_exprs = {lang:Translator.to_language(lang).from_expr(expr) for lang in Translator.available_languages()} for target_lang, target_expr in target_exprs.iteritems(): print "[+] Translate in %s:" % target_lang print target_expr print print "[+] Eval in Python:" def memory(addr, size): ret = random.randint(0, (1 << size) - 1) print "Memory access: @0x%x -> 0x%x" % (addr, ret) return ret for expr_id in expr.get_r(mem_read=True): if isinstance(expr_id, ExprId): value = random.randint(0, (1 << expr_id.size) - 1)
""" Module to generate C code for a given native @block """ import miasm2.expression.expression as m2_expr from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.ir.translators import Translator from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel # Miasm to C translator TRANSLATOR = Translator.to_language("C") SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)} MASK_INT = 0xffffffffffffffff class Attributes(object): """ Store an irblock attributes """ def __init__(self, log_mn=False, log_regs=False): self.mem_read = False self.mem_write = False self.set_exception = False self.log_mn = log_mn self.log_regs = log_regs self.instr = None
1: ["-"], 2: [ "<<", ">>", ], "2+": ["+", "*", "&", "|", "^"], } print "[+] Compute a random expression:" expr = ExprRandom_OpSubRange.get(depth=8) print "-> %s" % expr print target_exprs = { lang: Translator.to_language(lang).from_expr(expr) for lang in Translator.available_languages() } for target_lang, target_expr in target_exprs.iteritems(): print "[+] Translate in %s:" % target_lang print target_expr print print "[+] Eval in Python:" def memory(addr, size): ret = random.randint(0, (1 << size) - 1) print "Memory access: @0x%x -> 0x%x" % (addr, ret) return ret
from miasm2.expression.expression import * from miasm2.analysis.expression_range import expr_range from miasm2.ir.translators import Translator import z3 trans = Translator.to_language("z3") a = ExprId("a", 8) b = ExprId("b", 32) for expr in [ a, b, b[4:6], a + ExprInt(4, 8), ExprInt(5, 8) + ExprInt(4, 8), a.zeroExtend(32) + ExprInt(0x100, 32), (a.zeroExtend(32) * ExprInt(3, 32)) + ExprInt(0x100, 32), (a.zeroExtend(32) + ExprInt(0x80, 32)) * ExprInt(3, 32), ExprCond(b, a.zeroExtend(32) + ExprInt(0x100, 32), a.zeroExtend(32) + ExprInt(0x500, 32)), ExprCond(b[1:2], a.zeroExtend(32), a.zeroExtend(32) + ExprInt(0x1000, 32)) + \ ExprCond(b[0:1], a.zeroExtend(32) + ExprInt(0x5000, 32), a.zeroExtend(32) + ExprInt(0x10000, 32)), - a, - ExprInt(4, 8), b[:8].zeroExtend(16) - ExprInt(4, 16), a[4:6].zeroExtend(32) + ExprInt(-1, 32), a >> ExprInt(4, 8), a << ExprInt(4, 8), ExprOp("a>>", a, ExprInt(4, 8)), ExprInt(4, 8) >> a, ExprInt(4, 8) << a,
from miasm2.expression.simplifications_cond import ExprOp_inf_signed, ExprOp_inf_unsigned, ExprOp_equal parser = ArgumentParser("Expression simplification regression tests") parser.add_argument("--z3", action="store_true", help="Enable check against z3") parser.add_argument("-v", "--verbose", action="store_true", help="Verbose simplify") args = parser.parse_args() if args.verbose: log_exprsimp.setLevel(logging.DEBUG) # Additional imports and definitions if args.z3: import z3 from miasm2.ir.translators import Translator trans = Translator.to_language("z3") def check(expr_in, expr_out): """Check that expr_in is always equals to expr_out""" print "Ensure %s = %s" % (expr_in, expr_out) solver = z3.Solver() solver.add(trans.from_expr(expr_in) != trans.from_expr(expr_out)) result = solver.check() if result != z3.unsat: print "ERROR: a counter-example has been founded:" model = solver.model() print model print "Reinjecting in the simplifier:"
""" Module to generate C code for a given native @block """ import miasm2.expression.expression as m2_expr from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.ir.translators import Translator from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel # Miasm to C translator TRANSLATOR = Translator.to_language("C") SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)} MASK_INT = 0xffffffffffffffff class Attributes(object): """ Store an irblock attributes """ def __init__(self, log_mn=False, log_regs=False): self.mem_read = False self.mem_write = False self.set_exception = False self.log_mn = log_mn self.log_regs = log_regs self.instr = None class CGen(object):