dELTA
January 17th, 2008, 04:28
The following two VM detection methods were just reported by Sirmabus in a blog comment at another site, and I thought they deserved a better fate than that, so enjoy. 
------------------
Yet another simple way for VMWARE I found in use:
// Does a VMWARE command to test for it's presence (causes an exception if it's not incidentally)
.text:10009370 mov eax, 564D5868h
.text:10009375 mov ebx, 0
.text:1000937A mov ecx, 0Ah
.text:1000937F mov edx, 5658h
.text:10009384 in eax, dx
.text:10009385 cmp ebx, 564D5868h
.text:1000938B setz [ebp+var_bResult]
..
..
return(var_bResult)
And one for finding Virtual PC, etc.
The huge dump here you can see is basically using WMI to compare CPU "manufacture" names.
"ConnectixCPU", "Virtual CPU ", "VPC6", and "VPC7":
IID *__usercall EnumCPUFunc00<eax>(int a1<edi>, int a2, int a3)
{
WORD *ST20_4_0; // ST20_4@0
int ST30_4_0; // ST30_4@0
WORD *ST34_4_0; // ST34_4@0
int ST38_4_0; // ST38_4@0
int ST3C_4_0; // ST3C_4@0
int ST40_4_0; // ST40_4@0
LONG ST44_4_0; // ST44_4@0
void *ST5C_4_0; // ST5C_4@0
LONG ST60_4_0; // ST60_4@0
SOLE_AUTHENTICATION_SERVICE *ST64_4_0; // ST64_4@0
void *ST68_4_0; // ST68_4@0
DWORD ST6C_4_0; // ST6C_4@0
DWORD ST70_4_0; // ST70_4@0
void *ST74_4_0; // ST74_4@0
DWORD ST78_4_0; // ST78_4@0
void *ST7C_4_0; // ST7C_4@0
int v19; // ST5C_4@1
const CLSID *v20; // ST6C_4@1
IUnknown *v21; // ST70_4@1
DWORD v22; // ST74_4@1
const IID *v23; // ST78_4@1
LPVOID *v24; // ST7C_4@1
WORD *v25; // eax@10
OLECHAR *v26; // eax@12
OLECHAR *v27; // esi@12
HRESULT v28; // eax@14
int v29; // ST1C_4@16
LONG v30; // esi@17
HRESULT v31; // eax@20
HRESULT v32; // eax@22
void *v33; // eax@24
void *v34; // esi@24
int v35; // ebx@28
void *v36; // eax@32
void *v37; // esi@32
int v38; // ecx@39
LPVOID v40; // ST7C_4@1
int v41; // edx@4
int v42; // edx@6
int v43; // edx@8
int v44; // ecx@9
void *v45; // eax@17
int v46; // edx@20
int v47; // eax@25
int v48; // eax@33
IID *v49; // esi@74
int v50; // [sp+84h] [bp-50h]@1
signed int v51; // [sp+D0h] [bp-4h]@1
IID *v52; // [sp+5Ch] [bp-78h]@1
VARIANTARG pvargSrc; // [sp+4Ch] [bp-88h]@1
VARIANTARG pvarSrc; // [sp+3Ch] [bp-98h]@1
LPVOID ppv; // [sp+7Ch] [bp-58h]@2
int v56; // [sp+78h] [bp-5Ch]@4
VARIANTARG pvarg; // [sp+2Ch] [bp-A8h]@6
int v58; // [sp+24h] [bp-B0h]@8
void *v59; // [sp+20h] [bp-B4h]@8
WORD *v60; // [sp+1Ch] [bp-B8h]@9
signed int v61; // [sp+14h] [bp-C0h]@9
char v62; // [sp+64h] [bp-70h]@13
int v63; // [sp+70h] [bp-64h]@43
ST7C_4_0 = cNULL;
v50 = 0;
CStringConstructFunc01(ST7C_4_0);
ST7C_4_0 = 0;
v51 = 1;
*(_BYTE *)a3 = 0;
CoInitialize(v40);
ST7C_4_0 = 0;
v52 = 0;
*(_QWORD *)&pvargSrc.lVal = 3i64;
*(_QWORD *)&pvargSrc.vt = 4294967296i64;
*(_QWORD *)&pvarSrc.lVal = 4294967295i64;
*(_DWORD *)&pvarSrc.wReserved2 = 0;
if ( CoInitializeSecurity(ST5C_4_0, ST60_4_0, ST64_4_0, ST68_4_0, ST6C_4_0, ST70_4_0, ST74_4_0, ST78_4_0, v24) >= 0 )
{
ppv = 0;
ST7C_4_0 = &ppv;
v52 = &IID_IUnknown;
*(_QWORD *)&pvargSrc.lVal = 21474836480i64;
*(_DWORD *)&pvargSrc.wReserved2 = &stru_10023784;
if ( CoCreateInstance(v20, v21, v22, v23, v24) < 0 )
goto LABEL_72;
if ( !ppv )
goto LABEL_74;
v56 = 0;
v41 = *(_DWORD *)ppv;
ST7C_4_0 = &v56;
v52 = 0;
*(_QWORD *)&pvargSrc.lVal = 0i64;
*(_QWORD *)&pvargSrc.vt = 0i64;
*((_DWORD *)&pvarSrc.lVal + 1) = 0;
pvarSrc.lVal = (LONG)L"root\\cimv2";
*(_DWORD *)&pvarSrc.wReserved2 = ppv;
if ( (*(int (__cdecl **)(int))(v41 + 12))(v19) < 0 || !pvargSrc.lVal )
goto LABEL_72;
*(_DWORD *)&pvargSrc.wReserved2 = 0;
v42 = *(_DWORD *)pvargSrc.lVal;
*(_DWORD *)&pvarSrc.vt = &pvargSrc.wReserved2;
*(_QWORD *)&pvarg.lVal = 16i64;
*(_DWORD *)&pvarg.wReserved2 = L"Select * from Win32_Processor";
*(_DWORD *)&pvarg.vt = L"WQL";
ST44_4_0 = pvargSrc.lVal;
if ( (*(int (__cdecl **)(LONG))(v42 + 80))(ST44_4_0) < 0 || !*((_DWORD *)&pvarg.lVal + 1) )
{
LABEL_70:
if ( ST20_4_0 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
LABEL_72:
if ( ST20_4_0 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
goto LABEL_74;
}
v43 = **((_DWORD **)&pvarg.lVal + 1);
v58 = a1;
v59 = (void *)*((_DWORD *)&pvarg.lVal + 1);
if ( (*(int (__cdecl **)(int, int))(v43 + 12))(ST3C_4_0, ST40_4_0) >= 0 )
{
v60 = &pvarSrc.wReserved2;
ST34_4_0 = &pvarg.wReserved2;
*(_DWORD *)&pvarg.wReserved2 = 0;
v44 = *(_DWORD *)pvarg.lVal;
v61 = 1;
if ( (*(int (__cdecl **)(LONG, signed int, int, WORD *, int))(v44 + 16))(pvarg.lVal, -1, ST30_4_0, ST34_4_0, ST38_4_0) < 0 )
goto LABEL_65;
v25 = v60;
if ( v60 )
{
if ( *(_DWORD *)&pvarg < 1u )
goto LABEL_66;
v26 = SysAllocString(L"Manufacturer"
;
v27 = v26;
if ( v26 )
{
SysFreeString(v26);
ST20_4_0 = 0;
if ( (*(int (__cdecl **)(WORD *, OLECHAR *, _DWORD, char *))(*(_DWORD *)v60 + 16))(v60, v27, 0, &v62) >= 0 )
{
VariantInit(&pvarg);
v28 = VariantCopy(&pvarg, &pvargSrc);
if ( v28 < 0 )
sub_1001234F(v28);
v29 = 0;
v62 = 2;
if ( (_WORD)pvarg.vt == 8 )
{
v30 = pvarg.lVal;
sub_1000A080();
v45 = operator new(0xCu);
v60 = (WORD *)v45;
v62 = 3;
if ( v45 )
v29 = sub_1000A1B0((OLECHAR *)v30);
else
v29 = 0;
}
else
{
VariantInit(&pvarSrc);
v62 = 4;
sub_1000A2D0(&pvarSrc, v46, 8u, (int)&pvarg);
sub_1000A0D0((OLECHAR *)pvarSrc.lVal);
v62 = 2;
v31 = VariantClear(&pvarSrc);
if ( v31 < 0 )
sub_1001234F(v31);
}
v62 = 6;
v32 = VariantClear(&pvarg);
if ( v32 < 0 )
sub_1001234F(v32);
v33 = operator new(0xCu);
v34 = v33;
v60 = (WORD *)v33;
v62 = 7;
if ( v33 )
{
*((_DWORD *)v33 + 1) = 0;
*((_DWORD *)v33 + 2) = 1;
v47 = sub_1001227E("ConnectixCPU"
; -- Anyone? What VM is this?
*(_DWORD *)v34 = v47;
if ( !v47 )
{
if ( "ConnectixCPU" )
sub_1001234F(-2147024882);
}
v35 = (int)v34;
}
else
{
v35 = 0;
}
v62 = 6;
v60 = (WORD *)v35;
if ( !v35 )
sub_1001234F(-2147024882);
v62 = 8;
v36 = operator new(0xCu);
v37 = v36;
v59 = v36;
v62 = 9;
if ( v36 )
{
*((_DWORD *)v36 + 1) = 0;
*((_DWORD *)v36 + 2) = 1;
v48 = sub_1001227E("Virtual CPU "
;
*(_DWORD *)v37 = v48;
if ( !v48 )
{
if ( "Virtual CPU " )
sub_1001234F(-2147024882);
}
}
else
{
v37 = 0;
}
v62 = 8;
v59 = v37;
if ( !v37 )
sub_1001234F(-2147024882);
v38 = v29;
v62 = 10;
if ( v29 == v35 )
goto LABEL_43;
if ( v29 && v35 )
{
if ( !sub_1000A1F0(v35) )
{
LABEL_43:
*(_BYTE *)v63 = 1;
ConstructorFunc02("VPC6"
;
LABEL_51:
VariantClear(&pvargSrc);
v62 = 8;
if ( v37 )
{
if ( !InterlockedDecrement((LPLONG)v37 + 2) )
{
sub_1000A2A0();
FreeDataFunc00(v37);
}
}
v62 = 6;
if ( v35 )
{
if ( !InterlockedDecrement((LPLONG)(v35 + 8)) )
{
sub_1000A2A0();
FreeDataFunc00(v35);
}
}
v62 = 1;
if ( v29 )
{
if ( !InterlockedDecrement((LPLONG)(v29 + 8)) )
{
if ( v29 )
{
if ( *(_DWORD *)v29 )
SysFreeString(*(BSTR *)v29);
if ( *(_DWORD *)(v29 + 4) )
FreeDataFunc00(*(_DWORD *)(v29 + 4));
FreeDataFunc00(v29);
}
}
}
goto LABEL_65;
}
v38 = v29;
}
if ( v38 == (_DWORD)v37 || v38 && v37 && !sub_1000A1F0(v37) )
{
*(_BYTE *)v63 = 1;
ConstructorFunc02("VPC7"
;
}
else
{
*(_BYTE *)v63 = 0;
}
goto LABEL_51;
}
}
LABEL_65:
v25 = ST20_4_0;
LABEL_66:
if ( v25 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)v25 + 8))(v25);
goto LABEL_68;
}
}
LABEL_68:
if ( ST20_4_0 )
(*(int (__cdecl **)(_DWORD))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
goto LABEL_70;
}
LABEL_74:
CoUninitialize();
v49 = v52;
CStringConstructFunc02(&v61);
LOBYTE(pvargSrc.lVal) = 0;
CStringDestructFunc00();
return v49;
}

------------------
Yet another simple way for VMWARE I found in use:
// Does a VMWARE command to test for it's presence (causes an exception if it's not incidentally)
.text:10009370 mov eax, 564D5868h
.text:10009375 mov ebx, 0
.text:1000937A mov ecx, 0Ah
.text:1000937F mov edx, 5658h
.text:10009384 in eax, dx
.text:10009385 cmp ebx, 564D5868h
.text:1000938B setz [ebp+var_bResult]
..
..
return(var_bResult)
And one for finding Virtual PC, etc.
The huge dump here you can see is basically using WMI to compare CPU "manufacture" names.
"ConnectixCPU", "Virtual CPU ", "VPC6", and "VPC7":
IID *__usercall EnumCPUFunc00<eax>(int a1<edi>, int a2, int a3)
{
WORD *ST20_4_0; // ST20_4@0
int ST30_4_0; // ST30_4@0
WORD *ST34_4_0; // ST34_4@0
int ST38_4_0; // ST38_4@0
int ST3C_4_0; // ST3C_4@0
int ST40_4_0; // ST40_4@0
LONG ST44_4_0; // ST44_4@0
void *ST5C_4_0; // ST5C_4@0
LONG ST60_4_0; // ST60_4@0
SOLE_AUTHENTICATION_SERVICE *ST64_4_0; // ST64_4@0
void *ST68_4_0; // ST68_4@0
DWORD ST6C_4_0; // ST6C_4@0
DWORD ST70_4_0; // ST70_4@0
void *ST74_4_0; // ST74_4@0
DWORD ST78_4_0; // ST78_4@0
void *ST7C_4_0; // ST7C_4@0
int v19; // ST5C_4@1
const CLSID *v20; // ST6C_4@1
IUnknown *v21; // ST70_4@1
DWORD v22; // ST74_4@1
const IID *v23; // ST78_4@1
LPVOID *v24; // ST7C_4@1
WORD *v25; // eax@10
OLECHAR *v26; // eax@12
OLECHAR *v27; // esi@12
HRESULT v28; // eax@14
int v29; // ST1C_4@16
LONG v30; // esi@17
HRESULT v31; // eax@20
HRESULT v32; // eax@22
void *v33; // eax@24
void *v34; // esi@24
int v35; // ebx@28
void *v36; // eax@32
void *v37; // esi@32
int v38; // ecx@39
LPVOID v40; // ST7C_4@1
int v41; // edx@4
int v42; // edx@6
int v43; // edx@8
int v44; // ecx@9
void *v45; // eax@17
int v46; // edx@20
int v47; // eax@25
int v48; // eax@33
IID *v49; // esi@74
int v50; // [sp+84h] [bp-50h]@1
signed int v51; // [sp+D0h] [bp-4h]@1
IID *v52; // [sp+5Ch] [bp-78h]@1
VARIANTARG pvargSrc; // [sp+4Ch] [bp-88h]@1
VARIANTARG pvarSrc; // [sp+3Ch] [bp-98h]@1
LPVOID ppv; // [sp+7Ch] [bp-58h]@2
int v56; // [sp+78h] [bp-5Ch]@4
VARIANTARG pvarg; // [sp+2Ch] [bp-A8h]@6
int v58; // [sp+24h] [bp-B0h]@8
void *v59; // [sp+20h] [bp-B4h]@8
WORD *v60; // [sp+1Ch] [bp-B8h]@9
signed int v61; // [sp+14h] [bp-C0h]@9
char v62; // [sp+64h] [bp-70h]@13
int v63; // [sp+70h] [bp-64h]@43
ST7C_4_0 = cNULL;
v50 = 0;
CStringConstructFunc01(ST7C_4_0);
ST7C_4_0 = 0;
v51 = 1;
*(_BYTE *)a3 = 0;
CoInitialize(v40);
ST7C_4_0 = 0;
v52 = 0;
*(_QWORD *)&pvargSrc.lVal = 3i64;
*(_QWORD *)&pvargSrc.vt = 4294967296i64;
*(_QWORD *)&pvarSrc.lVal = 4294967295i64;
*(_DWORD *)&pvarSrc.wReserved2 = 0;
if ( CoInitializeSecurity(ST5C_4_0, ST60_4_0, ST64_4_0, ST68_4_0, ST6C_4_0, ST70_4_0, ST74_4_0, ST78_4_0, v24) >= 0 )
{
ppv = 0;
ST7C_4_0 = &ppv;
v52 = &IID_IUnknown;
*(_QWORD *)&pvargSrc.lVal = 21474836480i64;
*(_DWORD *)&pvargSrc.wReserved2 = &stru_10023784;
if ( CoCreateInstance(v20, v21, v22, v23, v24) < 0 )
goto LABEL_72;
if ( !ppv )
goto LABEL_74;
v56 = 0;
v41 = *(_DWORD *)ppv;
ST7C_4_0 = &v56;
v52 = 0;
*(_QWORD *)&pvargSrc.lVal = 0i64;
*(_QWORD *)&pvargSrc.vt = 0i64;
*((_DWORD *)&pvarSrc.lVal + 1) = 0;
pvarSrc.lVal = (LONG)L"root\\cimv2";
*(_DWORD *)&pvarSrc.wReserved2 = ppv;
if ( (*(int (__cdecl **)(int))(v41 + 12))(v19) < 0 || !pvargSrc.lVal )
goto LABEL_72;
*(_DWORD *)&pvargSrc.wReserved2 = 0;
v42 = *(_DWORD *)pvargSrc.lVal;
*(_DWORD *)&pvarSrc.vt = &pvargSrc.wReserved2;
*(_QWORD *)&pvarg.lVal = 16i64;
*(_DWORD *)&pvarg.wReserved2 = L"Select * from Win32_Processor";
*(_DWORD *)&pvarg.vt = L"WQL";
ST44_4_0 = pvargSrc.lVal;
if ( (*(int (__cdecl **)(LONG))(v42 + 80))(ST44_4_0) < 0 || !*((_DWORD *)&pvarg.lVal + 1) )
{
LABEL_70:
if ( ST20_4_0 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
LABEL_72:
if ( ST20_4_0 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
goto LABEL_74;
}
v43 = **((_DWORD **)&pvarg.lVal + 1);
v58 = a1;
v59 = (void *)*((_DWORD *)&pvarg.lVal + 1);
if ( (*(int (__cdecl **)(int, int))(v43 + 12))(ST3C_4_0, ST40_4_0) >= 0 )
{
v60 = &pvarSrc.wReserved2;
ST34_4_0 = &pvarg.wReserved2;
*(_DWORD *)&pvarg.wReserved2 = 0;
v44 = *(_DWORD *)pvarg.lVal;
v61 = 1;
if ( (*(int (__cdecl **)(LONG, signed int, int, WORD *, int))(v44 + 16))(pvarg.lVal, -1, ST30_4_0, ST34_4_0, ST38_4_0) < 0 )
goto LABEL_65;
v25 = v60;
if ( v60 )
{
if ( *(_DWORD *)&pvarg < 1u )
goto LABEL_66;
v26 = SysAllocString(L"Manufacturer"

v27 = v26;
if ( v26 )
{
SysFreeString(v26);
ST20_4_0 = 0;
if ( (*(int (__cdecl **)(WORD *, OLECHAR *, _DWORD, char *))(*(_DWORD *)v60 + 16))(v60, v27, 0, &v62) >= 0 )
{
VariantInit(&pvarg);
v28 = VariantCopy(&pvarg, &pvargSrc);
if ( v28 < 0 )
sub_1001234F(v28);
v29 = 0;
v62 = 2;
if ( (_WORD)pvarg.vt == 8 )
{
v30 = pvarg.lVal;
sub_1000A080();
v45 = operator new(0xCu);
v60 = (WORD *)v45;
v62 = 3;
if ( v45 )
v29 = sub_1000A1B0((OLECHAR *)v30);
else
v29 = 0;
}
else
{
VariantInit(&pvarSrc);
v62 = 4;
sub_1000A2D0(&pvarSrc, v46, 8u, (int)&pvarg);
sub_1000A0D0((OLECHAR *)pvarSrc.lVal);
v62 = 2;
v31 = VariantClear(&pvarSrc);
if ( v31 < 0 )
sub_1001234F(v31);
}
v62 = 6;
v32 = VariantClear(&pvarg);
if ( v32 < 0 )
sub_1001234F(v32);
v33 = operator new(0xCu);
v34 = v33;
v60 = (WORD *)v33;
v62 = 7;
if ( v33 )
{
*((_DWORD *)v33 + 1) = 0;
*((_DWORD *)v33 + 2) = 1;
v47 = sub_1001227E("ConnectixCPU"

*(_DWORD *)v34 = v47;
if ( !v47 )
{
if ( "ConnectixCPU" )
sub_1001234F(-2147024882);
}
v35 = (int)v34;
}
else
{
v35 = 0;
}
v62 = 6;
v60 = (WORD *)v35;
if ( !v35 )
sub_1001234F(-2147024882);
v62 = 8;
v36 = operator new(0xCu);
v37 = v36;
v59 = v36;
v62 = 9;
if ( v36 )
{
*((_DWORD *)v36 + 1) = 0;
*((_DWORD *)v36 + 2) = 1;
v48 = sub_1001227E("Virtual CPU "

*(_DWORD *)v37 = v48;
if ( !v48 )
{
if ( "Virtual CPU " )
sub_1001234F(-2147024882);
}
}
else
{
v37 = 0;
}
v62 = 8;
v59 = v37;
if ( !v37 )
sub_1001234F(-2147024882);
v38 = v29;
v62 = 10;
if ( v29 == v35 )
goto LABEL_43;
if ( v29 && v35 )
{
if ( !sub_1000A1F0(v35) )
{
LABEL_43:
*(_BYTE *)v63 = 1;
ConstructorFunc02("VPC6"

LABEL_51:
VariantClear(&pvargSrc);
v62 = 8;
if ( v37 )
{
if ( !InterlockedDecrement((LPLONG)v37 + 2) )
{
sub_1000A2A0();
FreeDataFunc00(v37);
}
}
v62 = 6;
if ( v35 )
{
if ( !InterlockedDecrement((LPLONG)(v35 + 8)) )
{
sub_1000A2A0();
FreeDataFunc00(v35);
}
}
v62 = 1;
if ( v29 )
{
if ( !InterlockedDecrement((LPLONG)(v29 + 8)) )
{
if ( v29 )
{
if ( *(_DWORD *)v29 )
SysFreeString(*(BSTR *)v29);
if ( *(_DWORD *)(v29 + 4) )
FreeDataFunc00(*(_DWORD *)(v29 + 4));
FreeDataFunc00(v29);
}
}
}
goto LABEL_65;
}
v38 = v29;
}
if ( v38 == (_DWORD)v37 || v38 && v37 && !sub_1000A1F0(v37) )
{
*(_BYTE *)v63 = 1;
ConstructorFunc02("VPC7"

}
else
{
*(_BYTE *)v63 = 0;
}
goto LABEL_51;
}
}
LABEL_65:
v25 = ST20_4_0;
LABEL_66:
if ( v25 )
(*(int (__cdecl **)(WORD *))(*(_DWORD *)v25 + 8))(v25);
goto LABEL_68;
}
}
LABEL_68:
if ( ST20_4_0 )
(*(int (__cdecl **)(_DWORD))(*(_DWORD *)ST20_4_0 + 8))(ST20_4_0);
goto LABEL_70;
}
LABEL_74:
CoUninitialize();
v49 = v52;
CStringConstructFunc02(&v61);
LOBYTE(pvargSrc.lVal) = 0;
CStringDestructFunc00();
return v49;
}