about summary refs log tree commit diff stats
path: root/test/ir/symbexec.py
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2017-10-03 17:20:38 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2018-03-15 14:46:36 +0100
commit1b534d9ad543473f12ddcb631e0cddb0cbd54ff4 (patch)
tree5d5248ceb9358a1f497f4830e821e50afb340dba /test/ir/symbexec.py
parentedabfcda0fa8c0dd8ab3017853b375b1ee24b754 (diff)
downloadmiasm-1b534d9ad543473f12ddcb631e0cddb0cbd54ff4.tar.gz
miasm-1b534d9ad543473f12ddcb631e0cddb0cbd54ff4.zip
Symbexec: use hashtable for mem symbols
Diffstat (limited to 'test/ir/symbexec.py')
-rwxr-xr-xtest/ir/symbexec.py309
1 files changed, 255 insertions, 54 deletions
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 90d08d17..7d5bf44a 100755
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -13,70 +13,271 @@ class TestSymbExec(unittest.TestCase):
         from miasm2.ir.symbexec import SymbolicExecutionEngine
         from miasm2.ir.ir import AssignBlock
 
-        addrX = ExprInt(-1, 32)
-        addr0 = ExprInt(0, 32)
-        addr1 = ExprInt(1, 32)
-        addr8 = ExprInt(8, 32)
-        addr9 = ExprInt(9, 32)
-        addr20 = ExprInt(20, 32)
-        addr40 = ExprInt(40, 32)
-        addr50 = ExprInt(50, 32)
-        mem0 = ExprMem(addr0, 32)
-        mem1 = ExprMem(addr1, 8)
-        mem8 = ExprMem(addr8, 32)
-        mem9 = ExprMem(addr9, 32)
-        mem20 = ExprMem(addr20, 32)
-        mem40v = ExprMem(addr40,  8)
-        mem40w = ExprMem(addr40, 16)
-        mem50v = ExprMem(addr50,  8)
-        mem50w = ExprMem(addr50, 16)
+
         id_x = ExprId('x', 32)
-        id_y = ExprId('y', 8)
         id_a = ExprId('a', 32)
