Find a feasible way to judge whether "the program is running under pure DOS". The basic idea is as follows:
The MSW (Machine Status Word) of the 80386 register can be read in real mode or any privilege level, while the control register CR0 can only be read in real mode or privilege level 0. And the lower 16 bits of CR0 are the MSW. According to this principle, if their values are equal, it is considered to be running under pure DOS; otherwise, it is running under the DOS virtual machine in Windows.
BOOL IsWindowVM()
{
DWORD dwCr0;
WORD wMsw;
// Read machine status word MSW
asm smsw ax;
asm mov wMsw, ax
// Read control register cr0, which may cause an exception under VM
asm mov eax, cr0
asm mov dwCr0, eax
// Judge whether they are equal. When equal, it means pure DOS; otherwise, VM
if (wMsw == (WORD)(dwCr0 & 0xFFFFlu))
{
return (FALSE);
}
return (TRUE);
}
Although after pure DOS loads "Emm386.Exe", pure DOS will enter "protected mode" from "real mode", but at this time pure DOS is running in "protected mode" of privilege level 0, and the code is not affected!
Since the above code uses 32-bit instructions, modify the 16-bit code as:
BOOL IsWindowVM()
{
DWORD dwCr0;
WORD wMsw;
// read MSW
__emit__(0x0F, 0x01, 0xE0);//asm mov smsw ax
asm mov wMsw, ax
// Read cr0
asm mov ax, wMsw
asm inc ax
__emit__(0x0F, 0x20, 0xC0); //asm mov eax, cr0
// eax to dwCr0
__emit__(0x66, 0x50); //asm push eax
asm pop ax
asm pop dx
asm mov word ptr dwCr0 + 0, ax
asm mov word ptr dwCr0 + 2, dx
// judge
return ((wMsw == (WORD)(dwCr0 & 0xFFFFlu)) ? FALSE : TRUE);
}
[ Last edited by firstsail on 2008-3-14 at 08:21 PM ]