检查虚拟机是否存在的一些方法是 -
- 寻找 VM 工件的存在,例如由 VM Guest 工具创建的进程、文件、注册表项
- 使用虚拟化软件公开的非标准 x86 指令
如果您想了解更多信息,这里有一个很好的演示文稿来讨论这些主题。
由于方法 2 是我们将使用的最简单直接的方法。
以下代码片段可用于检查代码是否在 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;
}
这是从Code Project上发布的项目中获取的代码的一部分。出于演示目的,它不包含检查Microsoft Virtual PC
. 您可以访问主站点以获取代码Virtual PC
和预编译的演示。该站点上还提供了一个 DLL,但具有讽刺意味的是,这些函数并未导出,这违背了 DLL 的目的,因为您无法在程序中调用它。因此我不得不自己编译上面的代码并创建一个 DLL。
__try
并且__catch
是 Microsoft 特定的 C++ 扩展。您需要在 Windows 上使用 Visual Studio 编译它,因为 usinggcc
不起作用。
下载并安装以下组件 -
- Visual Studio 2005(或更高版本)
- 微软平台 SDK 2003
创建一个新的 DLL 项目并将上述代码粘贴到主 CPP 文件中。
将此添加到您的代码中以导出您的函数。如果没有这个,您的 DLL 将被编译,但函数将无法从外部调用。
extern "C" __declspec(dllexport)
bool IsInsideVMWare()
{
//Code
}
现在通过构建 Visual Studio 项目来编译 DLL。如果您遇到windows.h
未找到或其他错误等错误,请参阅这些 stackoverflow 问题 -
要检查函数是否已导出到 DLL,您可以使用DLL Export Viewer 查看您的 DLL 导出(即公开)的函数列表。
现在我们有了检查 VM 存在的组件。我们需要做的就是从 Java 中调用它。
下载从 Java 调用本机代码所需的JNA库。创建一个 Eclipse 项目并将 and 添加DLL
到JNA
类路径中。
创建以下文件 -
VmCheck.java
package in.ksharma;
import com.sun.jna.Library;
public interface VmCheck extends Library {
boolean IsInsideVMWare();
boolean IsInsideVPC();
}
Test.java
package in.ksharma;
import com.sun.jna.Native;
public class Test {
public static void main(String[] args) {
VmCheck lib = (VmCheck) Native.loadLibrary("VmDetect.dll", VmCheck.class);
if(lib.IsInsideVMWare() || lib.IsInsideVPC())
System.out.println("I'm trapped in the matrix.");
else
System.out.println("I'm for real.");
}
}
这是显示在 VM 中运行的最终代码的屏幕截图 -