In this entry, I am going to share some tips to develop your own hypervisors using VMware Workstation and briefly introduce a sample ring-1 monitoring tool based on a home made hypervisor. This entry may not be for you if you already have your own hypervisors you can update at your disposal or are not interested in development at all.
Motivation
Now, you may wonder why you want to write your own hypervisors even though there are quite a few open source projects you could re-purpose. The reason is "it sounds better if you say that you wrote your own hypervisor from scratch." ;) Besides, reading full-fledged hypervisors may not be as enjoyable as writing your own code. Let us see how you can do it.
What You Need
You need VMware Workstation as a test environment. It supports nested virtualization (emulation of VT-x technology) and lets you debug your hypervisor code form the host Windows through Windbg in the exact same manner as regular kernel debugging.
You may also be able to use other VMware products that support nested virtualization like Fusion, but you will have to configure kernel debugging between two VMs, which is not the most straightforward way. Also, having Windows as a host lets you use VirtualKD which makes communication between a debugee and a debugger very fast. VirtualBox, unfortunately, does not support nested VM and allow to execute VMX operations in it.
You may also be able to use other VMware products that support nested virtualization like Fusion, but you will have to configure kernel debugging between two VMs, which is not the most straightforward way. Also, having Windows as a host lets you use VirtualKD which makes communication between a debugee and a debugger very fast. VirtualBox, unfortunately, does not support nested VM and allow to execute VMX operations in it.
If you are paranoia and do not trust software emulated VT-x, you could use a real box with a serial port (which means it is not going to be a laptop) as a debugee. You might already know that kernel debugging through USB is possible. DO NOT GO THERE unless you already have hardware that was confirmed that it supports USB debugging. There are some subtle requirements which you will not tell if a debugee device suffices by just looking at the specs online. Besides that, being able to take snapshots and memory dump from a hanged machine using VMware drastically speeds up your development.
Image 1: USB2 debug-cable. Not recommended. |
Configuring Virtual Machines
You have to make some changes in a debugee virtual machine. Firstly, you have to check the following options:
- Virtualize Intel VT-x/EPT or AMD-V/RVI
- Virtualize CPU performance counters
Image 2: Virtual Machine Config |
Secondly, you should add those lines in a corresponding VMX file [1], otherwise you will end up with getting mysterious, random-looking NMI_HARDWARE_FAILURE bug check.
----
hypervisor.cpuid.v0 = "FALSE"
mce.enable = "TRUE"
vhu.enable = "TRUE"
----
EDIT (Nov 1, 2015): Removed entries with apic.xapic since I confirmed that it still worked without them.
EDIT (Nov 1, 2015): Removed entries with apic.xapic since I confirmed that it still worked without them.
Gotchas
Once you have configured the VM, the rest is only a matter of programming, but there are some gotchas I would like to share to keep you sane:
- Try to avoid use of APIs inside a VMExit handler (in VMX root mode). Since the handler can be executed from any contexts including exception handlers or code under a very high IRQL, it is tough to conclude that calling an API which you do not know *exactly* what it does is 100% safe.
- For the same reason, avoid calling DbgPrint() from the VMExit handler. It usually works fine but sometimes causes mysterious errors like triple fault when you request a lot of log. Instead, store log texts into pre-allocated non-paged pool and print them out later from a safe context.
- Do not step-in to vmlaunch and vmresume instructions. The debugger will never return control to you, and the debugee will hang.
- Do not put software breakpoints everywhere in the VMExit handler. Although it seems to be fine in most cases, in some situation, the debugger does not get control from the debugee, and the system just freezes when int 3 is executed.
Getting Memory Dump From a Hanged Debugee System
One of the biggest advantages of using VMware is that you can take memory dump (.dmp files) from a hanged debugee and give it to Windbg just like normal crash dump analysis.To take a dump file, first you suspend the virtual machine when it is freezed and take a snapshot.
Image 3: Suspend a hanged virtual machine |
Then, navigate to where snapshot files are stored and run the vmss2core command under the VMware Workstation directory with names of the latest vmsn and vmem files. For instance, commands look like this:
----
> cd "C:\Users\user\Documents\Virtual Machines\Windows 8 x64"
> "C:\Program Files (x86)\VMware\VMware Workstation\vmss2core-win.exe" -W8 "Windows 8 x64-Snapshot45.vmsn" "Windows 8 x64-Snapshot45.vmem"
vmss2core version 2452889 Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
scanning pa=0 len=0x10000000
Cannot translate linear address 7ff7d12b1b00.
Cannot read context LA from PRCB.
...
... 2020 MBs written.
... 2030 MBs written.
... 2040 MBs written.
Finished writing core.
----
Note that vmss2core comes with VMware Workstation by default (version 2780323) does not seem to be functioning (always generates 0 byte of empty files). If that the case for you too, download version 2452889 from VMware's website.
Now, you have gotten the memory.dmp and can give it to the debugger.
----
> windbg -z memory.dmp
----
Image 4: Memory dump analysis |
References
There are some open source hypervisor projects you can refer to for implementation. Those are small enough to read quickly and written for Windows hosts.- MiniHyperVisorProject by Peter Hlavaty
- Blue Pill by Joanna Rutkowska
- virtdbg
- hyperdbg
A Sample Monitoring Tool Based on a Hypervisor
With those tips, you should be able to develop your own hypervisor fairly smoothly and utilize it for your research. I, for example, wrote a proof-of-concept hypervisor, Sushi, monitoring use of some uncommon instructions from non-image kernel space and stopping a thread when write protection in CR0 is modified.Image 5: Demo hypervisor "Sushi" detecting interesting stuff |
This is less than 4000 lines of code yet gives me an ability to investigate some run-time behaviour of the kernel I was unable to monitor. It is pretty awesome, and above all, playing with low-level stuff like this is quite fun.
In short, if you are interested in developing hypervisors for whatever reasons, you can do it without buying any extra hardware, and then, you can also make it one of your analysis tools like this demo hypervisor.
In short, if you are interested in developing hypervisors for whatever reasons, you can do it without buying any extra hardware, and then, you can also make it one of your analysis tools like this demo hypervisor.
This is cool stuff, I always wanted to try to look into the existing hypervisor debuggers like virtdbg and hyperdbg. Keep up the good work! :)
ReplyDeleteThank you :) Though I have never used those projects, they are really interesting and implementation is straightforward to read. You should check them out.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThank you for sharing your experience!
ReplyDeleteI'm focusing on hidden hypervisor detection in both cases: with one and with several nested hypervisors.
Here you can find the details of my recent work - igorkorkin.blogspot.ru/2015/05/two-challenges-of-stealthy-hypervisors.html.
I've got an idea about the HYP-based tool to analyze the Windows memory content. The thing is that this tool can help to analyze not only fixed memory dumps but can help to carry out research about how memory content has been changing. It will look like taskmgr.exe for Windows memory.
Another idea is to use HYP-based tool to dump GPU memory to reveal the possible spyware. Look at this - The impact of GPU-assisted malware on memory forensics: A case study http://www.dfrws.org/2015/proceedings/DFRWS2015-10.pdf
Let's collaborate & develop such ideas.
Feel free to drop me a line.
Thanks for sharing your work, Igor. Memory forensics is a quite interesting field to me. Let us have some chats when we have time.
ReplyDeleteThis is awesome one.will try to do same thing on windows 10.Thanks
ReplyDeleteThis is awesome one.will try to do same thing on windows 10.Thanks
ReplyDeleteVery welcome. I hope this article help you develop your own hypervisor tools and analyze things. Please let me know if you made any interesting things.
ReplyDeleteDoes this work for windows 32 platforms.. I am not able to build drivers for 32.. some asm erros.
ReplyDeleteCheck out HyperPlatform and let me know if you need any help. It supports x86 as well.
Deletehttps://github.com/tandasat/HyperPlatform
On x64.. sc start Sushi is failing with error "Invalid Handle". for both debug/release. do you come across this error.
DeleteI saw that error when you tried to load a driver but not all imported symbols were not addressed. You may find unaddressed imports using Dependency Walker.
DeleteI tried the dependency thing.. all dependencies are available.
ReplyDeleteI found the solution here. http://stackoverflow.com/questions/13254487/why-am-i-getting-error-code-6-on-startservice
Thank you for letting me know the solution. I will keep in mind it when I make a project next time!
Delete