Beispiel #1
0
def setup():
    global qemu
    global avatar
    global fake_target

    arch = setup_ARCH()

    avatar = Avatar(arch=arch, output_directory=test_dir)
    qemu = QemuTarget(
        avatar,
        name='qemu_test',
        #firmware="./tests/binaries/qemu_arm_test",
        firmware='%s/firmware' % test_dir,
    )
    fake_target = FakeTarget()

    dev1 = avatar.add_memory_range(0x101f2000,
                                   0x1000,
                                   'dev1',
                                   forwarded=True,
                                   forwarded_to=fake_target,
                                   qemu_name='avatar-rmemory')

    mem1 = avatar.add_memory_range(
        rom_addr,
        0x1000,
        'mem1',
        #file='%s/tests/binaries/qemu_arm_test' %
        #   os.getcwd())
        file='%s/firmware' % test_dir)
Beispiel #2
0
def setup():
    global qemu
    global avatar
    avatar = Avatar()
    qemu = QemuTarget(avatar,
                      name='qemu_test',
                      firmware="./tests/binaries/qemu_arm_test",
                      gdb_executable=GDB_EXECUTABLE,
                      executable=QEMU_EXECUTABLE)
    fake_target = FakeTarget()

    dev1 = avatar.add_memory_range(0x101f2000,
                                   0x1000,
                                   'dev1',
                                   forwarded=True,
                                   forwarded_to=fake_target,
                                   qemu_name='avatar-rmemory')

    mem1 = avatar.add_memory_range(0x8000000,
                                   0x1000,
                                   'mem1',
                                   file='%s/tests/binaries/qemu_arm_test' %
                                   os.getcwd())
Beispiel #3
0
def setup():
    global qemu
    global avatar
    global fake_target
    avatar = Avatar(output_directory='/tmp/testava')
    qemu = QemuTarget(
        avatar,
        name='qemu_test',
        firmware="./tests/binaries/qemu_arm_test",
    )
    fake_target = FakeTarget()

    dev1 = avatar.add_memory_range(0x101f2000,
                                   0x1000,
                                   'dev1',
                                   forwarded=True,
                                   forwarded_to=fake_target,
                                   qemu_name='avatar-rmemory')

    mem1 = avatar.add_memory_range(0x8000000,
                                   0x1000,
                                   'mem1',
                                   file='%s/tests/binaries/qemu_arm_test' %
                                   os.getcwd())
avatar = Avatar(arch=ARMV7M, output_directory='/tmp/panda_rr')
avatar.load_plugin('orchestrator')

nucleo = avatar.add_target(OpenOCDTarget,
                           openocd_script='nucleo-l152re.cfg',
                           gdb_executable="arm-none-eabi-gdb",
                           gdb_port=1234)

panda = avatar.add_target(PandaTarget,
                          executable='panda/qemu-system-arm',
                          gdb_executable="arm-none-eabi-gdb",
                          gdb_port=1235)

rom = avatar.add_memory_range(0x08000000,
                              0x1000000,
                              'rom',
                              file='firmware.bin')

ram = avatar.add_memory_range(0x20000000, 0x14000, 'ram')
mmio = avatar.add_memory_range(0x40000000,
                               0x1000000,
                               'mmio',
                               forwarded=True,
                               forwarded_to=nucleo)

avatar.init_targets()

