about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/expression/expression.py2
-rw-r--r--miasm2/expression/modint.py35
-rw-r--r--miasm2/ir/symbexec.py37
-rw-r--r--test/expression/expression.py6
-rw-r--r--test/ir/symbexec.py17
5 files changed, 71 insertions, 26 deletions
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index 581dc8dc..f8af52d9 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -380,6 +380,8 @@ class ExprInt(Expr):
             if size is not None and num.size != size:
                 raise RuntimeError("size must match modint size")
         elif size is not None:
+            if size not in mod_size2uint:
+                define_uint(size)
             self.__arg = mod_size2uint[size](num)
             self.__size = self.arg.size
         else:
diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py
index 76896eb9..a801c948 100644
--- a/miasm2/expression/modint.py
+++ b/miasm2/expression/modint.py
@@ -198,25 +198,36 @@ mod_size2int = {}
 mod_uint2size = {}
 mod_int2size = {}
 
+def define_int(size):
+    """Build the 'modint' instance corresponding to size @size"""
+    global mod_size2int, mod_int2size
+
+    name = 'int%d' % size
+    cls = type(name, (modint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2int[size] = cls
+    mod_int2size[cls] = size
+    return cls
+
+def define_uint(size):
+    """Build the 'moduint' instance corresponding to size @size"""
+    global mod_size2uint, mod_uint2size
+
+    name = 'uint%d' % size
+    cls = type(name, (moduint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2uint[size] = cls
+    mod_uint2size[cls] = size
+    return cls
 
 def define_common_int():
     "Define common int: ExprInt1, ExprInt2, .."
-    global mod_size2int, mod_int2size, mod_size2uint, mod_uint2size
-
     common_int = xrange(1, 257)
 
     for i in common_int:
-        name = 'uint%d' % i
-        c = type(name, (moduint,), {"size": i, "limit": 1 << i})
-        globals()[name] = c
-        mod_size2uint[i] = c
-        mod_uint2size[c] = i
+        define_int(i)
 
     for i in common_int:
-        name = 'int%d' % i
-        c = type(name, (modint,), {"size": i, "limit": 1 << i})
-        globals()[name] = c
-        mod_size2int[i] = c
-        mod_int2size[c] = i
+        define_uint(i)
 
 define_common_int()
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index db3eacdc..2bb99e5d 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -392,6 +392,28 @@ class symbexec(object):
 
         return pool_out.iteritems()
 
+    def apply_change(self, dst, src):
+        """
+        Apply @dst = @src on the current state WITHOUT evaluating both side
+        @dst: Expr, destination
+        @src: Expr, source
+        """
+        if isinstance(dst, m2_expr.ExprMem):
+            mem_overlap = self.get_mem_overlapping(dst)
+            for _, base in mem_overlap:
+                diff_mem = self.substract_mems(base, dst)
+                del self.symbols[base]
+                for new_mem, new_val in diff_mem:
+                    self.symbols[new_mem] = new_val
+        src_o = self.expr_simp(src)
+        self.symbols[dst] = src_o
+        if dst == src_o:
+            del self.symbols[dst]
+        if isinstance(dst, m2_expr.ExprMem):
+            if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
+                self.func_write(self, dst, src_o)
+                del self.symbols[dst]
+
     def eval_ir(self, assignblk):
         """
         Apply an AssignBlock on the current state
@@ -400,21 +422,8 @@ class symbexec(object):
         mem_dst = []
         src_dst = self.eval_ir_expr(assignblk)
         for dst, src in src_dst:
+            self.apply_change(dst, src)
             if isinstance(dst, m2_expr.ExprMem):
-                mem_overlap = self.get_mem_overlapping(dst)
-                for _, base in mem_overlap:
-                    diff_mem = self.substract_mems(base, dst)
-                    del self.symbols[base]
-                    for new_mem, new_val in diff_mem:
-                        self.symbols[new_mem] = new_val
-            src_o = self.expr_simp(src)
-            self.symbols[dst] = src_o
-            if dst == src_o:
-                del self.symbols[dst]
-            if isinstance(dst, m2_expr.ExprMem):
-                if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
-                    self.func_write(self, dst, src_o)
-                    del self.symbols[dst]
                 mem_dst.append(dst)
         return mem_dst
 
diff --git a/test/expression/expression.py b/test/expression/expression.py
index 847ba7eb..58c0ca37 100644
--- a/test/expression/expression.py
+++ b/test/expression/expression.py
@@ -5,7 +5,13 @@ from pdb import pm
 from miasm2.expression.expression import *
 from miasm2.expression.expression_helper import *
 
+# Expression comparison
 assert(ExprInt64(-1) != ExprInt64(-2))
+assert(ExprInt64(1) != ExprInt32(1))
+
+# Expression size
+big_cst = ExprInt(1, size=0x1000)
+assert big_cst.size == 0x1000
 
 # Possible values
 #- Common constants
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 6df0bbc3..24b02341 100644
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -11,6 +11,7 @@ class TestSymbExec(unittest.TestCase):
             ExprCompose, ExprAff
         from miasm2.arch.x86.sem import ir_x86_32
         from miasm2.ir.symbexec import symbexec
+        from miasm2.ir.ir import AssignBlock
 
         addrX = ExprInt32(-1)
         addr0 = ExprInt32(0)
@@ -59,6 +60,22 @@ class TestSymbExec(unittest.TestCase):
         self.assertEqual(e.apply_expr(ExprAff(id_eax, addr9)), addr9)
         self.assertEqual(e.apply_expr(id_eax), addr9)
 
+        # apply_change / eval_ir / apply_expr
+
+        ## x = a (with a = 0x0)
+        assignblk = AssignBlock()
+        assignblk[id_x] = id_a
+        e.eval_ir(assignblk)
+        self.assertEqual(e.apply_expr(id_x), addr0)
+
+        ## x = a (without replacing 'a' with 0x0)
+        e.apply_change(id_x, id_a)
+        self.assertEqual(e.apply_expr(id_x), id_a)
+
+        ## x = a (with a = 0x0)
+        self.assertEqual(e.apply_expr(assignblk.dst2ExprAff(id_x)), addr0)
+        self.assertEqual(e.apply_expr(id_x), addr0)
+
 if __name__ == '__main__':
     testsuite = unittest.TestLoader().loadTestsFromTestCase(TestSymbExec)
     report = unittest.TextTestRunner(verbosity=2).run(testsuite)