def emul(self, ctx=None, step=False): """Symbolic execution of relevant nodes according to the history Return the values of inputs nodes' elements @ctx: (optional) Initial context as dictionnary @step: (optional) Verbose execution Warning: The emulation is not sound if the inputs nodes depend on loop variant. """ # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) assignblks = [] # Build a single affectation block according to history last_index = len(self.relevant_labels) for index, label in enumerate(reversed(self.relevant_labels), 1): if index == last_index and label == self.initial_state.label: line_nb = self.initial_state.line_nb else: line_nb = None assignblks += self.irblock_slice(self._ira.blocks[label], line_nb).assignblks # Eval the block temp_label = AsmLabel("Temp") symb_exec = SymbolicExecutionEngine(self._ira, ctx_init) symb_exec.eval_updt_irblock(IRBlock(temp_label, assignblks), step=step) # Return only inputs values (others could be wrongs) return {element: symb_exec.symbols[element] for element in self.inputs}
for miasm_int, res in [(five, 1), (four, 0), (seven, 0), (one0seven, 0)]: e6 = ExprOp('parity', miasm_int) ez3 = Translator.to_language('z3').from_expr(e6) z3_e6 = z3.BitVecVal(res, 1) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- # '-' for miasm_int, res in [(five, -5), (four, -4)]: e6 = ExprOp('-', miasm_int) ez3 = Translator.to_language('z3').from_expr(e6) z3_e6 = z3.BitVecVal(res, 32) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- e7 = ExprId(AsmLabel("label_histoire", 0xdeadbeef), 32) ez3 = Translator.to_language('z3').from_expr(e7) z3_e7 = z3.BitVecVal(0xdeadbeef, 32) assert equiv(ez3, z3_e7) # Should just not throw anything to pass e8 = ExprId(AsmLabel("label_jambe"), 32) ez3 = Translator.to_language('z3').from_expr(e8) assert not equiv(ez3, z3_e7) # -------------------------------------------------------------------------- # cntleadzeros, cnttrailzeros # cnttrailzeros(0x1138) == 3 cnttrailzeros1 = Translator.to_language('z3').from_expr( ExprOp("cnttrailzeros", ExprInt(0x1138, 32)))
dg = DiGraphSimplifier() dg.enable_passes([remove_useless_blocks]) blocks = dg(blocks) ### Only two blocks should remain assert len(blocks) == 2 assert first_block in blocks assert last_block in blocks ## Graph the final output open("graph2.dot", "w").write(blocks.dot()) # Test helper methods ## Label2block should always be updated assert blocks.label2block(first_block.label) == first_block my_block = AsmBlock(AsmLabel("testlabel")) blocks.add_node(my_block) assert len(blocks) == 3 assert blocks.label2block(first_block.label) == first_block assert blocks.label2block(my_block.label) == my_block ## Bad blocks assert len(list(blocks.get_bad_blocks())) == 0 assert len(list(blocks.get_bad_blocks_predecessors())) == 0 ### Add a bad block, not linked my_bad_block = AsmBlockBad(AsmLabel("testlabel_bad")) blocks.add_node(my_bad_block) assert list(blocks.get_bad_blocks()) == [my_bad_block] assert len(list(blocks.get_bad_blocks_predecessors())) == 0 ### Link the bad block and update edges ### Indeed, a sub-element has been modified (bto from a block from blocks)
r = ExprId("r") a_init = ExprId("a_init") b_init = ExprId("b_init") c_init = ExprId("c_init") d_init = ExprId("d_init") r_init = ExprId("r_init") # Return register pc = ExprId("pc") sp = ExprId("sp") CST1 = ExprInt(0x11, 32) CST2 = ExprInt(0x12, 32) CST3 = ExprInt(0x13, 32) LBL0 = AsmLabel("lbl0") LBL1 = AsmLabel("lbl1") LBL2 = AsmLabel("lbl2") LBL3 = AsmLabel("lbl3") LBL4 = AsmLabel("lbl4") LBL5 = AsmLabel("lbl5") LBL6 = AsmLabel("lbl6") IRDst = ExprId('IRDst', 32) dummy = ExprId('dummy', 32) def gen_irblock(label, exprs_list): irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock):
def gen_label(self): return AsmLabel("GEN")
def get_next_label(self, _): return AsmLabel("NEXT")
def get_next_instr(self, _): return AsmLabel("NEXT")