General security

QEMU Windows Guest: Installing the Operating System

Dejan Lukan
December 27, 2013 by
Dejan Lukan

Now that we've created the image for our guest, we must continue with installing the operating system on it. In Virtualbox/VMWare, we usually select the CD-ROM to boot from the iso installation image and start the virtual machine, after which the installation is automatically started by booting from the CD-ROM. It's essentially the same in QEMU, except that we must do that from the command line. We have already provided enough information that we now know that we must use the QEMU-kvm executable.

First we must look at the command-line options that we must be aware of before trying to do that. The most basic command line options are presented below (summarized after [2]).

What should you learn next?

What should you learn next?

From SOC Analyst to Secure Coder to Security Manager — our team of experts has 12 free training plans to help you hit your goals. Get your free copy now.

Option Description

-machine [type=]name[,prop=value]

Selects the emulated machine by name, where all machines can be printed with "QEMU-kvm -machine ?". We can use the accel and dump-guest-core properties, where the first enables an accelerator kvm or tcg and the latter includes guest memory in a core dump. We'll use:

> -machine accel=kvm

-name name The name of the QEMU guest VM, which will be displayed when connecting to that VM by using VNC.

-cpu model Selects the CPU model, where all the CPUs can be printed with "QEMU-kvm -cpu ?".> -cpu core2duo

-m megs

Sets the number of MB of memory the VM will have.

> -m 1024

-smp n[,cores=c][,threads=t][,sockets=s][,maxcpus=m] Simulates the SMP system with n CPUs, which have c number of cores with t threads.> -smp 1,sockets=1,cores=1,threads=1

Sets the system UUID.> -uuid 2f1b6dfc-9a5a-574d-578a-4ac2a10de010

-nodefaults Normally QEMU sets default devices such as serial port, parallel port, virtual console, monitor device, VGA adapter, floppy, and CD-ROM drive, but we can disable all those devices with -nodefaults.> -nodefaults

-chardev backend ,id=id [,options] Specifies the character device options, where the backend is one of the following: null, socket, udp, msmouse, vc, file, pipe, console, serial, pty, stdio, braille, tty, parport spicevmc. Each device must also have an string id, which uniquely identifies the device.

-rtc [base=utc|localtime|date][,clock=host|vm][,driftfix=none|slew] Enables the time clock start at UTC, local time or a specific date. The clock parameter specifies whether RTC is set by the host clock or vm if we want to isolate the guest's clock from the host's.> -rtc base=localtime

-no-shutdown Doesn't stop QEMU when VM stops, but only stops the emulation.> -no-shutdown

-device driver[,prop[=value][,...]] Creates a virtual device by setting the device driver and its properties. All the devices can be printed with "QEMU-kvm -device ?". We should emulate the device that we would like to have in the guest OS: we must ensure that the OS has a device driver to be able to use that device. When creating a device for networking, we can choose e1000, rtl8139, virtio-net (required special driver) device by using "-device TYPE,netdev=NAME" command-line options. The NAME is a name of the previously defined -netdev backend to which the virtual network device with be connected.

-drive option[,option[,option[,...]]]

Define a new drive, where the options can be:- file: disk images used with this drive

- if: which interface type the drive is connected: none, ide, scsi, sd, mtd, floppy, pflash, or virtio.

- bus: define drive bus number.

- unit: define drive unit id.

- media: the type of media: disk, CD-ROM.

- snapshot: allow snapshots of drive.

- cache: how the host cache is used to access block data: none, writeback, unsafe, writethrough.

- format: specifies the disk format to be used.- serial: the serial number to assign to the device.

- addr: set the address of the PCI controller.

-net user[,option][,option][,...]

-netdev user,id=id[,option][,option][,...] Creates a new network interface, where the rtl8139 is created by default, but we can also use: virtio, i82551, i82557b, i82559er, ne2k_pci, ne2k_isa, pcnet, e1000, smc91c111, lance and mcf_fec. Note that we can use both the -net or -netdev command-line option to create a new interface.

-vnc display[,option[,option[,...]]] QEMU can use different options to display the VGA output; normally it uses SDL, but this option instructs it to use VNC.> -vnc 127.0.0.1:0

-vga type Specifies the VGA card to emulate, where we can use: cirrus, std, vmware, qxl, none.> -vga qxl