-        id_eax = ExprId('eax_init', 32)
-
-        e = SymbolicExecutionEngine(ir_x86_32(),
-                                    {mem0: id_x, mem1: id_y, mem9: id_x,
-                                     mem40w: id_x[:16], mem50v: id_y,
-                                     id_a: addr0, id_eax: addr0})
-        self.assertEqual(e.find_mem_by_addr(addr0), mem0)
-        self.assertEqual(e.find_mem_by_addr(addrX), None)
-        self.assertEqual(e.eval_expr(ExprMem(addr1 - addr1, 32)), id_x)
-        self.assertEqual(e.eval_expr(ExprMem(addr1, 8)), id_y)
-        self.assertEqual(e.eval_expr(ExprMem(addr1 + addr1, 32)), ExprCompose(
-            id_x[16:32], ExprMem(ExprInt(4, 32), 16)))
-        self.assertEqual(e.eval_expr(mem8), ExprCompose(
-            id_x[0:24], ExprMem(ExprInt(11, 32), 8)))
-        self.assertEqual(e.eval_expr(mem40v), id_x[:8])
-        self.assertEqual(e.eval_expr(mem50w), ExprCompose(
-            id_y, ExprMem(ExprInt(51, 32), 8)))
-        self.assertEqual(e.eval_expr(mem20), mem20)
-        e.func_read = lambda x: x
-        self.assertEqual(e.eval_expr(mem20), mem20)
-        self.assertEqual(set(e.modified()), set(e.symbols))
-        self.assertRaises(
-            KeyError, e.symbols.__getitem__, ExprMem(ExprInt(100, 32), 32))
-        self.assertEqual(e.apply_expr(id_eax), addr0)
-        self.assertEqual(e.apply_expr(ExprAff(id_eax, addr9)), addr9)
-        self.assertEqual(e.apply_expr(id_eax), addr9)
-
-        # apply_change / eval_ir / apply_expr
+        id_b = ExprId('b', 32)
+        id_c = ExprId('c', 32)
+        id_d = ExprId('d', 32)
+        id_e = ExprId('e', 64)
+
+        sb = SymbolicExecutionEngine(ir_x86_32(),
+                                    {
+                                        ExprMem(ExprInt(0x4, 32), 8): ExprInt(0x44, 8),
+                                        ExprMem(ExprInt(0x5, 32), 8): ExprInt(0x33, 8),
+                                        ExprMem(ExprInt(0x6, 32), 8): ExprInt(0x22, 8),
+                                        ExprMem(ExprInt(0x7, 32), 8): ExprInt(0x11, 8),
+
+                                        ExprMem(ExprInt(0x20, 32), 32): id_x,
+
+                                        ExprMem(ExprInt(0x40, 32), 32): id_x,
+                                        ExprMem(ExprInt(0x44, 32), 32): id_a,
+
+                                        ExprMem(ExprInt(0x54, 32), 32): ExprInt(0x11223344, 32),
+
+                                        ExprMem(id_a, 32): ExprInt(0x11223344, 32),
+                                        id_a: ExprInt(0, 32),
+                                        id_b: ExprInt(0, 32),
+
+                                        ExprMem(id_c, 32): ExprMem(id_d + ExprInt(0x4, 32), 32),
+                                        ExprMem(id_c + ExprInt(0x4, 32), 32): ExprMem(id_d + ExprInt(0x8, 32), 32),
+
+                                    })
+
+
+        self.assertEqual(sb.eval_expr(ExprInt(1, 32)-ExprInt(1, 32)), ExprInt(0, 32))
+
+        ## Test with unknown mem + integer
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0, 32), 32)), ExprMem(ExprInt(0, 32), 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(1, 32), 32)), ExprCompose(ExprMem(ExprInt(1, 32), 24), ExprInt(0x44, 8)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(2, 32), 32)), ExprCompose(ExprMem(ExprInt(2, 32), 16), ExprInt(0x3344, 16)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(3, 32), 32)), ExprCompose(ExprMem(ExprInt(3, 32), 8), ExprInt(0x223344, 24)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(4, 32), 32)), ExprInt(0x11223344, 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(5, 32), 32)), ExprCompose(ExprInt(0x112233, 24), ExprMem(ExprInt(8, 32), 8)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(6, 32), 32)), ExprCompose(ExprInt(0x1122, 16), ExprMem(ExprInt(8, 32), 16)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(7, 32), 32)), ExprCompose(ExprInt(0x11, 8), ExprMem(ExprInt(8, 32), 24)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(8, 32), 32)), ExprMem(ExprInt(8, 32), 32))
+
+        ## Test with unknown mem + integer
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x50, 32), 32)), ExprMem(ExprInt(0x50, 32), 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x51, 32), 32)), ExprCompose(ExprMem(ExprInt(0x51, 32), 24), ExprInt(0x44, 8)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x52, 32), 32)), ExprCompose(ExprMem(ExprInt(0x52, 32), 16), ExprInt(0x3344, 16)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x53, 32), 32)), ExprCompose(ExprMem(ExprInt(0x53, 32), 8), ExprInt(0x223344, 24)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x54, 32), 32)), ExprInt(0x11223344, 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x55, 32), 32)), ExprCompose(ExprInt(0x112233, 24), ExprMem(ExprInt(0x58, 32), 8)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x56, 32), 32)), ExprCompose(ExprInt(0x1122, 16), ExprMem(ExprInt(0x58, 32), 16)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x57, 32), 32)), ExprCompose(ExprInt(0x11, 8), ExprMem(ExprInt(0x58, 32), 24)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x58, 32), 32)), ExprMem(ExprInt(0x58, 32), 32))
+
+
+
+        ## Test with unknown mem + id
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x1D, 32), 32)), ExprCompose(ExprMem(ExprInt(0x1D, 32), 24), id_x[:8]))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x1E, 32), 32)), ExprCompose(ExprMem(ExprInt(0x1E, 32), 16), id_x[:16]))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x1F, 32), 32)), ExprCompose(ExprMem(ExprInt(0x1F, 32), 8), id_x[:24]))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x20, 32), 32)), id_x)
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x21, 32), 32)), ExprCompose(id_x[8:], ExprMem(ExprInt(0x24, 32), 8)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x22, 32), 32)), ExprCompose(id_x[16:], ExprMem(ExprInt(0x24, 32), 16)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x23, 32), 32)), ExprCompose(id_x[24:], ExprMem(ExprInt(0x24, 32), 24)))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x24, 32), 32)), ExprMem(ExprInt(0x24, 32), 32))
+
+
+        ## Partial read
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(4, 32), 8)), ExprInt(0x44, 8))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x20, 32), 8)), id_x[:8])
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x23, 32), 8)), id_x[24:])
+
+
+        ## Merge
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x40, 32), 64)), ExprCompose(id_x, id_a))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x42, 32), 32)), ExprCompose(id_x[16:], id_a[:16]))
+
+        # Merge memory
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x100, 32), 32)), ExprMem(ExprInt(0x100, 32), 32))
+        self.assertEqual(sb.eval_expr(ExprMem(id_c + ExprInt(0x2, 32), 32)), ExprMem(id_d  + ExprInt(0x6, 32), 32))
+
+        ## Func read
+        def custom_func_read(mem):
+            if mem == ExprMem(ExprInt(0x1000, 32), 32):
+                return id_x
+            return mem
+
+        sb.func_read = custom_func_read
+
+        ## Unmodified read
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(4, 32), 8)), ExprInt(0x44, 8))
+
+        ## Modified read
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x1000, 32), 32)), id_x)
+
+
+        ## Apply_change / eval_ir / apply_expr
 
         ## x = a (with a = 0x0)
         assignblk = AssignBlock({id_x:id_a})