avatar.start_target = nucleo
avatar.add_transition(0x8005104, nucleo, panda, synced_ranges=[ram], stop=True)
avatar.start_orchestration()
Beispiel #5
0
class PSPEmulator():

    custom_memory = bytearray(2**32)

    accessed_mem = {}

    verbose = True

    interactive = False

    ccp_cmd = {"process": False, "start": 0x0, "end": 0x0}
    qemu = None

    def __init__(self):
        self.avatar = None
        self.close = False
        self.trace_parse = None
        self.trace_file = None
        self.ignored_addresses = set()

    def init(self,
             entry_addr,
             qemu_bin,
             qemu_args,
             verbose=False,
             interactive=False):
        self.avatar = Avatar(output_directory=AVATAR_DIR)
        self.avatar.log.setLevel('DEBUG')

        PSPEmulator.verbose = verbose
        PSPEmulator.interactive = interactive

        PSPEmulator.qemu = self.avatar.add_target(
            QemuTarget,
            name='qemu1',
            executable=qemu_bin,
            gdb_executable="arm-eabi-gdb",
            additional_args=qemu_args)
        PSPEmulator.qemu.cpu_model = 'cortex-a8'

        self.avatar.watchmen.add_watchman('RemoteMemoryRead',
                                          'before',
                                          self.before_remote_memory_access,
                                          is_async=False)
        self.avatar.watchmen.add_watchman('RemoteMemoryWrite',
                                          'before',
                                          self.before_remote_memory_access,
                                          is_async=False)

        PSPEmulator.qemu.entry_address = entry_addr

    def load_file(self, address, mem_size, filename, offset, file_size):
        self.avatar.add_memory_range(address,
                                     mem_size,
                                     file=filename,
                                     file_offset=offset,
                                     file_bytes=file_size)

    def load_custom_mem(self, address, filename, offset=0, size=0):
        f = open(filename, 'rb')
        if offset != 0:
            f.seek(offset)

        if size != 0:
            data = f.read(size)
        else:
            data = f.read()

        self.custom_memory[address:address + len(data)] = data

    def add_memory_range(self, start, end, permissions='rw-'):
        if ((end - start) % 0x1000) != 0:
            print("[PSPEmulator] ERROR: memory ranges must be page aligned"
                  "(0x%.8x)" % start)
        self.avatar.add_memory_range(start,
                                     end - start,
                                     permission=permissions)

    def set_memory_value(self, address, value, size=4):
        if size != 1 and size != 4:
            print("[PSPEmulator] ERROR: Only 1 or 4 bytes are supported")
            return

        if size == 1:
            PSPEmulator.custom_memory[address] = value
        elif size == 4:
            bval = (value).to_bytes(4, byteorder='big')
            PSPEmulator.custom_memory[address] = bval[0]
            PSPEmulator.custom_memory[address + 1] = bval[1]
            PSPEmulator.custom_memory[address + 2] = bval[2]
            PSPEmulator.custom_memory[address + 3] = bval[3]

    def qemu_init(self):
        PSPEmulator.qemu.init()

    def set_breakpoint(self, address):
        PSPEmulator.qemu.set_breakpoint(address)

    def watch_memory_range(self, start, end, permissions='rw-'):
        if ((end - start) % 0x1000) != 0:
            print("[PSPEmulator] ERROR: watched memory ranges must be page"
                  "aligned (0x%.8x)" % start)
            return
        self.avatar.add_memory_range(start,
                                     end - start,
                                     emulate=CustomMemoryPeripheral,
                                     permission=permissions)

    def add_virtual_ccp(self, address):
        if not PSPEmulator.qemu:
            print("[PSPEmulator] ERROR: PSPEmulator not initialized yet. Call"
                  "init() first")
            return
        self.avatar.add_memory_range(address,
                                     0x1000,
                                     emulate=VirtualCCP,
                                     permission='rw-')
        # self.ignored_addresses.add(address)

    def add_misc_dev(self, address):
        if not PSPEmulator.qemu:
            print("[PSPEmulator] ERROR: PSPEmulator not initialized yet. Call"
                  "init() first")
            return
        self.avatar.add_memory_range(address,
                                     0x1000,
                                     emulate=VirtMisc,
                                     permission='rw-')

    def add_virtual_timer(self, address):
        if not PSPEmulator.qemu:
            print("[PSPEmulator] ERROR: PSPEmulator not initialized yet. Call"
                  "init() first")
            return
        self.avatar.add_memory_range(address,
                                     0x1000,
                                     name="VirtualTimer",
                                     emulate=VirtualTimer,
                                     permission='rw-')
        # self.ignored_addresses.add(address)

    def watch_memory(self, address=None, size=None):
        # TODO: Automatically configure "remaining", i.e. not yet configured
        #       memory ranges to be backed by our CustomMemoryPeripheral
        print(self.avatar.memory_ranges)
        for interval in self.avatar.memory_ranges:
            print("0x%x 0x%x" % (interval.begin, interval.end))

    def __del__(self):
        self.avatar.shutdown()
        if self.trace_file and self.trace_parse:
            command = 'python2.7 %s %s /tmp/trace > /tmp/parsed' % \
                      (self.trace_parse, self.trace_file)
            print("[PSPEmulator] Calling %s" % command)
            os.system(command)

    def exit(self):
        self.close = True
        self.__del__()

    def disconnect_gdb(self):
        PSPEmulator.qemu.gdb.remote_disconnect()

    def connect_gdb(self):
        PSPEmulator.qemu.gdb.remote_connect()

    def run(self):
        while not self.close:
            if PSPEmulator.qemu.state != TargetStates.EXITED:
                PSPEmulator.qemu.cont()
            PSPEmulator.qemu.wait(TargetStates.EXITED | TargetStates.STOPPED)
            if PSPEmulator.qemu.state == TargetStates.STOPPED:
                if PSPEmulator.ccp_cmd["process"] is True:
                    print("[ccp_dev] Parsing new cmd at pc=0x%.8x" %
                          PSPEmulator.qemu.read_register("pc"))
                    self.print_ccp_cmds(PSPEmulator.ccp_cmd["start"],
                                        PSPEmulator.ccp_cmd["end"])
                    PSPEmulator.ccp_cmd["process"] = False
                else:
                    embed(banner1="QEMU entered STOPPED state at pc=0x%.8x" %
                          PSPEmulator.qemu.read_register("pc"))
            else:
                print("[PSPEmulator] Qemu exited with state: %s" %
                      str(PSPEmulator.qemu.state))
                self.exit()

    def print_ccp_cmds(self, start, end):

        cmds = (end - start) // 0x20
        for e in range(0x0, cmds):
            dwords = [
                PSPEmulator.qemu.read_memory(i, 0x4)
                for i in range(start + (e * 0x20), start + (e * 0x20) +
                               0x20, 0x4)
            ]
            print("\n[ccp_dev] Processing ccp cmd %d" % e)
            cmt, engine = ccp_parse.parse_dword0(dwords[0])
            print("[ccp_dev]\t %s" % cmt)
            print("[ccp_dev]\t Length of src data 0x%x" % dwords[1])
            print("[ccp_dev]\t Src ptr 0x%x" % dwords[2])
            print("[ccp_dev]\t %s" % ccp_parse.parse_dword3(dwords[3]))
            print("[ccp_dev]\t %s" % ccp_parse.parse_dword4(engine, dwords[4]))
            print("[ccp_dev]\t %s" % ccp_parse.parse_dword5(engine, dwords[5]))
            print("[ccp_dev]\t Low 32bit key ptr: 0x%x" % dwords[6])
            print("[ccp_dev]\t High 16bit key ptr + mem type: 0x%x" %
                  dwords[7])
            print()

    def swap32(i):
        return struct.unpack("<I", struct.pack(">I", i))[0]

    def enable_tracing(self, trace_parse, trace_file):
        self.trace_file = trace_file
        self.trace_parse = trace_parse
        PSPEmulator.qemu.qmp.execute_command('trace-event-set-state', {
            'name': 'exec_tb',
            'enable': True
        })
        PSPEmulator.qemu.qmp.execute_command('trace-event-set-state', {
            'name': 'guest_mem_before_exec',
            'enable': True
        })

    def before_remote_memory_access(self, avatar, remote_memory_msg, **kwargs):
        address = remote_memory_msg.address
        pc = remote_memory_msg.pc

        # Ignore pages belonging to emulated devices
        if (address & 0xFFFFF000) in self.ignored_addresses:
            return

        read_or_write = ''
        if isinstance(remote_memory_msg, RemoteMemoryReadMessage):
            read_or_write = 'read'
        else:  # if isinstance(remote_memory_msg, RemoteMemoryWriteMessage):
            read_or_write = 'write'

        # if not PSPEmulator.ccp_cmd["process"]:
        #     print('[custom_memory] New %s at 0x%.8x from PC: 0x%.8x' % (read_or_write, address, pc))

        if address not in PSPEmulator.accessed_mem:
            PSPEmulator.accessed_mem[address] = set()

        # print("BeforeMemaccess: pc 0x%.8x addr 0x%.8x" % (pc, address))

        PSPEmulator.accessed_mem[address].add((pc, read_or_write))

    def print_custom_memory(self):
        for i in PSPEmulator.accessed_mem:
            val = int.from_bytes(PSPEmulator.custom_memory[i:i + 4], 'little')
            print('\t0x%.8x: \t0x%.8x \taccessed_by: %s' %
                  (i, val,
                   repr([
                       v[1] + ':' + hex(v[0])
                       for v in PSPEmulator.accessed_mem[i]
                   ])))
