diff options
| -rw-r--r-- | miasm2/expression/simplifications_common.py | 65 | ||||
| -rw-r--r-- | test/expression/simplifications.py | 41 |
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[:]: |