判断程序的执行环境是VM

来段老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        eaxdx  ; 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

 


 

没有更多推荐了,返回首页