From 1e42a5d64439c587df81432e690ac464e84cd873 Mon Sep 17 00:00:00 2001 From: Ajax Date: Tue, 13 Feb 2018 14:21:37 +0100 Subject: Fix 'simp_op_cond_int' comment --- miasm2/expression/simplifications_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'miasm2/expression/simplifications_common.py') diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 02b43c4b..6eb5e804 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -327,7 +327,7 @@ def simp_cond_op_int(e_s, expr): "Extract conditions from operations" - # x?a:b + x?c:d + e => x?(a+b+e:c+d+e) + # x?a:b + x?c:d + e => x?(a+c+e:b+d+e) if not expr.op in ["+", "|", "^", "&", "*", '<<', '>>', 'a>>']: return expr if len(expr.args) < 2: -- cgit 1.4.1 From c887ab5c5da2c12ccb84be93da238a9c9be3e229 Mon Sep 17 00:00:00 2001 From: Ajax Date: Tue, 13 Feb 2018 14:46:18 +0100 Subject: A >> X >> Y => A >> (X+Y) ONLY IF X + Y does not overflow --- miasm2/expression/simplifications_common.py | 9 +++++++-- test/expression/simplifications.py | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'miasm2/expression/simplifications_common.py') diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 6eb5e804..6840a0ac 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -212,10 +212,15 @@ def simp_cst_propagation(e_s, expr): args0 = args[0].args[0] args = [args0, args1] - # A >> X >> Y => A >> (X+Y) + # A >> X >> Y => A >> (X+Y) if X + Y does not overflow + # To be sure, only consider the simplification when X.msb and Y.msb are 0 if (op_name in ['<<', '>>'] and args[0].is_op(op_name)): - args = [args[0].args[0], args[0].args[1] + args[1]] + X = args[0].args[1] + Y = args[1] + if (e_s(X.msb()) == ExprInt(0, 1) and + e_s(Y.msb()) == ExprInt(0, 1)): + args = [args[0].args[0], X + Y] # ((A & A.mask) if op_name == "&" and args[-1] == expr.mask: diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index 8799191b..5a223f7c 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -77,6 +77,9 @@ d = ExprId('d', 32) e = ExprId('e', 32) f = ExprId('f', size=64) +b_msb_null = b[:31].zeroExtend(32) +c_msb_null = c[:31].zeroExtend(32) + m = ExprMem(a) s = a[:8] @@ -377,6 +380,12 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), ((ExprMem(ExprCond(a, b, c)),ExprCond(a, ExprMem(b), ExprMem(c)))), (ExprCond(a, i0, i1) + ExprCond(a, i0, i1), ExprCond(a, i0, i2)), + (a << b << c, a << b << c), # Left unmodified + (a << b_msb_null << c_msb_null, + a << (b_msb_null + c_msb_null)), + (a >> b >> c, a >> b >> c), # Left unmodified + (a >> b_msb_null >> c_msb_null, + a >> (b_msb_null + c_msb_null)), ] for e_input, e_check in to_test: -- cgit 1.4.1 From 3baf9b6d10b9a2e11a1d92f268ce4470f343fc64 Mon Sep 17 00:00:00 2001 From: Ajax Date: Tue, 13 Feb 2018 14:49:52 +0100 Subject: 'simp_cond_factor' is wrong if << / >> / a>> has more than 2 arguments --- miasm2/expression/simplifications_common.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'miasm2/expression/simplifications_common.py') diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 6840a0ac..22e328e1 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -365,6 +365,14 @@ def simp_cond_factor(e_s, expr): return expr if len(expr.args) < 2: return expr + + if expr.op in ['>>', '<<', 'a>>']: + assert len(expr.args) == 2 + + # Note: the following code is correct for non-commutative operation only if + # there is 2 arguments. Otherwise, the order is not conserved + + # Regroup sub-expression by similar conditions conds = {} not_conds = [] multi_cond = False @@ -380,7 +388,9 @@ def simp_cond_factor(e_s, expr): conds[cond].append(arg) if not multi_cond: return expr - c_out = not_conds[:] + + # Rebuild the new expression + c_out = not_conds for cond, vals in conds.items(): new_src1 = [x.src1 for x in vals] new_src2 = [x.src2 for x in vals] -- cgit 1.4.1 From 8e5fa3a219da14ee0e2f7096c6ba3e164cce959d Mon Sep 17 00:00:00 2001 From: Ajax Date: Tue, 13 Feb 2018 16:45:39 +0100 Subject: Update rot simplification, to avoid overflow cases --- miasm2/expression/simplifications_common.py | 35 +++++++++++++++------- test/expression/simplifications.py | 45 ++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 21 deletions(-) (limited to 'miasm2/expression/simplifications_common.py') diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 22e328e1..ccb97cb3 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -196,21 +196,34 @@ def simp_cst_propagation(e_s, expr): args[1].arg == args[0].size): return args[0] - # A <<< X <<< Y => A <<< (X+Y) (ou <<< >>>) + # (A <<< X) <<< Y => A <<< (X+Y) (or <<< >>>) if X + Y does not overflow if (op_name in ['<<<', '>>>'] and args[0].is_op() and args[0].op in ['<<<', '>>>']): - op1 = op_name - op2 = args[0].op - if op1 == op2: - op_name = op1 - args1 = args[0].args[1] + args[1] - else: - op_name = op2 - args1 = args[0].args[1] - args[1] + A = args[0].args[0] + X = args[0].args[1] + Y = args[1] + if op_name != args[0].op and e_s(X - Y) == ExprInt(0, X.size): + return args[0].args[0] + elif X.is_int() and Y.is_int(): + new_X = int(X) % expr.size + new_Y = int(Y) % expr.size + if op_name == args[0].op: + rot = (new_X + new_Y) % expr.size + op = op_name + else: + rot = new_Y - new_X + op = op_name + if rot < 0: + rot = - rot + op = {">>>": "<<<", "<<<": ">>>"}[op_name] + args = [A, ExprInt(rot, expr.size)] + op_name = op - args0 = args[0].args[0] - args = [args0, args1] + else: + # Do not consider this case, too tricky (overflow on addition / + # substraction) + pass # A >> X >> Y => A >> (X+Y) if X + Y does not overflow # To be sure, only consider the simplification when X.msb and Y.msb are 0 diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index cb8dc4f8..2650d4d1 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -86,6 +86,13 @@ f = ExprId('f', size=64) b_msb_null = b[:31].zeroExtend(32) c_msb_null = c[:31].zeroExtend(32) +a31 = ExprId('a31', 31) +b31 = ExprId('b31', 31) +c31 = ExprId('c31', 31) +b31_msb_null = ExprId('b31', 31)[:30].zeroExtend(31) +c31_msb_null = ExprId('c31', 31)[:30].zeroExtend(31) + + m = ExprMem(a) s = a[:8] @@ -120,17 +127,35 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), (ExprOp('>>>', a, ExprInt(32, 32)), a), (ExprOp('>>>', a, ExprInt(0, 32)), a), (ExprOp('<<', a, ExprInt(0, 32)), a), + (ExprOp('<<<', a31, ExprInt(31, 31)), a31), + (ExprOp('>>>', a31, ExprInt(31, 31)), a31), + (ExprOp('>>>', a31, ExprInt(0, 31)), a31), + (ExprOp('<<', a31, ExprInt(0, 31)), a31), + + (ExprOp('<<<', a31, ExprOp('<<<', b31, c31)), + ExprOp('<<<', a31, ExprOp('<<<', b31, c31))), + (ExprOp('<<<', ExprOp('>>>', a31, b31), c31), + ExprOp('<<<', ExprOp('>>>', a31, b31), c31)), + (ExprOp('>>>', ExprOp('<<<', a31, b31), c31), + ExprOp('>>>', ExprOp('<<<', a31, b31), c31)), + (ExprOp('>>>', ExprOp('<<<', a31, b31), b31), + a31), + (ExprOp('<<<', ExprOp('>>>', a31, b31), b31), + a31), + (ExprOp('>>>', ExprOp('>>>', a31, b31), b31), + ExprOp('>>>', ExprOp('>>>', a31, b31), b31)), + (ExprOp('<<<', ExprOp('<<<', a31, b31), b31), + ExprOp('<<<', ExprOp('<<<', a31, b31), b31)), + + (ExprOp('>>>', ExprOp('<<<', a31, ExprInt(0x1234, 31)), ExprInt(0x1111, 31)), + ExprOp('>>>', a31, ExprInt(0x13, 31))), + (ExprOp('<<<', ExprOp('>>>', a31, ExprInt(0x1234, 31)), ExprInt(0x1111, 31)), + ExprOp('<<<', a31, ExprInt(0x13, 31))), + (ExprOp('>>>', ExprOp('<<<', a31, ExprInt(-1, 31)), ExprInt(0x1111, 31)), + ExprOp('>>>', a31, ExprInt(0x1c, 31))), + (ExprOp('<<<', ExprOp('>>>', a31, ExprInt(-1, 31)), ExprInt(0x1111, 31)), + ExprOp('<<<', a31, ExprInt(0x1c, 31))), - (ExprOp('<<<', a, ExprOp('<<<', b, c)), - ExprOp('<<<', a, ExprOp('<<<', b, c))), - (ExprOp('<<<', ExprOp('<<<', a, b), c), - ExprOp('<<<', a, (b+c))), - (ExprOp('<<<', ExprOp('>>>', a, b), c), - ExprOp('>>>', a, (b-c))), - (ExprOp('>>>', ExprOp('<<<', a, b), c), - ExprOp('<<<', a, (b-c))), - (ExprOp('>>>', ExprOp('<<<', a, b), b), - a), (ExprOp(">>>", ExprInt(0x1000, 16), ExprInt(0x11, 16)), ExprInt(0x800, 16)), (ExprOp("<<<", ExprInt(0x1000, 16), ExprInt(0x11, 16)), -- cgit 1.4.1