示例#1
0
def start_qemu(qemu_exec,
               image,
               spice_port,
               qmp_filename,
               incoming_port=None,
               extra_args=[]):
    incoming_args = []
    if incoming_port:
        incoming_args = ("-incoming tcp::%s" % incoming_port).split()
    args = ([
        qemu_exec, "-qmp",
        "unix:%s,server,nowait" % qmp_filename, "-spice",
        "disable-ticketing,port=%s" % spice_port
    ] + incoming_args + extra_args)
    if os.path.exists(image):
        args += [
            "-m", "512", "-drive",
            "file=%s,index=0,media=disk,cache=unsafe" % image, "-snapshot"
        ]
    proc = Popen(args, executable=qemu_exec, stdin=PIPE, stdout=PIPE)
    while not os.path.exists(qmp_filename):
        time.sleep(0.1)
    proc.qmp_filename = qmp_filename
    proc.qmp = qmp.QEMUMonitorProtocol(qmp_filename)
    while True:
        try:
            proc.qmp.connect()
            break
        except socket.error, err:
            pass
示例#2
0
    def snap(self, dbg, snap_uri):
        log.debug(
            "%s: qemudisk.Qemudisk.snap: vdi_uuid %s pid %d qmp_sock %s snap_uri %s"
            % (dbg, self.vdi_uuid, self.pid, self.qmp_sock, snap_uri))

        if self.vdi_type != 'qcow2':
            raise Exception('Incorrect VDI type')

        _qmp_ = qmp.QEMUMonitorProtocol(self.qmp_sock)
        _qmp_.connect()

        args = {
            'driver': 'qcow2',
            'cache': {
                'direct': True,
                'no-flush': True
            },
            #'discard': 'unmap',
            'file': {
                'driver': 'rbd',
                'pool': utils.get_pool_name_by_uri(dbg, snap_uri),
                'image': utils.get_image_name_by_uri(dbg, snap_uri)
            },
            # 'node-name': RBD_NODE_NAME},
            'node-name': SNAP_NODE_NAME,
            'backing': ''
        }

        _qmp_.command('blockdev-add', **args)

        args = {'node': ROOT_NODE_NAME, 'overlay': SNAP_NODE_NAME}

        _qmp_.command('blockdev-snapshot', **args)

        _qmp_.close()
示例#3
0
    def __init__(self, log, socket, negotiate=True):
        ''' regular QMP for all vm commands '''
        self._qmp = qmp.QEMUMonitorProtocol(socket)
        self._qmp.connect(negotiate=negotiate)

        self._log = log
        self._events = []
示例#4
0
 def quit(self, dbg):
     log.debug(
         "%s: qemudisk.Qemudisk.quit: vdi_uuid %s pid %d qmp_sock %s" %
         (dbg, self.vdi_uuid, self.pid, self.qmp_sock))
     _qmp_ = qmp.QEMUMonitorProtocol(self.qmp_sock)
     _qmp_.connect()
     _qmp_.command('quit')
     _qmp_.close()
示例#5
0
 def launch(self):
     '''Launch the VM and establish a QMP connection'''
     devnull = open('/dev/null', 'rb')
     qemulog = open(self._qemu_log_path, 'wb')
     try:
         self._qmp = qmp.QEMUMonitorProtocol(self._monitor_path, server=True)
         self._popen = subprocess.Popen(self._args, stdin=devnull, stdout=qemulog,
                                        stderr=subprocess.STDOUT)
         self._qmp.accept()
     except:
         os.remove(self._monitor_path)
         raise
