コード例 #1
0
ファイル: cff_solver.py プロジェクト: fIappy/stadeo
    def _deobfuscate_cff_loops(self, source_block, symbols):
        """

        :param symbols: initial symbols of symbolic execution engine to be created
        :param source_block: head of the graph to be deobfuscated
        :return:
        """
        symb_exec = SymbolicExecutionEngine(self.ir_arch)
        flat_block = self.flat_loops.get_block(source_block.loc_key, symb_exec, None)
        # maps flattening blocks to their respective loc_keys
        new_head = LocKey(0)
        flat_block_to_loc_key = {flat_block: new_head}
        todo = [FlattenState(flat_block, symbols)]
        counter = {}
        while todo:
            state = todo.pop()
            block_loc_key = state.flat_block.block_loc_key
            self.relevant_nodes.add(block_loc_key)
            counter[block_loc_key] = counter.get(block_loc_key, 0) + 1
            logger.debug("Processing block at 0x%x as %s; in all affected: %d; loops_id: %s; the jtc_vars are:" %
                         (self.asmcfg.loc_db.get_location_offset(block_loc_key) or 0xBAD, str(block_loc_key),
                          block_loc_key in self.all_affected_lines,
                          self.flat_loops[block_loc_key].loc_key))
            if counter[block_loc_key] > 500:
                raise Exception("Couldn't deobfuscate cff loop, either fell into an infinite loop or processing very "
                                "big function")
            symb_exec.set_state(state.symbols)
            # evaluate all affected lines
            self._eval_updt_lines(symb_exec, block_loc_key)
            for flat_block in self._insert_flat_block(state.flat_block, symb_exec, flat_block_to_loc_key):
                todo.append(FlattenState(flat_block, symb_exec.get_state()))
        return new_head
コード例 #2
0
    def _recognize(self, max_loop_num):
        symb_engine = SymbolicExecutionEngine(self.ir_arch, regs.regs_init)
        todo = [(LocKey(0), symb_engine.get_state())]
        done_loc = set()
        if not max_loop_num:
            max_loop_num = float('inf')
        found_loops_num = 0
        while todo:
            loc_key, symb_state = todo.pop()
            if loc_key in done_loc or loc_key not in self.ircfg.blocks:
                continue
            done_loc.add(loc_key)
            ir_block = self.ircfg.blocks[loc_key]
            symb_engine.set_state(symb_state)
            for ind, assignblk in enumerate(ir_block.assignblks):
                for dst, src in assignblk.items():
                    if max_loop_num < found_loops_num:
                        return
                    if src.is_int() and int(src) in self.func_addresses:
                        assignblk_node = AssignblkNode(ir_block.loc_key, ind,
                                                       dst)
                        # no uses
                        if assignblk_node not in self.analyses.defuse_edges or not \
                                self.analyses.defuse_edges[assignblk_node]:
                            # possible virtual table initialization
                            self.possible_merge_funcs.add(
                                (int(src), frozenset(), loc_key))
                    elif src.is_op("call_func_stack"):
                        self._process_call(src, dst, symb_engine, assignblk,
                                           loc_key)
                    elif (expr_simp(src).is_int() and not is_bad_expr(dst)) \
                            or (ir_block.loc_key == LocKey(0) and dst == src and
                                (not self._merging_var_candidates or dst in self._merging_var_candidates)):
                        if self._process_assignment(ir_block, ind, dst):
                            self._merging_var_candidates = None
                            found_loops_num += 1
                symb_engine.eval_updt_assignblk(assignblk)

            for succ in self.ircfg.successors(loc_key):
                todo.append((succ, symb_engine.get_state()))