def initialize(state): ''' Synchronize the stack and register state (manticore->qemu) ''' logger.debug("Copying {} bytes in the stack..".format(stack_top - state.cpu.SP)) stack_bottom = min(state.cpu.SP, gdb.getR('SP')) for address in range(stack_bottom, stack_top): b = state.cpu.read_int(address, 8) gdb.setByte(address, chr(b)) logger.debug("Done") # Qemu fd's start at 5, ours at 3. Add two filler fds mcore_stdout = state.platform.files[1] state.platform.files.append(mcore_stdout) state.platform.files.append(mcore_stdout) # Sync gdb's regs for gdb_reg in gdb.getCanonicalRegisters(): if gdb_reg.endswith('psr'): mcore_reg = 'APSR' else: mcore_reg = gdb_reg.upper() value = state.cpu.read_register(mcore_reg) gdb.setR(gdb_reg, value)
def post_mcore(state, last_instruction): ''' Handle syscalls (import memory) and bail if we diverge ''' global in_helper # Synchronize qemu state to manticore's after a system call if last_instruction.mnemonic.lower() == 'svc': # Syncronize all writes that have happened writes = state.cpu.memory.pop_record_writes() if writes: logger.debug("Got %d writes", len(writes)) for addr, val in writes: gdb.setByte(addr, val[0]) # Write return val to gdb gdb_r0 = gdb.getR('R0') if gdb_r0 != state.cpu.R0: logger.debug("Writing 0x{:x} to R0 (overwriting 0x{:x})".format( state.cpu.R0, gdb.getR('R0'))) for reg in state.cpu.canonical_registers: if reg.endswith('PSR') or reg in ('R15', 'PC'): continue val = state.cpu.read_register(reg) gdb.setR(reg, val) # Ignore Linux kernel helpers if (state.cpu.PC >> 16) == 0xffff: in_helper = True return # If we executed a few instructions of a helper, we need to sync Manticore's # state to GDB as soon as we stop executing a helper. if in_helper: for reg in state.cpu.canonical_registers: if reg.endswith('PSR'): continue # Don't sync pc if reg == 'R15': continue gdb.setR(reg, state.cpu.read_register(reg)) in_helper = False if cmp_regs(state.cpu): cmp_regs(state.cpu, should_print=True) state.abandon()
def sync_svc(state): ''' Mirror some service calls in manticore. Happens after qemu executed a SVC instruction, but before manticore did. ''' syscall = state.cpu.R7 # Grab idx from manticore since qemu could have exited name = linux_syscalls.armv7[syscall] logger.debug("Syncing syscall: {}".format(name)) try: # Make sure mmap returns the same address if 'mmap' in name: returned = gdb.getR('R0') logger.debug("Syncing mmap ({:x})".format(returned)) state.cpu.write_register('R0', returned) if 'exit' in name: return except ValueError: for reg in state.cpu.canonical_registers: print '{}: {:x}'.format(reg, state.cpu.read_register(reg)) raise
def sync_svc(state): """ Mirror some service calls in manticore. Happens after qemu executed a SVC instruction, but before manticore did. """ syscall = state.cpu.R7 # Grab idx from manticore since qemu could have exited name = linux_syscalls.armv7[syscall] logger.debug(f"Syncing syscall: {name}") try: # Make sure mmap returns the same address if "mmap" in name: returned = gdb.getR("R0") logger.debug(f"Syncing mmap ({returned:x})") state.cpu.write_register("R0", returned) if "exit" in name: return except ValueError: for reg in state.cpu.canonical_registers: print(f"{reg}: {state.cpu.read_register(reg):x}") raise