示例#6
0
    def open(self, dbg):
        log.debug(
            "%s: qemudisk.Qemudisk.open: vdi_uuid %s pid %d qmp_sock %s" %
            (dbg, self.vdi_uuid, self.pid, self.qmp_sock))

        args = {
            'driver': self.vdi_type,
            'cache': {
                'direct': True,
                'no-flush': True
            },
            #'discard': 'unmap',
            'file': {
                'driver':
                'rbd',
                'pool':
                "%s%s" % (utils.RBDPOOL_PREFIX, self.sr_uuid),
                'image':
                "%s%s" % (utils.VDI_PREFIXES[self.vdi_type], self.vdi_uuid)
            },
            #'node-name': RBD_NODE_NAME},
            "node-name": ROOT_NODE_NAME
        }

        log.debug("%s: qemudisk.Qemudisk.open: args: %s" % (dbg, args))

        _qmp_ = qmp.QEMUMonitorProtocol(self.qmp_sock)
        _qmp_.connect()

        try:
            _qmp_.command("blockdev-add", **args)

            # Start an NBD server exposing this blockdev
            _qmp_.command("nbd-server-start",
                          addr={
                              'type': 'unix',
                              'data': {
                                  'path': self.nbd_sock
                              }
                          })
            _qmp_.command("nbd-server-add",
                          device=ROOT_NODE_NAME,
                          writable=True)
            log.debug("%s: qemudisk.Qemudisk.open: RBD Image opened: %s" %
                      (dbg, args))
        except Exception:
            raise Volume_does_not_exist(self.vdi_uuid)
        finally:
            _qmp_.close()
示例#7
0
    def resume(self, dbg):
        log.debug(
            "%s: qemudisk.Qemudisk.resume: vdi_uuid %s pid %d qmp_sock %s" %
            (dbg, self.vdi_uuid, self.pid, self.qmp_sock))

        _qmp_ = qmp.QEMUMonitorProtocol(self.qmp_sock)
        _qmp_.connect()

        try:
            # Resume IO on blockdev
            args = {"device": ROOT_NODE_NAME}
            _qmp_.command("x-blockdev-resume", **args)
        except Exception:
            raise Volume_does_not_exist(self.vdi_uuid)
        finally:
            _qmp_.close()
示例#8
0
    def close(self, dbg):
        log.debug(
            "%s: qemudisk.Qemudisk.close: vdi_uuid %s pid %d qmp_sock %s" %
            (dbg, self.vdi_uuid, self.pid, self.qmp_sock))

        _qmp_ = qmp.QEMUMonitorProtocol(self.qmp_sock)
        _qmp_.connect()

        if platform.linux_distribution()[1] == '7.5.0':
            try:
                path = "{}/{}".format(utils.VAR_RUN_PREFIX, self.vdi_uuid)
                with open(path, 'r') as f:
                    line = f.readline().strip()
                call(dbg, ["/usr/bin/xenstore-write", line, "5"])
                os.unlink(path)
            except:
                log.debug(
                    "%s: qemudisk.Qemudisk.close: There was no xenstore setup"
                    % dbg)
        elif platform.linux_distribution()[1] == '7.6.0':
            path = "{}/{}".format(utils.VAR_RUN_PREFIX, self.vdi_uuid)
            try:
                with open(path, 'r') as f:
                    line = f.readline().strip()
                os.unlink(path)
                args = {
                    'type': 'qdisk',
                    'domid': int(re.search('domain/(\d+)/', line).group(1)),
                    'devid': int(re.search('vbd/(\d+)/', line).group(1))
                }
                _qmp_.command(dbg, "xen-unwatch-device", **args)
            except:
                log.debug(
                    "%s: qemudisk.Qemudisk.close: There was no xenstore setup"
                    % dbg)
        try:
            # Stop the NBD server
            _qmp_.command("nbd-server-stop")
            # Remove the block device
            args = {"node-name": ROOT_NODE_NAME}
            _qmp_.command("blockdev-del", **args)
        except Exception:
            raise Volume_does_not_exist(self.vdi_uuid)
        finally:
            _qmp_.close()
示例#9
0
def start_qemu(qemu_exec,
               seamless_migration,
               image,
               spice_port,
               qmp_filename,
               incoming_port=None,
               with_agent=False):
    seamless_option = "on" if seamless_migration else "off"
    args = [
        qemu_exec, "-qmp", f"unix:{qmp_filename},server,nowait", "-spice",
        f"seamless-migration={seamless_option},disable-ticketing,port={spice_port}"
    ]
    if incoming_port:
        args += (f"-incoming tcp::{incoming_port}").split()

    if with_agent:
        args += [
            '-device', 'virtio-serial', '-chardev',
            'spicevmc,name=vdagent,id=vdagent', '-device',
            'virtserialport,chardev=vdagent,name=com.redhat.spice.0'
        ]

    if os.path.exists(image):
        args += [
            "-m", "512", "-enable-kvm", "-drive",
            f"file={image},index=0,media=disk,cache=writeback"
        ]

    proc = Popen(args, executable=qemu_exec, stdin=PIPE, stdout=PIPE)

    while not os.path.exists(qmp_filename):
        time.sleep(0.1)
    proc.qmp_filename = qmp_filename
    proc.qmp = qmp.QEMUMonitorProtocol(qmp_filename)
    while True:
        try:
            proc.qmp.connect()
            break
        except socket.error:
            pass
    proc.spice_port = spice_port
    proc.incoming_port = incoming_port
    return proc
