about summary refs log tree commit diff stats
path: root/test/analysis/dse.py
blob: 59fc2b59ddba082c1e5d099b3172058b83def648 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import sys
import os
from pdb import pm

from miasm2.core.cpu import ParseAst
from miasm2.arch.x86.arch import mn_x86, base_expr, variable
from miasm2.core import parse_asm
from miasm2.expression.expression import *
from miasm2.core import asmblock
from elfesteem.strpatchwork import StrPatchwork
from miasm2.analysis.machine import Machine
from miasm2.jitter.csts import *
from miasm2.analysis.dse import DSEEngine

reg_and_id = dict(mn_x86.regs.all_regs_ids_byname)

class DSE_test(object):
    """Inspired from TEST/ARCH/X86

    Test the symbolic execution correctly follow generated labels
    """
    TXT = '''
    main:
        SHL         EDX, CL
        RET
    '''

    arch_name = "x86_32"
    arch_attrib = 32
    ret_addr = 0x1337beef

    run_addr = 0x0

    def __init__(self, jitter_engine):
        self.machine = Machine(self.arch_name)
        self.myjit = self.machine.jitter(jitter_engine)
        self.myjit.init_stack()

        self.myjit.jit.log_regs = False
        self.myjit.jit.log_mn = False

    def init_machine(self):
        self.myjit.vm.add_memory_page(self.run_addr, PAGE_READ | PAGE_WRITE, self.assembly)
        self.myjit.push_uint32_t(self.ret_addr)
        self.myjit.add_breakpoint(self.ret_addr, lambda x:False)

    def prepare(self):
        self.myjit.cpu.ECX = 4
        self.myjit.cpu.EDX = 5

        self.dse = DSEEngine(self.machine)
        self.dse.attach(self.myjit)

    def __call__(self):
        self.asm()
        self.init_machine()
        self.prepare()
        self.run()
        self.check()

    def run(self):

        self.myjit.init_run(self.run_addr)
        self.myjit.continue_run()

        assert(self.myjit.pc == self.ret_addr)

    def asm(self):
        blocks, symbol_pool = parse_asm.parse_txt(mn_x86, self.arch_attrib, self.TXT,
                                                  symbol_pool=self.myjit.ir_arch.symbol_pool)


        # fix shellcode addr
        symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
        s = StrPatchwork()
        patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool)
        for offset, raw in patches.items():
            s[offset] = raw

        s = str(s)
        self.assembly = s

    def check(self):
        regs = self.dse.ir_arch.arch.regs
        value = self.dse.eval_expr(regs.EDX)
        # The expected value should contains '<<', showing it has been in the
        # corresponding generated label
        expected = ExprOp('<<', regs.EDX,
                          ExprCompose(regs.ECX[0:8],
                                      ExprInt(0x0, 24)) & ExprInt(0x1F, 32))
        assert value == expected

if __name__ == "__main__":
    [test(*sys.argv[1:])() for test in [DSE_test]]