-        e.eval_ir(assignblk)
-        self.assertEqual(e.apply_expr(id_x), addr0)
+        sb.eval_updt_assignblk(assignblk)
+        self.assertEqual(sb.eval_expr(id_x), ExprInt(0, 32))
 
         ## x = a (without replacing 'a' with 0x0)
-        e.apply_change(id_x, id_a)
-        self.assertEqual(e.apply_expr(id_x), id_a)
+        sb.apply_change(id_x, id_a)
+        self.assertEqual(sb.eval_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)
+        self.assertEqual(sb.eval_updt_expr(assignblk.dst2ExprAff(id_x)), ExprInt(0, 32))
+        self.assertEqual(sb.eval_expr(id_x), ExprInt(0, 32))
+        self.assertEqual(sb.eval_updt_expr(id_x), ExprInt(0, 32))
+
+        sb.dump()
+
+        ## state
+        reads = set()
+        for dst, src in sb.modified():
+            reads.update(ExprAff(dst, src).get_r())
+
+        self.assertEqual(reads, set([
+            id_x, id_a,
+            ExprMem(id_d + ExprInt(0x4, 32), 32),
+            ExprMem(id_d + ExprInt(0x8, 32), 32),
+        ]))
+
+        # Erase low id_x byte with 0xFF
+        sb.apply_change(ExprMem(ExprInt(0x20, 32), 8), ExprInt(0xFF, 8))
+        state = dict(sb.modified(ids=False))
+        self.assertEqual(state[ExprMem(ExprInt(0x20, 32), 8)], ExprInt(0xFF, 8))
+        self.assertEqual(state[ExprMem(ExprInt(0x21, 32), 24)], id_x[8:32])
+
+        # Erase high id_x byte with 0xEE
+        sb.apply_change(ExprMem(ExprInt(0x23, 32), 8), ExprInt(0xEE, 8))
+
+        state = dict(sb.modified(ids=False))
+        self.assertEqual(state[ExprMem(ExprInt(0x20, 32), 8)], ExprInt(0xFF, 8))
+        self.assertEqual(state[ExprMem(ExprInt(0x21, 32), 16)], id_x[8:24])
+        self.assertEqual(state[ExprMem(ExprInt(0x23, 32), 8)], ExprInt(0xEE, 8))
+
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x22, 32), 32)), ExprCompose(id_x[16:24], ExprInt(0xEE, 8), ExprMem(ExprInt(0x24, 32), 16)))
+
+        # Erase low byte of 0x11223344 with 0xFF at 0x54
+        sb.apply_change(ExprMem(ExprInt(0x54, 32), 8), ExprInt(0xFF, 8))
+
+        # Erase low byte of 0x11223344 with 0xFF at id_a
+        sb.apply_change(ExprMem(id_a + ExprInt(0x1, 32), 8), ExprInt(0xFF, 8))
+        state = dict(sb.modified(ids=False))
+        self.assertEqual(state[ExprMem(id_a + ExprInt(0x1, 32), 8)], ExprInt(0xFF, 8))
+        self.assertEqual(state[ExprMem(id_a + ExprInt(0x2, 32), 16)], ExprInt(0x1122, 16))
+
+        # Write uint32_t at 0xFFFFFFFE
+        sb.apply_change(ExprMem(ExprInt(0xFFFFFFFE, 32), 32), ExprInt(0x11223344, 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0, 32), 16)), ExprInt(0x1122, 16))
+
+        # Revert memory to original value at 0x42
+        sb.apply_change(ExprMem(ExprInt(0x42, 32), 32), ExprMem(ExprInt(0x42, 32), 32))
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0x42, 32), 32)), ExprMem(ExprInt(0x42, 32), 32))
+
+        # Revert memory to original value at c + 0x2
+        sb.apply_change(ExprMem(id_c + ExprInt(0x2, 32), 32), ExprMem(id_c + ExprInt(0x2, 32), 32))
+        self.assertEqual(sb.eval_expr(ExprMem(id_c + ExprInt(0x2, 32), 32)), ExprMem(id_c + ExprInt(0x2, 32), 32))
+
+        # Test del symbol
+        del sb.symbols[id_a]
+        sb.dump()
+        del sb.symbols[ExprMem(id_a, 8)]
+        print "*"*40, 'Orig:'
+        sb.dump()
+
+        sb_cp = sb.symbols.copy()
+        print "*"*40, 'Copy:'
+        sb_cp.dump()
+
+        # Add symbol at address limit
+        sb.apply_change(ExprMem(ExprInt(0xFFFFFFFE, 32), 32), id_c)
+        sb.dump()
+        found = False
+        for dst, src in sb.symbols.iteritems():
+            if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_c:
+                found = True
+        assert found
+
+
+        # Add symbol at address limit
+        sb.apply_change(ExprMem(ExprInt(0x7FFFFFFE, 32), 32), id_c)
+        sb.dump()
+        found = False
+        for dst, src in sb.symbols.iteritems():
+            if dst == ExprMem(ExprInt(0x7FFFFFFE, 32), 32) and src == id_c:
+                found = True
+        assert found
+
+
+
+        # Add truncated symbol at address limit
+        sb.apply_change(ExprMem(ExprInt(0xFFFFFFFC, 32), 64), id_e)
+        # Revert parts of memory
+        sb.apply_change(ExprMem(ExprInt(0xFFFFFFFC, 32), 16), ExprMem(ExprInt(0xFFFFFFFC, 32), 16))
+        sb.apply_change(ExprMem(ExprInt(0x2, 32), 16), ExprMem(ExprInt(0x2, 32), 16))
+        sb.dump()
+        found = False
+        for dst, src in sb.symbols.iteritems():
+            if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_e[16:48]:
+                found = True
+        assert found
+
+
+        sb_empty = SymbolicExecutionEngine(ir_x86_32(), {})
+        sb_empty.dump()
+
+
+        # Test memory full
+        print 'full'
+        arch_addr8 = ir_x86_32()
+        # Hack to obtain tiny address space
+        arch_addr8.addrsize = 5
+        sb_addr8 = SymbolicExecutionEngine(arch_addr8, {})
+        sb_addr8.dump()
+        # Fulfill memory
+        sb_addr8.apply_change(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256))
+        sb_addr8.dump()
+        variables = sb_addr8.symbols.items()
+        assert variables == [(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256))]
+
+        print sb_addr8.symbols.symbols_mem
+
+        sb_addr8.apply_change(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256))
+        sb_addr8.dump()
+        variables = sb_addr8.symbols.items()
+        assert variables == [(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256))]
+        print sb_addr8.symbols.symbols_mem
+
+        print 'dump'
+        sb_addr8.symbols.symbols_mem.dump()
+
+
+        sb.dump()
+        try:
+            del sb.symbols.symbols_mem[ExprMem(ExprInt(0xFFFFFFFF, 32), 32)]
+        except KeyError:
+            # ok
+            pass
+        else:
+            raise RuntimeError("Should raise error!")
+
+
+        del sb.symbols.symbols_mem[ExprMem(ExprInt(0xFFFFFFFF, 32), 16)]
+        sb.dump()
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0xFFFFFFFE, 32), 32)),
+                         ExprCompose(id_e[16:24], ExprMem(ExprInt(0xFFFFFFFF, 32), 16), id_e[40:48]))
+        sb.symbols.symbols_mem.delete_partial(ExprMem(ExprInt(0xFFFFFFFF, 32), 32))
+
+        self.assertEqual(sb.eval_expr(ExprMem(ExprInt(0xFFFFFFFE, 32), 32)),
+                         ExprCompose(id_e[16:24], ExprMem(ExprInt(0xFFFFFFFF, 32), 24)))
+
+        sb.dump()
+
+        assert ExprMem(ExprInt(0xFFFFFFFE, 32), 8) in sb.symbols
+        assert ExprMem(ExprInt(0xFFFFFFFE, 32), 32) not in sb.symbols
+        assert sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFE, 32), 32))
+        assert not sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFF, 32), 8))
 
-        # state
-        self.assertEqual(e.as_assignblock().get_r(), set([id_x, id_y]))
+        assert sb_addr8.symbols.keys() == [ExprMem(ExprInt(0x5, 5), 256)]
 
 
 if __name__ == '__main__':