64位windows VMware检测 [英] 64-bit windows VMware detection

查看:19
本文介绍了64位windows VMware检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个应用程序来检测程序是否在虚拟机中运行.

I am trying to develop an application which detects if program is running inside a virtual machine.

对于 32 位 Windows,已经在以下链接中解释了方法:http://www.codeproject.com/Articles/9823/检测如果你的程序正在运行内部虚拟

For 32-bit Windows, there are already methods explained in the following link: http://www.codeproject.com/Articles/9823/Detect-if-your-program-is-running-inside-a-Virtual

我正在尝试在 64 位 Windows 操作系统中调整有关 Virtual PC 和 VMware 检测的代码.对于 VMware,该代码可以在 Windows XP 64 位操作系统中成功检测.但是当我在本机系统(Windows 7 64 位操作系统)中运行它时,程序崩溃了.

I am trying to adapt the code regarding Virtual PC and VMware detection in an 64-bit Windows operating system. For VMware, the code can detect successfully in an Windows XP 64-bit OS. But the program crashes when I run it in a native system (Windows 7 64-bit OS).

我将代码放在 .asm 文件中,并使用 ml64.exe 文件定义自定义构建步骤.64 位 Windows 的 asm 代码是:

I put the code in an .asm file and define custom build step with ml64.exe file. The asm code for 64-bit Windows is:

IsInsideVM proc

      push   rdx
      push   rcx
      push   rbx

      mov    rax, 'VMXh'
      mov    rbx, 0     ; any value but not the MAGIC VALUE
      mov    rcx, 10    ; get VMWare version
      mov    rdx, 'VX'  ; port number

      in     rax, dx    ; read port
                        ; on return EAX returns the VERSION
      cmp    rbx, 'VMXh'; is it a reply from VMWare?
      setz   al         ; set return value
      movzx rax,al

      pop    rbx
      pop    rcx
      pop    rdx

      ret
IsInsideVM endp

我在 cpp 文件中调用此部分,例如:

I call this part in a cpp file like:

__try
{
returnValue = IsInsideVM();
}
__except(1)
{
    returnValue = false;
}

提前致谢.

推荐答案

来自 红色药丸"nofollow noreferrer">Joanna 可能有效:invisiblethings.org 博客的随机备份页面:

The old red pill from Joanna may work: random backup page of invisiblethings.org blog:

吞下红色药丸或多或少等价于以下代码(在矩阵中时返回非零):

Swallowing the Red Pill is more or less equivalent to the following code (returns non zero when in Matrix):

 int swallow_redpill () {
   unsigned char m[2+4], rpill[] = "x0fx01x0dx00x00x00x00xc3";
   *((unsigned*)&rpill[3]) = (unsigned)m;
   ((void(*)())&rpill)();
   return (m[5]>0xd0) ? 1 : 0;
 }

这段代码的核心其实是SIDT指令(编码为0F010D[addr]),它在目的操作数中存放了中断描述符表寄存器(ID​​TR)的内容,实际上是一个内存位置.SIDT 指令的特殊和有趣之处在于,它可以在非特权模式(ring3)下执行,但它返回敏感寄存器的内容,供操作系统内部使用.

The heart of this code is actually the SIDT instruction (encoded as 0F010D[addr]), which stores the contents of the interrupt descriptor table register (IDTR) in the destination operand, which is actually a memory location. What is special and interesting about SIDT instruction is that, it can be executed in non privileged mode (ring3) but it returns the contents of the sensitive register, used internally by operating system.

因为只有一个IDTR寄存器,但至少有两个OS同时运行(即host和guest OS),所以VMM需要将guest的IDTR重新定位到一个安全的地方,这样才不会与一个主人的.不幸的是,VMM 无法知道来宾操作系统中运行的进程是否(以及何时)执行 SIDT 指令,因为它没有特权(并且不会产生异常).这样进程就得到了IDT表的重定位地址.据观察,在 VMWare 上,IDT 的重定位地址在地址 0xffXXXXXX,而在 Virtual PC 上,它是 0xe8XXXXXX.这是在 VMWare Workstation 4 和 Virtual PC 2004 上测试过的,两者都运行在 Windows XP 主机操作系统上.

Because there is only one IDTR register, but there are at least two OS running concurrently (i.e. the host and the guest OS), VMM needs to relocate the guest's IDTR in a safe place, so that it will not conflict with a host's one. Unfortunately, VMM cannot know if (and when) the process running in guest OS executes SIDT instruction, since it is not privileged (and it doesn't generate exception). Thus the process gets the relocated address of IDT table. It was observed that on VMWare, the relocated address of IDT is at address 0xffXXXXXX, whereas on Virtual PC it is 0xe8XXXXXX. This was tested on VMWare Workstation 4 and Virtual PC 2004, both running on Windows XP host OS.

注意:我自己没有测试过,但看起来它使用了一种非特权的方法.如果最初不适用于 x64,进行一些调整可能会有所帮助.

Note: I haven't tested it myself but look that it uses an unprivileged approach. If it does not work at first for x64, some tweaking may help.

另外,刚刚发现了一个问题,内容可能对您有帮助:在 linux 上检测 VMM

Also, just found out a question with content that may help you: Detecting VMM on linux

这篇关于64位windows VMware检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