Detecting emulator presence...
Detecting emulator presence...
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
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
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English )
Derrick operating system: http://derrick.xf.cz (Slovak and English )
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.
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.
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;
}
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...
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...
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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.
Maybe this helps?
It's also at: http://bos.asmhackers.net/forum/viewtopic.php?id=59Smiddy @ BOS forums wrote:Hi,
I'm sharing code, enjoy!
I hope you all can use it...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
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
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.
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.
Thanks for your responses and hints!
inflater
inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English )
Derrick operating system: http://derrick.xf.cz (Slovak and English )