Detecting bochs from your OS?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Detecting bochs from your OS?

Post by Candy »

How do you detect your OS is running inside bochs?
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post 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..
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

There also some code in these posts
http://www.osdev.org/phpBB2/viewtopic.p ... t+emulator
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Detecting bochs from your OS?

Post 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
Attachments
detectvm.asm
VM detection code
(11.02 KiB) Downloaded 120 times
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post 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.
User avatar
dc0d32
Member
Member
Posts: 69
Joined: Thu Jun 09, 2005 11:00 pm
Location: Right here

Post by dc0d32 »

Can we check for the PCI device IDs of different emulators? Haven't checked if they are unique though.
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post 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..)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
Post Reply