示例#10
0
def get_client():
    client = qmp.QEMUMonitorProtocol(('192.168.1.100', 4444))
    client.connect()
    return client
示例#11
0
    colors.fg.green, colors.fg.pink
]
color_id = 0


def get_color():
    global color_id
    color = thread_colors[color_id]
    color_id += 1
    if color_id >= len(thread_colors):
        color_id = 0
    return color


try:
    srv = qmp.QEMUMonitorProtocol(socket_path)
    srv.connect()
    print(
        "Start handling QMP events for SR-IOV live migration datapath switching."
    )
    print()
    while True:
        ev = srv.pull_event(True)
        if ev:
            print("New event:")
            pprint(ev)
            eh = EventHandler(vm, ev)
            eh.start()
except qmp.QMPConnectError:
    die('QMP connetion error')
except qmp.QMPCapabilitiesError:
示例#12
0
test_sig = ecdsa_sign(cek_priv,b'TEST')
cek_pub_signed = build_ecdsa_pubkey(signed_cek[0x14:0x14+0x48],
                                    signed_cek[0x5c:0x5c+0x48])

if not check_ecdsa_sig(cek_pub_signed,b'TEST',test_sig):
    print("ERROR: Provided CEK private key does not match signed CEK public key")
    sys.exit(-1)

# Prepare certs to be send to target. NOTE: We must use the obtained signed CEK

plat_certs = str(base64.b64encode(pek + oca + signed_cek), 'ascii')
amd_certs = str(base64.b64encode(signed_ask + ark), 'ascii')
pdh = str(base64.b64encode(pdh), 'ascii')

print("Connecting to target qemu QMP port at %s:%d" % TARGET)
mon = qmp.QEMUMonitorProtocol(TARGET)
mon.connect()

print("Stopping remote VM")
mon.cmd("stop")

print("Sending migration parameters")
mon.cmd('migrate-set-parameters', { 'sev-amd-cert' : amd_certs })
mon.cmd('migrate-set-parameters', { 'sev-plat-cert' : plat_certs })
mon.cmd('migrate-set-parameters', { 'sev-pdh' : pdh })

print("Receive remote PDH and write to ./pdh_remote.cert")
pdh = base64.b64decode(mon.cmd('query-sev-capabilities')['return']['pdh'])
with open("./pdh_remote.cert",'wb') as f:
    f.write(pdh)
