您的位置:首页 > 其它

判断程序的执行环境是VM

2008-03-21 09:20 246 查看
来段老V的代码 很古老的
抗VM分析
mov ecx, 0Ah ; CX=function# (0Ah=get_version)
mov eax, 'VMXh' ; EAX=magic
mov dx, 'VX' ; DX=magic
in eax, dx ; specially processed io cmd
; output: EAX/EBX/ECX = data
cmp ebx, 'VMXh' ; also eax/ecx modified (maybe vmw/os ver?)
je under_VMware


===

bool IsInsideVMWare()
{
bool rc = true;

__try
{
__asm
{
push edx
push ecx
push ebx

mov eax, 'VMXh'
mov ebx, 0 // any value but not the MAGIC VALUE
mov ecx, 10 // get VMWare version
mov edx, 'VX' // port number

in eax, dx // read port
// on return EAX returns the VERSION
cmp ebx, 'VMXh' // is it a reply from VMWare?
setz [rc] // set return value

pop ebx
pop ecx
pop edx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
rc = false;
}

return rc;
}

bool IsInsideVPC()
{
bool rc = false;

__try
{
_asm push ebx
_asm mov ebx, 0 // Flag
_asm mov eax, 1 // VPC function number

// call VPC
_asm __emit 0Fh
_asm __emit 3Fh
_asm __emit 07h
_asm __emit 0Bh

_asm test ebx, ebx
_asm setz [rc]
_asm pop ebx
}
// The except block shouldn't get triggered if VPC is running!!
__except(IsInsideVPC_exceptionFilter(GetExceptionInformation()))
{
}

return rc;
}
==============

给个通用判断的方法,不管VMWare或VirtuaPC都有效

int DCVM ()
{
unsigned char m[2+4], rpill[] = "/x0f/x01/x0d/x00/x00/x00/x00/xc3";
*((unsigned*)&rpill[3]) = (unsigned)m;
((void(*)())&rpill)();

printf ("idt base: %#x/n", *((unsigned*)&m[2]));
if (m[5]>0xd0) printf ("虚拟机/r/n", m[5]);
else printf ("真实机器/r/n");
return 0;
}
#include <stdio.h>

int LdtCheck()
{
unsigned char m[2];
__asm sldt m; //L,not i
printf("LDTR: %2.2x %2.2x/n", m[0], m[1]);
return (m[0] != 0x00 && m[1] != 0x00) ? 1 : 0;
}

int main(int argc, char * argv[])
{

if (LdtCheck())
printf("Virtual Machine detected./n");
else
printf("Native machine detected./n");

return 0;
}

#include <stdio.h>

inline int idtCheck ()
{
unsigned char m[2];
__asm sidt m;
printf("IDTR: %2.2x %2.2x/n", m[0], m[1]);
return (m[1]>0xd0) ? 1 : 0;
}

int gdtCheck()
{
unsigned char m[2];
__asm sgdt m;
printf("GDTR: %2.2x %2.2x/n", m[0], m[1]);
return (m[1]>0xd0) ? 1 : 0;
}

int ldtCheck()
{
unsigned char m[2];
__asm sldt m;
printf("LDTR: %2.2x %2.2x/n", m[0], m[1]);
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;
}
是能够测出来,但是编译时有下列警告信息,让人不爽。

C:/WINDDK/3790>cl test.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

test.c
test.c(7) : warning C4409: illegal instruction size
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj
*************************************************
' 检测程序是否运行于 VPC 虚拟机中
'
' 返回: 真表示运行在虚拟机中
' ------------------------------------------------
' 以下代码仅仅适用于在非标准模块中
' 这些代码根据BBS中bigwahaha提供的代码实现,本人未
' 进行测试检验, 有环境测试OK的用户请及时反馈
'*************************************************
Private Function IsInsideVPC() As Boolean
'_asm{overall}
'_asm{
' push ebp
' mov ebp,esp ;esp,retAdr,this,retVal

' assume fs:nothing
' push offset @F
' push fs:[0]
' mov fs:[0],esp

' push ebx
' xor ebx,ebx
' dec ebx ; 初始 EBX = TRUE (VB)
' mov eax, 1 ; VPC function number
' db 0Fh,3Fh,07h,0Bh
'
' ;设定返回值
' mov eax,[ebp+3*4]
' mov [eax],ebx
'
' pop ebx
' pop fs:[0]
' add esp,4
' leave
' xor eax,eax ;返回 S_OK
' ret 2*4
'
' @@:
' mov edx,dword ptr [esp+0CH]
' add dword ptr ds:[edx+0B8h],4 ; regEip
' xor eax,eax
' mov dword ptr ds:[edx+0A4h],eax ; regEbx,eax
' mov dword ptr ds:[edx],10007h ; ContextFlags,CONTEXT_FULL
' ret 4 * 4
'}
End Function

'*************************************************
' 检测程序是否运行于 VMWare 虚拟机中
'
' 返回: 真表示运行在虚拟机中
' ------------------------------------------------
' 以下代码仅仅适用于在非标准模块中
' 这些代码根据BBS中bigwahaha提供的代码实现,本人未
' 进行测试检验, 有环境测试OK的用户请及时反馈
'*************************************************
Private Function IsInsideVMWare() As Boolean
'_asm{overall}
'_asm{
' push ebp
' mov ebp,esp ;esp,retAdr,this,retVal
'
' assume fs:nothing
' push offset @IsInsideVMWare_error
' push fs:[0]
' mov fs:[0],esp
'
' push ebx
' mov eax, 'VMXh'
' xor ebx,ebx ; any value but not the MAGIC VALUE
' mov ecx, 10 ; get VMWare version
' mov dx, 'VX' ; port number
'
' in eax, dx ; read port
' ; on return EAX returns the VERSION
' xor edx,edx
' cmp ebx, 'VMXh' ; is it a reply from VMWare?
' jnz @F
' dec edx
' @@:
' ;设定返回值
' mov eax,[ebp+3*4]
' mov [eax],edx
'
' pop ebx
' pop fs:[0]
' add esp,4
' leave
' xor eax,eax ;返回 S_OK
' ret 2*4
'
' @IsInsideVMWare_error:
' mov edx,dword ptr [esp+0CH]
' inc dword ptr ds:[edx+0B8h] ; regEip
' xor eax,eax
' mov dword ptr ds:[edx],10007h ; ContextFlags,CONTEXT_FULL
' ret 4 * 4
'}
End Function
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: