Skip to content

Instantly share code, notes, and snippets.

@twdrozhevskij
Created November 1, 2020 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twdrozhevskij/6366d688c5b9a592ad841724e03b56a9 to your computer and use it in GitHub Desktop.
Save twdrozhevskij/6366d688c5b9a592ad841724e03b56a9 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
from fcntl import ioctl
import sys
import time
from mmap import mmap, PROT_READ, PROT_WRITE, MAP_SHARED, MAP_PRIVATE, MAP_ANONYMOUS
from structs import *
RAM_SIZE = 0x10000
def load_guestbin(path):
with open(path, 'rb') as guest:
return guest.read()
def main():
with open('/dev/kvm', 'wb+') as kvm_fd:
# KVM layer
version = ioctl(kvm_fd, KVM_GET_API_VERSION, 0)
if version != 12:
print(f'Unsupported version: {version}')
sys.exit(1)
# Create VM
vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0)
# Create VM Memory
mem = mmap(-1, RAM_SIZE, MAP_PRIVATE | MAP_ANONYMOUS, PROT_READ | PROT_WRITE)
pmem = ctypes.c_uint.from_buffer(mem)
mem_region = UserspaceMemoryRegion(slot=0, flags=0,
guest_phys_addr=0, memory_size=RAM_SIZE,
userspace_addr=ctypes.addressof(pmem))
ioctl(vm_fd, KVM_SET_USER_MEMORY_REGION, mem_region)
# Create VCPU
vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
# Read guest.bin
guest_bin = load_guestbin('guest.bin')
mem[:len(guest_bin)] = guest_bin
sregs = Sregs()
ioctl(vcpu_fd, KVM_GET_SREGS, sregs)
# Initialize selector and base with zeros
sregs.cs.selector = sregs.cs.base = sregs.ss.selector = sregs.ss.base = sregs.ds.selector = sregs.ds.base = sregs.es.selector = sregs.es.base = sregs.fs.selector = sregs.fs.base = sregs.gs.selector = 0
# Save special registers
ioctl(vcpu_fd, KVM_SET_SREGS, sregs)
# Initialize and save normal registers
regs = Regs()
regs.rflags = 2 # bit 1 must always be set to 1 in EFLAGS and RFLAGS
regs.rip = 0 # our code runs from address 0
ioctl(vcpu_fd, KVM_SET_REGS, regs)
runsz = ioctl(kvm_fd, KVM_GET_VCPU_MMAP_SIZE, 0)
run_buf = mmap(vcpu_fd, runsz, MAP_SHARED, PROT_READ | PROT_WRITE)
run = Run.from_buffer(run_buf)
try:
while True:
ret = ioctl(vcpu_fd, KVM_RUN, 0)
if ret < 0:
print('KVM_RUN failed')
return
if run.exit_reason == KVM_EXIT_IO:
print(f'IO port: {run.io.port}, data: {run_buf[run.io.data_offset]}')
elif run.exit_reason == KVM_EXIT_SHUTDOWN:
return
time.sleep(1)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment