VM の存在を確認するいくつかの方法は次のとおりです。
- VM ゲスト ツールによって作成されたプロセス、ファイル、レジストリ エントリなどの VM アーティファクトの存在を探す
- 仮想化ソフトウェアによって公開された非標準の 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 の目的が無効になります。したがって、上記のコードを自分でコンパイルして DLL を作成する必要がありました。
__try
および__catch
Microsoft 固有の C++ 拡張機能です。使用すると機能しないため、これを Windows の Visual Studio でコンパイルする必要がありますgcc
。
次のコンポーネントをダウンロードしてインストールします -
- Visual Studio 2005 (またはそれ以降)
- マイクロソフト プラットフォーム SDK 2003
新しい DLL プロジェクトを作成し、上記のコードをメインの CPP ファイルに貼り付けます。
関数をエクスポートするには、これをコードに追加します。これがないと、DLL はコンパイルされますが、関数は外部から呼び出すことができません。
extern "C" __declspec(dllexport)
bool IsInsideVMWare()
{
//Code
}
ここで、Visual Studio プロジェクトをビルドして DLL をコンパイルします。not found やその他のエラーなどのエラーが発生した場合はwindows.h
、これらのスタックオーバーフローの質問を参照してください -
関数が DLL にエクスポートされたかどうかを確認するには、DLL エクスポート ビューアーを使用して、DLL によってエクスポートされた (公開された) 関数のリストを表示します。
これで、VM の存在をチェックするコンポーネントができました。Java から呼び出すだけです。
Java からネイティブ コードを呼び出すために必要なJNAライブラリをダウンロードします。Eclipse プロジェクトを作成し、DLL
andJNA
をクラスパスに追加します。
次のファイルを作成します -
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 で実行される最終的なコードを示すスクリーンショットを次に示します。