diff options
| -rw-r--r-- | miasm2/expression/expression.py | 2 | ||||
| -rw-r--r-- | miasm2/expression/modint.py | 35 | ||||
| -rw-r--r-- | miasm2/ir/symbexec.py | 37 | ||||
| -rw-r--r-- | test/expression/expression.py | 6 | ||||
| -rw-r--r-- | test/ir/symbexec.py | 17 |
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) |