about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/expression/simplifications_common.py65
-rw-r--r--test/expression/simplifications.py41
2 files changed, 106 insertions, 0 deletions
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index 489869f3..13588ffd 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -263,6 +263,71 @@ def simp_cst_propagation(e_s, e):
             return -ExprOp(op, *new_args)
         args = new_args
 
+    # A << int with A ExprCompose => move index
+    if op == "<<" and isinstance(args[0], ExprCompose) and isinstance(args[1], ExprInt):
+        final_size = args[0].size
+        shift = int(args[1].arg)
+        new_args = []
+        # shift indexes
+        for expr, start, stop in args[0].args:
+            new_args.append((expr, start+shift, stop+shift))
+        # filter out expression
+        filter_args = []
+        min_index = final_size
+        for expr, start, stop in new_args:
+            if start >= final_size:
+                continue
+            if stop > final_size:
+                expr = expr[:expr.size  - (stop - final_size)]
+                stop = final_size
+            filter_args.append((expr, start, stop))
+            min_index = min(start, min_index)
+        # create entry 0
+        expr = ExprInt_fromsize(min_index, 0)
+        filter_args = [(expr, 0, min_index)] + filter_args
+        return ExprCompose(filter_args)
+
+    # A >> int with A ExprCompose => move index
+    if op == ">>" and isinstance(args[0], ExprCompose) and isinstance(args[1], ExprInt):
+        final_size = args[0].size
+        shift = int(args[1].arg)
+        new_args = []
+        # shift indexes
+        for expr, start, stop in args[0].args:
+            new_args.append((expr, start-shift, stop-shift))
+        # filter out expression
+        filter_args = []
+        max_index = 0
+        for expr, start, stop in new_args:
+            if stop <= 0:
+                continue
+            if start < 0:
+                expr = expr[-start:]
+                start = 0
+            filter_args.append((expr, start, stop))
+            max_index = max(stop, max_index)
+        # create entry 0
+        expr = ExprInt_fromsize(final_size - max_index, 0)
+        filter_args += [(expr, max_index, final_size)]
+        return ExprCompose(filter_args)
+
+
+    # Compose(a) OP Compose(b) with a/b same bounds => Compose(a OP b)
+    if op in ['|', '&', '^'] and all([isinstance(arg, ExprCompose) for arg in args]):
+        bounds = set()
+        for arg in args:
+            bound = tuple([(start, stop) for (expr, start, stop) in arg.args])
+            bounds.add(bound)
+        if len(bounds) == 1:
+            bound = list(bounds)[0]
+            new_args = [[expr] for (expr, start, stop) in args[0].args]
+            for sub_arg in args[1:]:
+                for i, (expr, start, stop) in enumerate(sub_arg.args):
+                    new_args[i].append(expr)
+            for i, arg in enumerate(new_args):
+                new_args[i] = ExprOp(op, *arg), bound[i][0], bound[i][1]
+            return ExprCompose(new_args)
+
     return ExprOp(op, *args)
 
 
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 0f217c72..f4b4fcd6 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -12,6 +12,7 @@ b = ExprId('b')
 c = ExprId('c')
 d = ExprId('d')
 e = ExprId('e')
+f = ExprId('f', size=64)
 
 m = ExprMem(a)
 s = a[:8]
@@ -157,6 +158,46 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
      ExprInt_fromsize(a.size, -1)),
     (ExprOp('-', ExprInt8(1), ExprInt8(0)),
      ExprInt8(1)),
+
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x20),
+     ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x10),
+     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x30),
+     ExprCompose([(ExprInt_fromsize(48, 0), 0, 48), (a[:0x10], 48, 64)])),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x11),
+     ExprCompose([(ExprInt_fromsize(0x11, 0), 0, 0x11), (a, 0x11, 0x31), (ExprInt_fromsize(0xF, 0), 0x31, 0x40)])),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x40),
+     ExprInt64(0)),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x50),
+     ExprInt64(0)),
+
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x20),
+     ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)])),
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x10),
+     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])),
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x30),
+     ExprCompose([(a[0x10:], 0, 16), (ExprInt_fromsize(48, 0), 16, 64)])),
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x11),
+     ExprCompose([(ExprInt_fromsize(0xf, 0), 0, 0xf), (a, 0xf, 0x2f), (ExprInt_fromsize(0x11, 0), 0x2f, 0x40)])),
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x40),
+     ExprInt64(0)),
+    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x50),
+     ExprInt64(0)),
+
+
+    (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x20),
+     ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])),
+    (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x10),
+     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (b[:16], 48, 64)])),
+
+    (ExprCompose([(a, 0, 32), (b, 32, 64)]) | ExprCompose([(c, 0, 32), (d, 32, 64)]),
+     ExprCompose([(a|c, 0, 32), (b|d, 32, 64)])),
+    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (d, 32, 64)]),
+     ExprCompose([(a, 0, 32), (d, 32, 64)])),
+    (ExprCompose([(f[:32], 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (f[32:], 32, 64)]),
+     f),
+
 ]
 
 for e, e_check in to_test[:]: