about summary refs log tree commit diff stats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--miasm2/ir/symbexec_types.py169
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