检查虚拟机是否存在的一些方法包括:
- 查找由VM Guest工具创建的进程、文件、注册表条目等VM工件的存在
- 使用虚拟化软件公开的非标准x86指令
如果想了解更多信息,可以在此处查看一个很好的演示文稿。
由于第二种方法最简单和直接,我们将使用它。
以下代码片段可用于检查代码是否在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
是微软特定的C++扩展。您需要在Windows上使用Visual Studio进行编译,而不能使用
gcc
。
下载并安装以下组件 -
- Visual Studio 2005(或更高版本)
- Microsoft Platform 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中调用它。
下载
JNA库,该库需要从Java中调用本机代码。
创建一个Eclipse项目,并将
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.");
}
}
这是一张屏幕截图,显示最终代码在虚拟机上运行 -