diff options
| -rw-r--r-- | miasm/core/modint.py | 14 | ||||
| -rw-r--r-- | miasm/expression/simplifications.py | 2 | ||||
| -rw-r--r-- | miasm/expression/simplifications_common.py | 58 |
3 files changed, 74 insertions, 0 deletions
diff --git a/miasm/core/modint.py b/miasm/core/modint.py index 2ecefed1..14b4dc2c 100644 --- a/miasm/core/modint.py +++ b/miasm/core/modint.py @@ -55,6 +55,20 @@ class moduint(object): def __div__(self, y): # Python: 8 / -7 == -2 (C-like: -1) # int(float) trick cannot be used, due to information loss + # Examples: + # + # 42 / 10 => 4 + # 42 % 10 => 2 + # + # -42 / 10 => -4 + # -42 % 10 => -2 + # + # 42 / -10 => -4 + # 42 % -10 => 2 + # + # -42 / -10 => 4 + # -42 % -10 => -2 + den = int(y) num = int(self) result_sign = 1 if (den * num) >= 0 else -1 diff --git a/miasm/expression/simplifications.py b/miasm/expression/simplifications.py index c65b2b7b..38c4cbf4 100644 --- a/miasm/expression/simplifications.py +++ b/miasm/expression/simplifications.py @@ -65,11 +65,13 @@ class ExpressionSimplifier(ExprVisitorCallbackBottomToTop): simplifications_common.simp_compose_and_mask, simplifications_common.simp_bcdadd_cf, simplifications_common.simp_bcdadd, + simplifications_common.simp_smod_sext, ], m2_expr.ExprSlice: [ simplifications_common.simp_slice, simplifications_common.simp_slice_of_ext, + simplifications_common.simp_slice_of_sext, simplifications_common.simp_slice_of_op_ext, ], m2_expr.ExprCompose: [simplifications_common.simp_compose], diff --git a/miasm/expression/simplifications_common.py b/miasm/expression/simplifications_common.py index fd45ef6d..85af9dc4 100644 --- a/miasm/expression/simplifications_common.py +++ b/miasm/expression/simplifications_common.py @@ -594,6 +594,14 @@ def simp_compose(e_s, expr): args = args[:i] + [ExprMem(arg.ptr, arg.size + nxt.size)] + args[i + 2:] return ExprCompose(*args) + # {A, signext(A)[32:64]} => signext(A) + if len(args) == 2 and args[0].size == args[1].size: + arg1, arg2 = args + size = arg1.size + sign_ext = arg1.signExtend(arg1.size*2) + if arg2 == sign_ext[size:2*size]: + return sign_ext + # {a, x?b:d, x?c:e, f} => x?{a, b, c, f}:{a, d, e, f} conds = set(arg.cond for arg in expr.args if arg.is_cond()) @@ -1443,6 +1451,23 @@ def simp_slice_of_ext(_, expr): return arg.zeroExtend(expr.stop) return expr +def simp_slice_of_sext(e_s, expr): + """ + with Y <= size(A) + A.signExt(X)[0:Y] => A[0:Y] + """ + if not expr.arg.is_op(): + return expr + if not expr.arg.op.startswith("signExt"): + return expr + arg = expr.arg.args[0] + if expr.start != 0: + return expr + if expr.stop <= arg.size: + return e_s.expr_simp(arg[:expr.stop]) + return expr + + def simp_slice_of_op_ext(expr_s, expr): """ (X.zeroExt() + {Z, } + ... + Int)[0:8] => X + ... + int[:] @@ -1763,3 +1788,36 @@ def simp_bcdadd(_, expr): carry = 0 res += j << i return ExprInt(res, arg1.size) + + +def simp_smod_sext(expr_s, expr): + """ + a.size == b.size + smod(a.signExtend(X), b.signExtend(X)) => smod(a, b).signExtend(X) + """ + if not expr.is_op("smod"): + return expr + arg1, arg2 = expr.args + if arg1.is_op() and arg1.op.startswith("signExt"): + src1 = arg1.args[0] + if arg2.is_op() and arg2.op.startswith("signExt"): + src2 = arg2.args[0] + if src1.size == src2.size: + # Case: a.signext(), b.signext() + return ExprOp("smod", src1, src2).signExtend(expr.size) + return expr + elif arg2.is_int(): + src2 = expr_s.expr_simp(arg2[:src1.size]) + if expr_s.expr_simp(src2.signExtend(arg2.size)) == arg2: + # Case: a.signext(), int + return ExprOp("smod", src1, src2).signExtend(expr.size) + return expr + # Case: int , b.signext() + if arg2.is_op() and arg2.op.startswith("signExt"): + src2 = arg2.args[0] + if arg1.is_int(): + src1 = expr_s.expr_simp(arg1[:src2.size]) + if expr_s.expr_simp(src1.signExtend(arg1.size)) == arg1: + # Case: int, b.signext() + return ExprOp("smod", src1, src2).signExtend(expr.size) + return expr |