diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/ir/symbexec_types.py | 169 |
1 files changed, 28 insertions, 141 deletions
diff --git a/miasm2/ir/symbexec_types.py b/miasm2/ir/symbexec_types.py index bc5546de..9719a3b7 100644 --- a/miasm2/ir/symbexec_types.py +++ b/miasm2/ir/symbexec_types.py @@ -63,147 +63,13 @@ class SymbExecCType(SymbolicExecutionEngine): func_write=None, sb_expr_simp=expr_simp): self.chandler = chandler + super(SymbExecCType, self).__init__(ir_arch, {}, func_read, func_write, sb_expr_simp) self.symbols = dict(symbols) - offset_types = [] - for name in [('int',), ('long',), - ('long', 'long'), - ('char',), ('short',), - - ('unsigned', 'char',), ('unsigned', 'short',), - ('unsigned', 'int',), ('unsigned', 'long',), - ('unsigned', 'long', 'long')]: - objc = self.chandler.type_analyzer.types_mngr.get_objc(CTypeId(*name)) - offset_types.append(objc) - self.offset_types = offset_types - - def is_type_offset(self, objc): - """Return True if @objc is char/short/int/long""" - return objc in self.offset_types - - def get_type_int_by_size(self, size): - """Return a char/short/int/long type with the size equal to @size - @size: size in bit""" - - for objc in self.offset_types: - if objc.size == size / 8: - return objc - return None - - def is_offset_list(self, types, size): - """Return the corresponding char/short/int/long type of @size, if every - types in the list @types are type offset - @types: a list of c types - @size: size in bit""" - - for arg_type in types: - if not self.is_type_offset(arg_type): - return None - objc = self.get_type_int_by_size(size) - if objc: - return objc - # default size - objc = self.offset_types[0] - return objc - - def apply_expr_on_state_visit_cache(self, expr, state, cache, level=0): - ret = self._apply_expr_on_state_visit_cache(expr, state, cache, level) - if not ret: - return None - return tuple(ret) - - def _apply_expr_on_state_visit_cache(self, expr, state, cache, level=0): - """ - Deep First evaluate nodes: - 1. evaluate node's sons - 2. simplify - """ - - expr = self.expr_simp(expr) - if expr in cache: - return cache[expr] - elif expr in self.symbols: - ret = self.symbols[expr] - return ret - elif expr in state: - return state[expr] - elif isinstance(expr, ExprInt): - objc = self.get_type_int_by_size(expr.size) - if objc is None: - objc = self.chandler.type_analyzer.types_mngr.get_objc(CTypeId('int')) - return [objc] - elif isinstance(expr, ExprId): - if expr in state: - return state[expr] - return None - elif isinstance(expr, ExprMem): - ptr_type = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level + 1) - if not ptr_type: - return ptr_type - self.chandler.type_analyzer.expr_types[self.OBJC_INTERNAL] = ptr_type - ptr_expr = ExprId(self.OBJC_INTERNAL, expr.arg.size) - objcs = self.chandler.expr_to_types(ExprMem(ptr_expr, expr.size)) - return objcs - elif isinstance(expr, ExprCond): - src1 = self.apply_expr_on_state_visit_cache(expr.src1, state, cache, level + 1) - src2 = self.apply_expr_on_state_visit_cache(expr.src2, state, cache, level + 1) - if src1 is None or src2 is None: - return None - # Return common types - types = list(set(src1).intersection(src2)) - return types - elif isinstance(expr, ExprSlice): - objc = self.get_type_int_by_size(expr.size) - if objc is None: - return None - return [objc] - elif isinstance(expr, ExprOp): - if expr.op.startswith("call"): - return None - args = [] - types = [] - for oarg in expr.args: - arg_types = self.apply_expr_on_state_visit_cache(oarg, state, cache, level + 1) - if arg_types is None: - return None - types += list(arg_types) - if None in types: - return None - objc = self.is_offset_list(types, expr.size) - if objc: - return [objc] - # Find Base + int - if expr.op != '+': - return None - args = list(expr.args) - if args[-1].is_int(): - offset = args.pop() - types.pop() - if len(args) == 1: - arg, arg_types = args.pop(), types - self.chandler.type_analyzer.expr_types[self.OBJC_INTERNAL] = arg_types - ptr_expr = ExprId(self.OBJC_INTERNAL, arg.size) - objcs = self.chandler.expr_to_types(ptr_expr + offset) - return objcs - return None - elif isinstance(expr, ExprCompose): - types = set() - for oarg in expr.args: - arg_types = self.apply_expr_on_state_visit_cache(oarg, state, cache, level + 1) - if arg_types is None: - return None - types.update(arg_types) - objc = self.is_offset_list(types, expr.size) - if objc: - return [objc] - - return None - else: - raise TypeError("Unknown expr type") def get_state(self): """Return the current state of the SymbolicEngine""" @@ -217,22 +83,43 @@ class SymbExecCType(SymbolicExecutionEngine): pool_out = {} eval_cache = {} for dst, src in assignblk.iteritems(): - src = self.eval_expr(src, eval_cache) + objcs = self.chandler.expr_to_types(src, self.symbols) if isinstance(dst, ExprMem): continue elif isinstance(dst, ExprId): - pool_out[dst] = src + pool_out[dst] = tuple(objcs) else: raise ValueError("affected zarb", str(dst)) return pool_out.iteritems() + def eval_expr(self, expr, eval_cache=None): + return self.chandler.expr_to_types(expr, self.symbols) + def apply_change(self, dst, src): - objc = src - if objc is None and dst in self.symbols: - del self.symbols[dst] + if src is None: + if dst in self.symbols: + del self.symbols[dst] else: - self.symbols[dst] = objc + self.symbols[dst] = src def del_mem_above_stack(self, stack_ptr): """No stack deletion""" return + + def dump_id(self): + """ + Dump modififed registers symbols only + """ + for expr, expr_types in sorted(self.symbols.iteritems()): + if not expr.is_mem(): + print expr + for expr_type in expr_types: + print '\t', expr_type + + def dump_mem(self): + """ + Dump modififed memory symbols + """ + for expr, value in sorted(self.symbols.iteritems()): + if expr.is_mem(): + print expr, value |