Page 1 of 1
Detecting emulator presence...
Posted: Thu Apr 05, 2007 11:17 am
by inflater
Hi guys,
how can I please detect in my kernel, if it's running inside Bochs/QEMU or MS Virtual PC 2007? Is it able in real mode through assembler? If yes, can you post me the code? (ASM would be better, but C is good too.)
Thank you.
inflater
Posted: Thu Apr 05, 2007 11:24 am
by ~
Maybe testing for all incorrect behavior under the emulator, but you would need to find such code that works correctly in Bochs but fails in real hardware. It's a shame that it's appreciated until one figures out it could be used to detect Bochs, and generally gets dropped. Also, such bogus execution gets fixed because anyway it's needed and wouldn't be fun to keep up to date with the new and the outdated bugs.
You will also need a way of recovering from exceptions and misbehavior that could result.
That's the only way I get to think, because anyway emulators are intended to be undetectable for software, so they look exactly as true hardware. Being otherwise would trash the emulation.
Posted: Thu Apr 05, 2007 12:59 pm
by Dex
Here some code hackers use for that job.
Code: Select all
#include <stdio.h>
inline int idtCheck ()
{
unsigned char m[6];
__asm sidt m;
printf("IDTR: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", m[0], m[1],
m[2], m[3], m[4], m[5]);
return (m[5]>0xd0) ? 1 : 0;
}
int gdtCheck()
{
unsigned char m[6];
__asm sgdt m;
printf("GDTR: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", m[0], m[1],
m[2], m[3], m[4], m[5]);
return (m[5]>0xd0) ? 1 : 0;
}
int ldtCheck()
{
unsigned char m[6];
__asm sldt m;
printf("LDTR: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", m[0], m[1],
m[2], m[3], m[4], m[5]);
return (m[0] != 0x00 && m[1] != 0x00) ? 1 : 0;
}
int main(int argc, char * argv[])
{
idtCheck();
gdtCheck();
if (ldtCheck())
printf("Virtual Machine detected.\n");
else
printf("Native machine detected.\n");
return 0;
}
Posted: Thu Apr 05, 2007 1:03 pm
by ehird
Do all assembler folks not indent?
Posted: Thu Apr 05, 2007 1:08 pm
by ~
I do indent, and the rest of the projects are as well, but maybe less. And of course do more than indenting... what's the point?
By the way, interesting code, and interesting to see what's going on there; but anyway looks like a very simple (and fully reliable?) way of detecting for emulator or true hardware...
Posted: Thu Apr 05, 2007 1:11 pm
by bubach
no, why would you think that? some even do in assembly, for loops and stuff.
Posted: Thu Apr 05, 2007 2:13 pm
by Brynet-Inc
I'm not sure for what emulator the code Dex posted is for.. but It fails in QEMU.
Code: Select all
IDTR: ff 07 60 b2 55 d0
GDTR: ff ff 00 50 37 d3
LDTR: 18 00 00 50 37 d3
Native machine detected.
Posted: Thu Apr 05, 2007 2:34 pm
by Dex
Virtual PC if I remember and i am sure it does not work under linux
.
So it upto code here, to try it and mod it.
Posted: Thu Apr 05, 2007 2:49 pm
by bubach
Maybe this helps?
Smiddy @ BOS forums wrote:Hi,
I'm sharing code, enjoy!
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VM - Detects if we're in a virtual mcahine like Virtual PC, VMWare, or
;; Bochs. If there are others, this is where they shall reside for
;; detecting them.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BochsDetectedMessage db 'Bochs detected',13,10,0
BochsNotDetectedMessage db 'Bochs not detected',13,10,0
BochsOn dd 0
DetectBochs:
mov dx,0E9h
in al,dx
cmp al,0E9h
je .InBochs
mov eax,0
mov esi,BochsNotDetectedMessage
jmp .Done
.InBochs:
mov eax,1
mov esi,BochsDetectedMessage
.Done:
mov [BochsOn],eax
call PrintString
ret
ret
align 4
VPCDetectedMessage db 'Virtual PC Detected',13,10,0
VPCNotDetectedMessage db 'Virtual PC Not Detected',13,10,0
align 4
VPCOn dd 0
DetectVPC:
push ebx
cli ; Turn off interrupts
mov esi,VPCInvalidOpcodeException ; Store new Invalid Opcode Exception
mov eax,6 ; Invalid Opcode is 6
call AddExceptionToIDT ; Call routine to replace it
sti ; Turn on interrupts
mov ebx,0 ; This will stay 0 if VPC running
mov eax,1 ; VPC function number
.CallVPC:
db 0Fh,3Fh,07h,0Bh ; Call VPC
test ebx,ebx
jz .InVPC
mov eax,0
mov esi,VPCNotDetectedMessage
jmp .Done
.InVPC:
mov eax,1
mov esi,VPCDetectedMessage
.Done:
mov [VPCOn],eax
call PrintString
cli
mov esi,UnhandledINT ; Restore original unhandled interrupt
mov eax,6 ; Invalid Opcode is 6
call AddExceptionToIDT
sti
pop ebx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VPCInvalidOpcodeException - replaced invalid opcode exception handler with
;; this one to go past the VPC call in the above
;; procedure.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
VPCInvalidOpcodeException:
mov ebx,-1 ; Not running VPC
add DWORD [esp],4 ; Fix the EIP in stack to skip past call VPC
iret
;---------------------------------
; We need this because ATA
; Identify command is NOT working
; under vmware ;) surprise!
;---------------------------------
align 4
VMWareDetectedMessage db 'VM Ware Detected',13,10,0
VMWareNotDetectedMessage db 'VM Ware Not Detected',13,10,0
ALIGN 4
VMWareOn dd 0 ; Default = 0 = OFF, 1 = ON
DetectVMWare:
mov eax,564D5868h ; 'VMXh'
mov ebx,12345h ; This can be any number, but not 'VMXh'
mov ecx,00Ah ; Get VMWare version
mov edx,'VX' ; Port number
IN eax,dx ; Read port 5658h
cmp ebx,564D5868h ; Is this from the EAX?
je .InVMWare ; Yes, goto flag it
mov eax,0
mov esi,VMWareNotDetectedMessage
jmp .Done
.InVMWare:
mov eax,1
mov esi,VMWareDetectedMessage
.Done:
mov [VMWareOn],eax
call PrintString
ret
I hope you all can use it...
It's also at:
http://bos.asmhackers.net/forum/viewtopic.php?id=59
Posted: Thu Apr 05, 2007 6:40 pm
by mystran
Can anybody detect emulators with code running in userspace?
Posted: Fri Apr 06, 2007 3:01 am
by Combuster
I can sense an emulator when bochs is emulating an amd64 or anything before the pentium:
It works by checking what flags are touched by an DIV instruction. Bochs and Pentium processors preserve all flags, other processors set the flags in specific ways.
Actually, this method can even tell you the brand of your chip when it doesnt support cpuid, and for that reason it was originally used to detect cyricies. (My kernel uses it for exactly that reason)
However, this will obviously not detect a virtual machine.
Posted: Fri Apr 06, 2007 3:21 am
by inflater
Thanks for your responses and hints!
inflater
Posted: Sun Apr 08, 2007 8:35 am
by Daedalus
One other thing to try is looking at the hardware.
For example, most hardware in VMWare has the name "VMWare" tacked onto it - CDROMS, Hard disks, display adaptors, etc.
I'm not sure if Bochs does though ...