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
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()
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 = []
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()
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
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()
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()
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()
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
def get_client(): client = qmp.QEMUMonitorProtocol(('192.168.1.100', 4444)) client.connect() return client
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:
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)
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)