Esempio n. 1
0
    def bp_attach(self, jitter):
        """Attach a DSE in the current jitter"""
        self.dse = DSEEngine(self.machine, self.loc_db)
        self.dse.attach(self.myjit)
        self.dse.update_state_from_concrete()
        self.dse.update_state({
            self._regs.EBX: self._testid,
        })

        # Additional call to the exec callback is necessary, as breakpoints are
        # honored AFTER exec callback
        jitter.exec_cb(jitter)

        return True
Esempio n. 2
0
File: dse.py Progetto: cea-sec/miasm
    def bp_attach(self, jitter):
        """Attach a DSE in the current jitter"""
        self.dse = DSEEngine(self.machine)
        self.dse.attach(self.myjit)
        self.dse.update_state_from_concrete()
        self.dse.update_state({
            self._regs.EBX: self._testid,
        })

        # Additional call to the exec callback is necessary, as breakpoints are
        # honored AFTER exec callback
        jitter.exec_cb(jitter)

        return True
Esempio n. 3
0
File: dse.py Progetto: zyc1314/miasm
class DSEAttachInBreakpoint(DSETest):

    """
    Test that DSE is "attachable" in a jitter breakpoint
    """
    TXT = '''
    main:
        MOV    EAX, 5
        ADD    EBX, 6
        INC    EBX
        RET
    '''

    def __init__(self, *args, **kwargs):
        super(DSEAttachInBreakpoint, self).__init__(*args, **kwargs)
        self._dse = None
        ircls = self.machine.ir
        self._regs = ircls().arch.regs
        self._testid = ExprId("TEST", self._regs.EBX.size)

    def bp_attach(self, jitter):
        """Attach a DSE in the current jitter"""
        self.dse = DSEEngine(self.machine)
        self.dse.attach(self.myjit)
        self.dse.update_state_from_concrete()
        self.dse.update_state({
            self._regs.EBX: self._testid,
        })

        # Additional call to the exec callback is necessary, as breakpoints are
        # honored AFTER exec callback
        jitter.exec_cb(jitter)

        return True

    def prepare(self):
        pass

    def init_machine(self):
        super(DSEAttachInBreakpoint, self).init_machine()
        self.myjit.add_breakpoint(5, self.bp_attach)  # On ADD EBX, 6

    def check(self):
        value = self.dse.eval_expr(self._regs.EBX)
        # EBX = TEST
        # ADD EBX, 6
        # INC EBX
        # -> EBX_final = TEST + 7
        assert value == self._testid + ExprInt(7, self._regs.EBX.size)
Esempio n. 4
0
            elif dst in vm_registers_symb and vm_registers_symb[dst] == ExprId(
                    "VM_PC", 64):
                vm_instr += "VM_PC = {}\n".format(dse.eval_expr(src))

    print(vm_instr.strip())

    # remove callback
    del dse.instrumentation[NEXT_ADDR]

    return True


parser = Sandbox_Linux_x86_64.parser("Disassembler for keykoolol challenge")
parser.add_argument("filename", help="Challenge filename")
options = parser.parse_args()

sb = Sandbox_Linux_x86_64(options.filename, options, globals())

dse = DSEEngine(sb.machine)
dse.add_lib_handler(sb.libs, globals())

DISPATCHER_ADDR = 0xa5D
NEXT_ADDR = 0xa77

vm_registers_symb = {}
already_disass = {}

dse.add_instrumentation(DISPATCHER_ADDR, symbolize_vm)

sb.run()
Esempio n. 5
0
    def _process_func(self, func):
        dse = DSEEngine(self.sb.machine)
        dse.attach(
            self.sb.jitter
        )  # needs to be attached before setting exec_cb to overwrite it with ours
        bak_snap = dse.take_snapshot()
        dse.add_lib_handler(self.sb.libs, globals())
        occurances = {}
        addr = func.loc_db.get_location_offset(LocKey(0))
        asmb = func.loc_key_to_block(LocKey(0))
        strings = set()
        self.sb.jitter.exec_cb = lambda x: self._exec_callback(
            dse, func, occurances, x, strings, self._get_strings_from_dse)
        self.sb.jitter.init_run(addr)
        try:
            self.sb.jitter.run_until(asmb.lines[-1].offset)
        except:
            pass
        dse.update_state_from_concrete()
        initial_snap = dse.take_snapshot()  # prepared initial context
        strings.update(self._get_strings_from_dse(dse))
        dse.restore_snapshot(initial_snap)
        for loc_key in func.walk_breadth_first_forward(LocKey(0)):
            addr = func.loc_db.get_location_offset(loc_key)
            if not addr:
                continue
            occurances.clear()
            self.sb.jitter.init_run(addr)
            dse.symb.reset_modified()  # wipe errors from previous execution
            try:
                self.sb.jitter.continue_run()
            except Exception as e:
                pass
            dse.update_state_from_concrete()
            strings.update(self._get_strings_from_dse(dse))
            dse.restore_snapshot(initial_snap)

        dse.restore_snapshot(bak_snap)
        strings = self._get_top_level_strings(strings)
        return strings
Esempio n. 6
0
    def prepare(self):
        self.myjit.cpu.ECX = 4
        self.myjit.cpu.EDX = 5

        self.dse = DSEEngine(self.machine, self.loc_db)
        self.dse.attach(self.myjit)
Esempio n. 7
0
class DSETest(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.loc_db = LocationDB()
        self.machine = Machine(self.arch_name)
        jitter = self.machine.jitter
        self.myjit = jitter(self.loc_db, jitter_engine)
        self.myjit.init_stack()

        self.myjit.set_trace_log()

        self.dse = None
        self.assembly = None

    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.loc_db)
        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):
        mn_x86 = self.machine.mn
        asmcfg = parse_asm.parse_txt(mn_x86, self.arch_attrib, self.TXT,
                                     self.loc_db)

        # fix shellcode addr
        self.loc_db.set_location_offset(self.loc_db.get_name_location("main"),
                                        0x0)
        output = StrPatchwork()
        patches = asm_resolve_final(mn_x86, asmcfg)
        for offset, raw in viewitems(patches):
            output[offset] = raw

        self.assembly = bytes(output)

    def check(self):
        regs = self.dse.lifter.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
Esempio n. 8
0
File: dse.py Progetto: cea-sec/miasm
    def prepare(self):
        self.myjit.cpu.ECX = 4
        self.myjit.cpu.EDX = 5

        self.dse = DSEEngine(self.machine)
        self.dse.attach(self.myjit)
Esempio n. 9
0
File: dse.py Progetto: cea-sec/miasm
class DSETest(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)
        jitter = self.machine.jitter
        self.myjit = jitter(jitter_engine)
        self.myjit.init_stack()

        self.myjit.set_trace_log()

        self.dse = None
        self.assembly = None

    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):
        mn_x86 = self.machine.mn
        blocks, loc_db = parse_asm.parse_txt(
            mn_x86,
            self.arch_attrib,
            self.TXT,
            loc_db=self.myjit.ir_arch.loc_db
        )

        # fix shellcode addr
        loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
        output = StrPatchwork()
        patches = asm_resolve_final(mn_x86, blocks, loc_db)
        for offset, raw in viewitems(patches):
            output[offset] = raw

        self.assembly = bytes(output)

    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