NOEMBLEM/エンブレムが設定されていません。

メールの詳細(メール表示)

件名:

VMware 検出コード

差出人: KATO Kenjiさん
送信日時 2002/05/20 18:32
ML.NO [vmware-j:1230]
本文:

加藤です

ちょっと面白いコードを見つけたので紹介します。
現在の実行環境が VMware 内かどうかを判別するコードです。
ネタ元は news.vmware.com で、vmware や vmware-tools が
判定に利用しているのも基本的にこれと同じ方法だそうです。

3 年ほど前(VMware 1.0 の頃?)の記事ですが、VMware 3.1
でも判定方法は変わっていないようです。

GNUC / WIN32 用の C ソース (vmaware - 打ち間違いではあり
ません、念のため。VMware + aware = vmaware のようです) と、
DOS 用の com 作成スクリプト(vmvers) があります。

vmaware 方は、Win9x(VC++ 6.0)と Linux(gcc 2.95.3)で
VMware 3.1.1/2.0.4、物理マシン取り混ぜて試してみましたが
ちゃんと判定できました。ただし WinNT 系では駄目でした。
I/O コールを使用しているためで、アプリケーション例外で
落ちます。多分カーネルモードドライバを書かないといけない
のだと思います。

vmvers の方は、DOS、Win9x、WinNT/2K すべて OK でした。
こちらは完全に DOS プログラムなので、NT の仮想 DOS 環境
が I/O コールの面倒を見てくれているようです。

では少々長くなりますが...

========== vmaware.c ここから ==========
/* **********************************************************
* Copyright (C) 1998 VMWare, Inc.
* All Rights Reserved
* $Id: vmaware.c,v 1.1 1999/03/23 05:26:39 bugnion Exp $
* **********************************************************/

/*
* small app that checks if we are running inside a VM.
* The app SEGV on Operating systems that offer I/O space protection
* exit(0) only if we are running inside a virtual machine
*/

#include <stdio.h>
#include <process.h>

#define BDOOR_MAGIC 0x564D5868
#define BDOOR_CMD_GETVERSION 10
#define BDOOR_PORT 0x5658

typedef unsigned short uint16;
typedef unsigned uint32;

#ifdef __GNUC__

void
getVersion(uint32 *version,
uint32 *magic)
{
uint32 x,y;
__asm__ __volatile__("pushl %%ebxnt"
"pushl %%ecxnt"
"pushl %%edxnt" ::);

__asm__ __volatile__("movl $10, %%ecx"::);
__asm__ __volatile__("movl $0x564D5868, %%eax"::);
__asm__ __volatile__("inl %w1,%w0nt"
: "=a" (x) : "d" (BDOOR_PORT) );
__asm__ __volatile("movl %%ebx, %0" :"=r" (y));

__asm__ __volatile__("popl %%edxnt"
"popl %%ecxnt"
"popl %%ebxnt" ::);

*version = x;
*magic = y;
}

#elif _WIN32

void
getVersion(uint32 *version, uint32 *magic)
{
uint32 v;
uint32 m;

_asm {
push eax
push ebx
push ecx
push edx

mov eax, BDOOR_MAGIC
mov ecx, BDOOR_CMD_GETVERSION
mov dx, BDOOR_PORT
in eax, dx
mov v, eax
mov m, ebx

pop edx
pop ecx
pop ebx
pop eax
}

*version = v;
*magic = m;
}
#endif

main(int argc,
char **argv)
{
uint32 version;
uint32 magic;

getVersion(&version, &magic);
if (magic != BDOOR_MAGIC) {
printf("Not running inside a VM (version=0x%x magic=0x%x)n",version,magic);
exit(1);
} else {
printf("Thank you for running VMwaren");
// success
exit(0);
}
}
========== vmaware.c ここまで ==========

========== vmvers.dbg ここから ==========
n vmvers.com
e 100 66 b8 68 58 4d 56 66 b9 0a 00 00 00 ba 58 56 66
e 110 ed 66 81 fb 68 58 4d 56 74 03 66 33 c0 b4 4c cd
e 120 21
r bx
0
r cx
21
w
q
========== vmvers.dbg ここまで ==========

vmvers.dbg ファイルを作成して、DOS または DOS 窓で
debug.exe < vmvers.dbg
を実行すると、vmvers.com ができます。
単にバイナリエディタなどで e 100 - e 120 の行にある
33 バイトを直接入力しても良いですが...

vmaware と違って、vmvers.com は実行してもなにも表示せず、
VMware 内で実行されている場合は 1 以上、VMware ではない
場合には 0 の終了ステータスを返します。
バッチファイルで以下のように使用します。

vmvers.com
if errorlevel 1 goto inside_vm

echo Not in VMware
...

inside_vm:
echo VMware detected!
...

--
KATO Kenji (kenjik@…)

このエントリーをはてなブックマークに追加
添付:

このメールには下記のメールが返信されています: