Page 1 of 1

Detecting bochs from your OS?

Posted: Mon Aug 06, 2007 10:47 am
by Candy
How do you detect your OS is running inside bochs?

Posted: Mon Aug 06, 2007 11:22 am
by Brynet-Inc
This is a tricky question, there really should be a nice "standard" way to detect if an OS is being virtualized.. but most of the time you have to rely on a flaw in the VM, something that clearly isn't very reliable though..

Here is an interesting example I found.. http://invisiblethings.org/papers/redpill.html

Although this code has no effect in QEMU running OpenBSD - I have no way to test the validity of the code..

Posted: Mon Aug 06, 2007 4:55 pm
by Dex
There also some code in these posts
http://www.osdev.org/phpBB2/viewtopic.p ... t+emulator

Re: Detecting bochs from your OS?

Posted: Mon Aug 06, 2007 7:54 pm
by Brendan
Hi,
Candy wrote:How do you detect your OS is running inside bochs?
Unfortunately, Brynet-Inc is right - there should be a standard way of detecting virtual machines but there isn't. I personally blame security "experts", who want virtual machines to be entirely undetectable so they feel good about using them for honey pots (which is stupid if your code must be running at CPL=0 to detect the virtual machine).

This means you need to rely on flaws in the virtual machine, but you need to be a little tricky - for open source emulators like Bochs you want to rely on flaws that can't be easily changed. For an example, when Bochs was emulating an 80486 the CPUID instruction would say the CPU is an 80486DX but the 80486DX didn't actually support the CPUID instruction, so I used this as part of my Bochs detection code. Later, I rewrote "cpu/cpuid.cc" and fixed this problem (and others), which broke my own Bochs detection code.

For Bochs, first I try a little pre-check to see if it was compiled with the 0xE9 hack:

Code: Select all

	in al,0xE9						;Get return value from Bochs debug port
	cmp al,0xE9						;Is Bochs running (and compiled with "./configure --enable-port-e9-hack")?
	je .isBochs						; yes, running in Bochs
This isn't a reliable test (it's easy to compile Bochs without the 0xE9 hack), but it can save time.

Next, RDTSC counts instructions (not cycles) and Bochs doesn't emulate caches. I flush caches (WBINVD) and then use instructions like "MUL dword [0x00000FFE]" (which is deliberately misaligned and should cause 2 cache misses). RDTSC will count instructions, so one WBINVD and five MULs will be 6 "cycles".

This doesn't work if RDTSC isn't supported (if Bochs is emulating an 80486). In this case I do 2 loops, where both loops run from one PIT IRQ to the next (a fixed amount of time). For the first loop I repeatedly flush caches (WBINVD) and do several misaligned reads (e.g. "cmp dword [0x00006FFF],0"), and for the second loop I repeatedly do NOP and several misaligned reads. Then I compare how many times each loop executed. For Bochs the difference is small and sometimes the first loop does more iterations (flushing the caches is faster than NOP). For this I'd recommend making sure paging isn't enabled, as Bochs does emulate TLBs and flushes the TLBs when you do WBINVD (which is wrong - WBINVD should only flush instruction and data caches, not the TLBs). With paging enabled the first loop would be slower due to TLB flushing, which makes it hard to detect Bochs using this method.

The problem is that it's hard to write code that doesn't also detect other emulators. With my method, you can't tell the difference between Bochs and VirtualBox (they have the same flaws).

I've also got code for detecting Qemu, VMware and VirtualPC. Qemu doesn't emulate caches, RDTSC is always supported and RDTSC measures cycles and not instructions. VMware has a special I/O port that will change some registers if you touch the IO port when EAX is set to a special magic number, which can be used to find out which version of VMware is running. VirtualPC has a special instruction (which should be an invalid opcode) - you just execute this instruction and see if you get an exception or not.

Anyway, the latest version of my code isn't on my web site yet, so I attached it. It's still a work in progress though - I'm still looking for more information on detecting other virtual machines.


Cheers,

Brendan

Posted: Mon Aug 06, 2007 11:37 pm
by Candy
Hmm..... I was thinking in how to detect bochs with VBE was running so I could load a video driver, but the "VBE video card" has its own ID mechanism you can check. Output 0x00 to 0x1CE and then read a 16-bit word from 0x1CF and check it whether it is 0xB0C0. If it is, it's a bochs vbe device.

Posted: Tue Aug 07, 2007 12:20 am
by dc0d32
Can we check for the PCI device IDs of different emulators? Haven't checked if they are unique though.

Posted: Tue Aug 07, 2007 12:50 am
by Brynet-Inc
prashant wrote:Can we check for the PCI device IDs of different emulators? Haven't checked if they are unique though.
I hear VirtualBox's emulated video card uses a bogus PCI vendor/product ID, but most would try to emulate "commonly" supported chipsets, The reason for this is to support multiple "guest operating systems" without custom drivers.

It wouldn't make sense for VM's to have unique PCI ID's if there trying to support a wide range of OS's.. :wink:

One thing I noticed is the "ATA" vendor/model name of most Emulators is unique though, Perhaps that could be used.. although it would be sort of hack-ish. (And you're able to change the default name in a few emulators..)