Beispiel #6
0
class QemuTargetTestCase(unittest.TestCase):
    def setUp(self):
        self.setup_env()

    def setup_env(self, gdb_unix_socket_path=None):
        self.rom_addr = None
        self.arch = None
        self.setup_arch()

        self.avatar = Avatar(arch=self.arch,
                             output_directory=TEST_DIR,
                             configure_logging=False)
        self.qemu = QemuTarget(
            self.avatar,
            name='qemu_test',
            #firmware="./tests/binaries/qemu_arm_test",
            firmware='%s/firmware' % TEST_DIR,
            gdb_unix_socket_path=gdb_unix_socket_path,
        )
        self.fake_target = FakeTarget()

        dev1 = self.avatar.add_memory_range(0x101f2000,
                                            0x1000,
                                            'dev1',
                                            forwarded=True,
                                            forwarded_to=self.fake_target,
                                            qemu_name='avatar-rmemory')

        mem1 = self.avatar.add_memory_range(
            self.rom_addr,
            0x1000,
            'mem1',
            #file='%s/tests/binaries/qemu_arm_test' %
            #   os.getcwd())
            file='%s/firmware' % TEST_DIR)

    def setup_arch(self):

        ARCH = os.getenv('AVATAR2_ARCH')

        if ARCH == 'ARM':
            self.arch = ARM
            self.rom_addr = ARM_BASE_ADDR
            firmware = ARM_BIN

        elif ARCH == 'MIPS':
            self.arch = MIPS_24KF
            self.rom_addr = MIPS_BASE_ADDR
            firmware = MIPS_BIN

        else:
            self.assertTrue(False, 'Invalid Achitecture')

        if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR)
        with open('%s/firmware' % TEST_DIR, 'wb') as f:
            f.write(firmware)

    def tearDown(self):
        self.qemu.shutdown()

    def test_initilization(self):
        self.qemu.init()
        self.qemu.wait()
        self.assertEqual(self.qemu.state, TargetStates.STOPPED,
                         self.qemu.state)

    def test_step(self):
        self.qemu.init()
        self.qemu.wait()

        self.qemu.regs.pc = self.rom_addr
        self.qemu.step()

        pc = self.qemu.regs.pc
        self.assertEqual(pc, self.rom_addr + 4, pc)

    def test_memory_read(self):
        self.qemu.init()
        self.qemu.wait()

        mem = self.qemu.read_memory(self.rom_addr, 4)

        if self.arch == ARM:
            self.assertEqual(mem, 0xe3a0101e, mem)

        elif self.arch == MIPS_24KF:
            #self.assertEqual(mem, 0x2409001e, mem)
            self.assertEqual(mem, 0x1e000924, mem)
        else:
            self.assertTrue(False, "Architecture not supported")

    def test_memory_write(self):
        self.qemu.init()
        self.qemu.wait()

        self.qemu.write_memory(self.rom_addr, 4, 0x41414141)
        mem = self.qemu.read_memory(self.rom_addr, 4)
        self.assertEqual(mem, 0x41414141, mem)

    def test_remote_memory_write(self):
        self.qemu.init()
        self.qemu.wait()
        remote_memory_write = self.qemu.write_memory(0x101f2000, 4, 0x41414141)
        self.assertEqual(remote_memory_write, True)

        addr = self.fake_target.fake_write_addr
        size = self.fake_target.fake_write_size
        val = self.fake_target.fake_write_val
        self.assertEqual(addr, 0x101f2000, addr)
        self.assertEqual(size, 4, size)
        self.assertEqual(val, 0x41414141, val)

    def test_remote_memory_read(self):
        self.qemu.init()
        self.qemu.wait()
        self.assertEqual(self.qemu.state, TargetStates.STOPPED,
                         self.qemu.state)

        remote_memory_read = self.qemu.read_memory(0x101f2000, 4)
        self.assertEqual(remote_memory_read, 0xdeadbeef, remote_memory_read)