示例#13
0
def trace_ata_command(args):
    configure(args)
    configure_full_forwarding(args)
    #Do more configuration here
    configuration["s2e"]["plugins"]["LuaMonitorCommand"] = "verbose = true"
    configuration["s2e"]["plugins"]["Snapshot"] = "verbose = true"
    configuration["s2e"]["plugins"][
        "ExecutionTracer"] = ""  #"compression = \"gzip\""
    configuration["s2e"]["plugins"]["InstructionTracer"] = ""
    configuration["s2e"]["plugins"]["MemoryTracer"] = """
        monitorMemory = true,
        manualTrigger = false, 
        timeTrigger = false
    """
    start_hdd(args)
    ava = start_avatar()
    boot_hdd_until_bootloader_firmware_entry(ava)
    boot_hdd_from_boot_firmware_entry_to_main_firmware_entry(
        ava, args.dump_main_fw)

    #Now ...
    #Set breakpoint in serial character receive handler, used to regain control afterwards
    bkpt_interrupt = ava.get_target().set_breakpoint(0x2442aa)
    #Change program a bit to handle 0x03 (break) instead of 0xdb and put a breakpoint on that handler
    #    ava.get_target().write_typed_memory(0x243d06, 2, 0x2c03) #cmp r4, #0x03
    #    ava.get_target().write_typed_memory(0x243d52, 2, 0xe7fa) #b loc243d4a
    #    bkpt_interrupt = ava.get_target().set_breakpoint(0x243d52)
    ava.get_target().cont()

    #    bkpt_interrupt.wait()
    #    ava.get_target().cont()

    #Wait for JMicron USB-SATA bridge to show up
    #TODO: Prints LSUSB output, use Popen with PIPE to avoid
    while True:
        try:
            subprocess.check_call(["lsusb", "-d", "152d:2338"])
            break
        except subprocess.CalledProcessError:
            time.sleep(1)
            continue

    log.debug("USB SATA bridge showed up")

    #Leave the OS some time to play with the disk ...
    time.sleep(5)

    #TODO: This should work, but it does not ... so work around by directly sending CTRL+C to the HDD
    #    ava.get_target().execute_gdb_command(["-exec-interrupt"])
    with open(args.serial, 'wb') as serial_port:
        serial_port.write(bytes([0x03]))

    #Target should be stopped now
    #Set breakpoint at SATA interrupt handler
    bkpt_sata_irq = ava.get_target().set_breakpoint(0x1f42)
    ava.get_target().cont()

    #Send ATA identify packet (0xec)
    usb_ata_bridge = UsbScsiDevice()
    if args.action == "TRACE_IDENTIFY_ATA_CMD":
        usb_ata_bridge.send_ata_command(0xec, False, 512, 1, 0, 0, 0)
    elif args.action == "TRACE_READ_ATA_CMD":
        usb_ata_bridge.send_scsi_read(0x12345678, 0x42)
    elif args.action == "TRACE_WRITE_ATA_CMD":
        usb_ata_bridge.send_scsi_write(
            0xdeadbeef, bytes([(x & 0xff) for x in range(0, 2048)]))

#    usb_ata_bridge.send_ata_command_xxx(0x00, False, 0, 0, 0, 0x7654321, 0) #DO NOT EXECUTE THIS COMMAND! BRICKS THE HDD!

#Breakpoint should have been hit now, just call wait to make sure
    bkpt_sata_irq.wait()

    print("Bkpt after waiting for SATA irq hit")

    #TODO: Trigger snapshot of all RW-areas

    #We need to execute one instruction in the emulator so that everything
    #works ... especially the Snapshot plugin
    ava.get_emulator().write_typed_memory(0x0, 4, 0)
    ava.get_emulator().write_typed_memory(0x4, 4, 0)
    ava.get_emulator().set_register("pc", 0)
    bkpt_init_emulator = ava.get_emulator().set_breakpoint(0x4)
    ava.get_emulator().cont()
    bkpt_init_emulator.wait()
    bkpt_init_emulator.delete()

    #Load RO memory from files
    load_mainfw_ro_memory_into_emulator(ava)

    copy_cpu_registers(ava.get_target(), ava.get_emulator())
    copy_rw_memory(ava.get_target(), ava.get_emulator())

    print("Now happily tracing ... ")

    #Add a quirk to avoid getting stuck in the timer anti-jitter loop
    ava.get_emulator().write_typed_memory(0x103c40, 2, 0x46c0)  #NOP
    ava.get_emulator().write_typed_memory(0x181c, 2, 0x46c0)  #NOP
    ava.get_emulator().write_typed_memory(0x1027A4, 2, 0x4770)  #BX LR

    #Take a snapshot that can be used to restore stuff for symbolic execution
    qmp_console = qmp.QEMUMonitorProtocol(QMP_ADDRESS)
    qmp_console.connect()

    qmp_console.cmd("s2e-exec",
        {
            "cmd": "lua",
            "lua": "Snapshot.takeSnapshot('before_trace', 7, " + \
                "{" + \
                    "{address = 0x00000000, size = 0x00008000}, " + \
                    "{address = 0x00010000, size = 0x00020000}, " + \
                    "{address = 0x00100000, size = 0x00020000}, " + \
                    "{address = 0x04000000, size = 0x00004000}, " + \
                    "{address = 0x06000000, size = 0x01000000}})"
        })

    #This breakpoint is in the idle task, which is only called when all other tasks have no work
    #(i.e., when the current request has been served)
    bkpt_end_of_trace = ava.get_emulator().set_breakpoint(
        0x00253a06)  #For FW JC47

    #Trace execution
    ava.get_emulator().cont()

    bkpt_end_of_trace.wait()
    #Hara kiri!
    os.kill(os.getpid(), 9)