-boot [order=drives][,once=drives][,menu=on|off][,reboot-timeout=rb_timeout]

Specifies the boot order of drives as a string of drive letters, which can be:- a: floppy 1

- b: floppy 2

- c: first hard disk

- d: first CD-ROM

- n-p: network adapter

> -boot order=dc

-global driver.prop=value Sets the default value of driver's property, which is useful for setting options of devices created automatically.

-cdrom file Use the specified file as a CD-ROM image.

-enable-kvm Enables full KVM virtualization support.

Now we have a basic understanding of the QEMU-kvm command-line options, which brings us one step closer to the actual operating system install. In the next step we'll write a Bash script that we'll use to install the Windows7 operating system on the previously created image. The complete bash script can be seen below:

[python]
#!/bin/bash

/usr/bin/QEMU-kvm

-machine accel=kvm

-cpu core2duo

-name Windows7

-drive file=Windows7.img,if=ide,cache=writeback

-m 1G

-cdrom Windows7.iso

-boot order=c

-enable-kvm

-monitor stdio

-smp 1,sockets=1,cores=1,threads=1

-nodefaults

-usbdevice tablet

-rtc base=localtime

-vnc 127.0.0.1:1

-vga qxl

-full-screen

-device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0

-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6

-device e1000,netdev=net0

-netdev user,id=net0

[/python]

We still need to mention a couple of tricks I picked up when started playing with QEMU. First, the mouse cursors are not properly aligned. If you happen to install a Windows operating system and there are actually two cursors on the screen, the host cursor and the guest cursor, you have a problem, because the cursors are not on top of each other as they should be. To resolve this issue, we can add the following command-line parameter to the QEMU-kvm command, which resolves the problem:

[c]

-usbdevice tablet

[/c]

Another problem is a Windows operating system not recognizing the hard drive, which results in something like the screen below. Notice that Windows didn't recognize the hard drive. This happens because of the "if=virtio" parameter passed to the -drive option specifying the image to use.

This happens because Windows does not have support for a virtio driver and therefore it won't detect the hard drive. If we absolutely must use the virtio driver, then we can use a tip from [3], but I haven't tested it, so I don't know whether it works or not. Rather than that, we can also specify the "if=ide" interface and be done with it; Windows supports that driver and will detect the hard drive without a problem as can be seen on the picture below.

After that we can normally install Windows 7 as a QEMU guest. The same script can also be used to start Windows 7 after the installation; the only thing we need to change is the -boot option, which must be set to boot from hard drive rather than CD-ROM. Now we have Windows 7 guest installed and working and we can start by configuring other important options that we just have to have to make the VM useful.

But we should make the effort to use the virtio driver, since it provides better performance. To do that we need to add the "if=virtio" option to the -drive parameter and we must also add the "-boot order=c" to the command line, because otherwise we won't be able to boot from it.

Conclusion

In this article we've seen how we can go about installing the Windows 7 operating system on the QEMU image and taken a look into most useful command-line parameters that we need to become familiar with to work with QEMU. If you're just starting to use QEMU, you should definitely know about the command-line parameters presented in the previous table. This can also serve as a great reference when we don't remember certain command-line parameter and we don't want to read through the QEMU main page.

References:

[1] QEMU-img man page, http://linux.die.net/man/1/QEMU-img.

[2] QEMU-kvm man page, http://linux.die.net/man/1/QEMU-kvm.

[3]Updating the guest initramfs with the virtio driver, http://www.linux-kvm.org/page/Boot_from_virtio_block_device#Windows_XP.

[4] Ebtables, http://ebtables.sourceforge.net/.

[5] Saying How To Mangle The Packets, http://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html.

Dejan Lukan
Dejan Lukan

Dejan Lukan is a security researcher for InfoSec Institute and penetration tester from Slovenia. He is very interested in finding new bugs in real world software products with source code analysis, fuzzing and reverse engineering. He also has a great passion for developing his own simple scripts for security related problems and learning about new hacking techniques. He knows a great deal about programming languages, as he can write in couple of dozen of them. His passion is also Antivirus bypassing techniques, malware research and operating systems, mainly Linux, Windows and BSD. He also has his own blog available here: http://www.proteansec.com/.