English | Japanese Author: Ken Kato
Mail: chitchat<DOT>vdk<AT>gmail<DOT>com

仮想な背中


仮想な背中 > VMware バックドア I/O ポート

VMware バックドア I/O ポート

お知らせ
バックドアに関するより正確な情報は Open Virtual Machine Tools のソースコードから得ることができます。 このページは Open Virtual Machine Tools が公開されるより以前に、私の個人的な調査と 各国の VMware ユーザの人たちが寄せてくれた情報を元に作成されました。

バックドアとは?

VMware Command Line Tools がどのようにして ホストマシンで走っている VMware と通信しているかを説明します。 正規の VMware-Tools も同様の方法を用いているようです。

一口に言うと、このやり取りは VMware の仮想マシン特有の I/O ポートにアクセス することによって実現されます(以下、このポートを「バックドア(裏口)」 と呼びます)。バックドア機能は以下のように呼び出します:

	/* Intel 表記 (MASM 他、多くの Windows 系アセンブラ) */

	MOV EAX, 564D5868h                      /* マジックナンバー  */
	MOV EBX, コマンド特有のパラメータ
	MOV CX,  バックドアコマンド番号
	MOV DX,  5658h                          /* VMware I/O ポート */

	IN  EAX, DX (または OUT DX, EAX)

	/* AT&T 表記 (gnu as 他、多くの unix 系アセンブラ)   */

	movl $0x564D5868, %eax;                 /* マジックナンバー  */
	movl コマンド特有のパラメータ, %ebx;
	movw バックドアコマンド番号, %cx;
	movw $0x5658, %dx;                      /* VMware I/O ポート */

	inl  %dx, %eax; (または outl %eax, %dx)
一見普通の I/O アクセスのように見えますが、ここで実行される IN/OUT 命令は通常とは全く異なる役割を果たします。ここでは I/O アクセス命令というよりも バックドア機能の呼び出し命令だと考えたほうがよいでしょう。

上記の例では、マジックナンバーなど EAXEBXCX レジスタの値が IN 命令の実行前に設定されています。 通常の IN 命令は DXOUTEAX/DX にのみ影響を 受けますが、バックドア機能はそれ以外のレジスタも入出力パラメータとして使用する ためです。実際には、バックドア機能はすべてのレジスタを入出力両方に使用すること があります。上記の例では EAXEBXCX および DX のみが使用されていますが、バックドアコマンドによっては ECXEDX の上位ワード、さらには ESIEDI および EBP も使用して 双方向のデータのやり取りを行います。

INOUT の違いは、OUT 命令を使用した場合は EAX に値が返却されないということのみです。その他の点ではどちらも全く同じ結果です。

このため、高級言語のライブラリ関数を使用してバックドアポートにアクセスする 事はおそらくできません(C ランタイムライブラリによくある _inp()/_outp() 関数など)。 このような関数は、IN/OUT 命令でこれらのレジスタが変更されることを 想定していないからです。

TOP

バックドアコマンド

以下の情報は主に Windows 版の VMware で調査したものです。間違いや Linux 版との違い、以下にあげられていない製品での情報など歓迎します。

コマンド番号 機能
サポート状況
Y: サポート
(Y): サポートされているが機能不明
N: 未サポート
?: サポート状況不明
WS 4.0 と 4.5 は違いが大きいため別々に表記します
Workstation GSX
2.x 3.x 4.0 4.5 5.x 2.5 3.2
00h ? (おそらく未使用) N N N N N N N
01h プロセッサスピード取得 (MHz) Y Y Y Y Y Y Y
02h APM ファンクション Y Y Y Y *1 Y *1 Y Y *1
03h ? (関連キーワード: getDiskGeometry) (Y) (Y) (Y) (Y) (Y) (Y) (Y)
04h マウスカーソル位置取得 Y Y Y Y Y Y Y
05h マウスカーソル位置設定 Y Y Y Y Y Y Y
06h ペーストテキスト長取得 Y Y Y Y Y Y Y
07h ペーストテキストデータ取得 Y Y Y Y Y Y Y
08h コピーテキスト長設定 Y Y Y Y Y Y Y
09h コピーテキストデータ設定 Y Y Y Y Y Y Y
0Ah VMware バージョン取得 Y Y Y Y Y Y Y
0Bh デバイス情報取得 Y Y Y Y Y Y Y
0Ch デバイス接続・切断 Y Y Y Y Y Y Y
0Dh GUIオプション設定取得 Y Y Y Y Y Y Y
0Eh GUIオプション設定更新 Y Y Y Y Y Y Y
0Fh ホスト画面サイズ取得 Y Y Y Y Y Y Y
10h ? (関連キーワード: monitorControl) (Y) N N N N N N
11h 仮想ハードウェアバージョン取得 (Y)*2 N N N Y N N
12h "OS not found" ダイアログ表示 N Y N*3 Y *1 Y *1 Y Y *1
13h BIOS UUID 取得 N N Y Y Y Y Y
14h メモリーサイズ取得 (MB) N Y Y Y Y Y Y
15h ? (Y) N N N N N N
16h ? (関連キーワード: getOS2IntCursor) (Y) (Y) (Y) (Y) N (Y) (Y)
17h ホストシステム時刻取得 (GMT) Y Y Y Y Y Y Y
18h ? (関連キーワード: stopCatchup) (Y) (Y) (Y) (Y) (Y) (Y) (Y)
19h ? (おそらく未使用) N N N N N N N
1Ah ? (おそらく未使用) N N N N N N N
1Bh ? (おそらく未使用) N N N N N N N
1Ch ? (関連キーワード: initScsiOprom) N N N (Y) (Y) N (Y)
1Dh ? (おそらく未使用) N N N N N N N
1Eh ゲスト・ホスト間 RPC Y Y Y Y Y Y Y
エンハンスト RPC N N Y Y Y N Y
1Fh ? (関連キーワード: rsvd0) (Y) (Y) (Y) (Y) (Y) (Y) (Y)
20h ? (関連キーワード: rsvd1) (Y) (Y) (Y) (Y) (Y) (Y) (Y)
21h ? (関連キーワード: rsvd2) (Y) (Y) (Y) (Y) (Y) (Y) (Y)
22h ? (関連キーワード: ACPID) N N (Y) (Y) (Y) N (Y)
23h ? (おそらく未使用) N N N N N (Y) N
24h ? (おそらく未使用) N N N N N N N
25h ? (関連キーワード: PatchSMBIOS) N N N (Y) (Y) N (Y)
26h ? (おそらく未使用) N N N N N N N
27h ? (関連キーワード: absMouseData) N N N (Y) (Y) N (Y)
28h ? (関連キーワード: absMouseStatus) N N N (Y) (Y) N (Y)
29h ? (関連キーワード: absMouseCommand) N N N (Y) (Y) N (Y)
2ah ? (おそらく未使用) N N N N N N N
2bh ? (関連キーワード: PatchACPITables) N N N N (Y) N N

*1: 仮想プロセッサがリアルモードの場合のみ動作 (起動 BIOS、リアルモード DOS など)。
*2: 別の機能として実装されていると思われる。
*3: 実装はされているが、仮想マシンの BIOS からのみ使用可能なようになっていて、 実質的にゲスト OS からは使用できない。

TOP

01h - プロセッサスピード取得 (MHz)

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0001h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = プロセッサスピード (MHz)
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
ホストマシンのプロセッサスピードを取得します。 返却される値は VMware によって測定された値です。 一例として、私の 1000MHz マシンでは大抵 3EAh (1,002) が返却されます。

この情報は Andrei Tarassov が報告してくれました。

TOP

02h - APM ファンクション

サポート状況
WS2.x WS3.x WS4.0 WS4.5(*) WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = APM ファンクション特有のパラメータ
ECX(HI) = APM ファンクション番号 (下記参照)
ECX(LO) = 0002h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ? / FFFFFFFFh: 失敗
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
仮想マシンの APM ファンクションを呼び出します。 現在以下のファンクション・パラメータの組み合わせの動作が確認されています:
APM ファンクション (ECX:HI) APM パラメータ (EBX:LO) 備考
0007h 0004h サスペンド。使用しないこと- このコマンドを使用すると仮想マシンをサスペンドすることができますが、 VMware のサスペンド機能とは互換性がないらしくリジュームすることが できなくなります。
0007h 0007h 電源オフ

(*) WS4.5/GSX3.2 以降では、このコマンドは仮想プロセッサが特権モードで稼動中 (リアルモード DOS、ブート時 BIOS など) の場合にのみ動作します。 WS4.0/GSX2.5 以前ではそのような制限なしに使用できます。

TOP

04h - マウスカーソル位置取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5(*) WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0004h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX(HI) = X 座標
EAX(LO) = Y 座標
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
マウスカーソルのゲストのスクリーン領域の左上隅からの相対座標を取得します。
ゲストがフォーカスを持っていない場合には FF9CFF9Ch (-100, -100) が返却される ため、ゲストがフォーカスを持っているかどうかの判別に使用することができます。

(*) WS4.5/GSX3.2 以降で "Ungrab when cursor leaves window" オプションが 有効になっている場合、ゲスト内にマウスカーソルが表示されていない場合でも (DOS、Linux コンソールなど) マウスカーソルの位置が追跡され、このコマンドを 実行した時点のカーソル位置がゲスト領域外だった場合にゲストからフォーカスが 開放されます。
このオプションが無効になっている場合にはカーソル位置は追跡されず、このコマンド で返却されるカーソル位置はゲストがフォーカースを得た時点のカーソル位置、 または最後にコマンド 05h で設定された位置となります。

TOP

05h - マウスカーソル位置設定

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX(HI) = X 座標
EBX(LO) = Y 座標
ECX(HI) = 無視される
ECX(LO) = 0005h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
ゲストのスクリーン領域に対するマウスカーソルの相対座標を設定します。 たとえばカーソル位置を (0, 0) に設定した場合、ゲストからフォーカスが 失われたときにゲストのスクリーン領域の左上隅にカーソルが出現します。

カーソル位置はゲストのスクリーン領域内である必要はありませんが、 座標値は符号なし整数として扱われるためマイナスの値を指定することはできません (たとえば (-1, -1) は (65535, 65535) として扱われるため、カーソルはホストの 右下の画面外に移動されることになります)。 カーソルをゲストの画面外に移動しても、ゲストからフォーカスが失われるまで カーソルはホスト内に描画されません。

TOP

06h - ペーストテキスト長取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5(*) WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0006h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = テキスト長
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
ホストのクリップボードから取得可能なテキストの長さを取得します。 また同時にクリップボードのデータ転送プロセスを初期化するため、 本コマンド実行直後のテキスト取得コマンド (07h) では常に先頭のデータが返却されます。

WS4.0/GSX2.5 以前ではテキストの最大長は 65335 です。 クリップボード内のテキストがそれより長い場合は 0 が返却されます。
WS4.5/GSX3.2 以降ではテキストの最大長は 65436 です。 クリップボード内のテキストがそれより長い場合は 65436 が返却され、 テキストはその長さに切り詰められます。取得可能なテキストデータがない場合、 またはテキストが既に一度転送済みの場合 FFFFFFFFh が返却されます (下記参照)。

WS4.0/GSX2.5 以前では、本コマンドは多くの場合実際に取得されるテキスト長より 若干大きい値(5 程度)を返却します。また Windows ホストでは CR/LF (0Dh+0Ah) はすべて2バイトとして数えられますが、以降のテキスト取得コマンドでは 0Dh がすべて取り除かれます。
WS4.5/GSX3.2 以降ではテキスト取得コマンドで取得できるテキストの正確な長さが 返却されます(終端 NULL 文字は含みません)。
一例として、クリップボード内のテキストが "xyz[0Dh][0Ah]" だった場合、 WS4.0/GSX2.5 以前では 10 が返却されますが、実際に取得できるテキストは "xyz[0Ah]" の 4 文字となります。
WS4.5/GSX3.2 以降では正確に 4 が返却されます。

(*) WS4.5/GSX3.2 以降での動作
WS4.5/GSX3.2 以降では、ペースト操作 (06h と 07h の組み合わせ) は、仮想マシンが フォーカスを取得したあと1回だけしか行うことができません。ペースト操作の途中で コマンド 06h を使用して操作をリセットすることは何度でもできますが、 最後の1バイトを取得した後は、テキスト長取得コマンド(06h)は常に FFFFFFFFh を返却し、テキスト取得コマンド(07h)は常に 00000000h を返却します。 一度フォーカスをリリース・再取得しない限り、同じクリップボードデータを何度も 取得することはできません。
またコピー操作 (08h と 09h の組み合わせ) は、ペースト操作を最後まで実行した 後でないと行うことができません。ペースト操作を完了する前にコピー操作を行った 場合、コマンドは VMware によって無視され、データはコピーされません。 ペースト操作を完了した後であれば、コピー操作を何度でも行うことができます。
上記二つの動作制限のため、途中で一度フォーカスをリリース・再取得しない限り、 ゲスト内でコピーしたデータを自分で再ペーストすることはできません。

    (フォーカス取得)->ペースト->ペースト = NG
    (フォーカス取得)->コピー = NG
    (フォーカス取得)->不完全なペースト->コピー = NG
    (フォーカス取得)->ペースト->コピー->コピー = OK
    (フォーカス取得)->ペースト->コピー->ペースト = NG
    (フォーカス取得)->ペースト->コピー->(フォーカスリリース・再取得)->ペースト = OK
上記の動作はしぶかわよしき氏が報告してくれました。
TOP

07h - ペーストテキスト取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0007h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = クリップボード内のテキスト中 4 バイト (LSB に先頭バイト)
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
クリップボード内のテキストデータを取得します。本コマンド実行前に、テキスト長 取得コマンド (06h) を実行します。 コマンド 06h 実行後最初の本コマンド実行で最初の 4 バイト、次の実行で後続の 4 バイト、という形でテキストデータが返却されます。
クリップボード内に未取得のテキストデータが残っていない場合 00000000h が返却 されます。
このコマンドでは CR 文字 (0Dh) が転送されないため、DOS ゲストなどでは取得された テキスト中の LF 文字 (0Ah) に応じて CR 文字を補完する必要があります。

WS4.0/GSX2.5 以前では、テキスト長取得コマンド (06h) で返却される値は実際の テキスト長より若干大きいことが多いため、実際のテキスト終端を検知するには 返却されるテキストデータ内の NULL 文字を検索したほうがよいでしょう。

コマンド 06h 「WS4.5/GSX3.2 以降での動作」も参照 してください。

TOP

08h - コピーテキスト長設定

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = テキスト長(終端 NULL 含まず)
ECX(HI) = 無視される
ECX(LO) = 0008h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
テキストデータのコピーを開始する前に実行します。また、コピー操作の途中で 操作をリセットして、最初からやり直す際にもこのコマンドを実行します。

コマンド 06h 「WS4.5/GSX3.2 以降での動作」も参照 してください。

TOP

09h - コピーテキストデータ設定

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = コピーテキスト中の 4 バイト (LSB に先頭バイト)
ECX(HI) = 無視される
ECX(LO) = 0009h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
ペーストテキスト取得コマンド (07h) と同様の手順で テキストをホストのクリップボードに転送します。

Windows ホストでは、テキスト中の LF 文字 (0Ah) に対して無条件に CR 文字 (0Dh) が補完されるため、このコマンドに CR 文字を渡してはいけません (本コマンドに '0Dh 0Ah' の組み合わせを渡した場合、ホストには '0Dh 0Dh 0Ah' が転送されます)。

コマンド 06h 「WS4.5/GSX3.2 以降での動作」も参照 してください。

TOP

0Ah - VMware バージョン取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される (マジックナンバー以外の任意の値)
ECX(HI) = 無視される
ECX(LO) = 000Ah - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = バージョン番号 (?)
EBX = 564D5868h - マジックナンバー
ECX = WS3.x/GSX2.5 以降ではプロダクト種別 / WS2.x では変化なし
EDX = 変化なし

詳細
プログラムが VMware 上で実行されているかどうかを判別することができます。 EBX にバックドアマジックナンバーば返却されていた場合、VMware 上で 実行されていると判断することができます。

WS3.x/GSX2.5 以降では ECX に返却される値で VMware のプロダクト種別 を判別することができます。現在以下の値が判明しています:

EAX に返却される値の意味はまだわかっていません。 私自身が知っている限りでは常に 6 が返却されます (VMware WS2,3,4,5 および GSX2,3, すべて Windows 版)。
TOP

0Bh - デバイス情報取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX(HI) = デバイス番号 (0 〜 51)
EBX(LO) = データオフセット (0 〜 36)
ECX(HI) = 無視される
ECX(LO) = 000Bh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = 000000001h: 成功 / 00000000h: 失敗
EBX = デバイス情報データ (指定オフセットから 4 バイト、LSB に先頭バイト)
ECX = 変化なし
EDX = 変化なし

詳細
仮想デバイスのデバイス情報データを取得します。 各デバイスの情報データは 40 バイトありますので、完全なデバイス情報データを 取得するにはオフセットを変えながら (0, 4, 8, ...) 本コマンドを 10 回実行する 必要があります。

指定するオフセット値は 4 の倍数である必要はありません (0 から 36 の間の どの値でも指定することができます)。

デバイス情報データ構成:

上記以外のフィールドについては不明です。

指定デバイスが存在しない場合、またオフセットが 36 を超える場合には 本コマンドは失敗します。

TOP

0Ch - デバイス接続・切断

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX(HI) = 8000h (接続) / 0000h (切断)
EBX(LO) = デバイス番号 (0 〜 51)
ECX(HI) = 無視される
ECX(LO) = 000Ch - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = 00000001h: 成功 / 00000000h: 失敗
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
仮想デバイスの接続・切断を行います。

(*) WS5.5/GSX3.2 (もしかしたら以前のバージョンも) では、仮想マシン開始後 コマンド 0Bh を少なくとも一度は実行していないと、本コマンドが失敗することが あります。

TOP

0Dh - GUI オプション設定取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 000Dh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = オプション設定ビットマスク (下記参照)
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
現在の GUI オプション設定をビットマスク値として返却します。 各ビットは以下の GUI オプション項目に対応します:

TOP

0Eh - GUI オプション設定更新

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = オプション設定ビットマスク
ECX(HI) = 無視される
ECX(LO) = 000Eh - コマンド番号
ECX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
GUI オプション設定を更新します。コマンド 0Dh と同じ ビットマスク値を使用します。

このコマンドでビット 0040h (フルスクリーン実行中ビット) を更新しても 効果がありません。フルスクリーンモードに移行するにはビット 0080h をオンに します。 ただし WS3.x/GSX2.5 以前では、この方法でフルスクリーンモードに移行した場合、 元の VMware ウィンドウが不可視となってしまい、ウィンドウモードに戻ることが できなくなります(Windows ホストの場合。Linux 版では違うかもしれません)。

TOP

0Fh - ホスト画面サイズ取得

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX 3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 000Fh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX(HI) = X レゾリューション (ピクセル)
EAX(LO) = Y レゾリューション (ピクセル)
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
ホストの画面サイズを取得します。

TOP

11h - 仮想ハードウェアバージョン取得

サポート状況
WS5.x

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0011h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = 仮想ハードウェアバージョン
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
現在の仮想マシンの仮想ハードウェアバージョンを取得します。
仮想ハードウェアバージョン:

WS3.x/GSX2.x で作成された仮想マシンにも仮想ハードウェアバージョン (1 または 2) がありますが、それらの仮想マシンは仮想ハードウェアのアップグレードを実行 しないと WS5.x で実行することができないため、本コマンドで 1 または 2 が返却 されることはありません。

註: コマンド 11h は WS2.x でも実装されているようですが、全く別の機能として 実装されているらしく、詳細は不明です。

TOP

12h - "OS not found" ダイアログ表示

サポート状況
WS3.x WS4.5(*) WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0012h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = 変化なし
EBX = 変化なし
ECX = 変化なし
EDX = 変化なし

詳細
このコマンドを実行すると、ホスト上で "A bootable CD-ROM disc, floppy diskette, or hard disk was not detected." ダイアログが表示されます (プロダクト、バージョンによって文章は若干異なります)。 ダイアログが閉じられるまで、仮想マシンは完全にフリーズします。

(*) WS4.5/GSX3.2 移行では、このコマンドは仮想プロセッサが特権モードで動作 している場合にのみ使用できます(リアルモード DOS、起動 BIOS など)。 本コマンドは WS4.0 でも実装されていますが、仮想マシン BIOS のコンテキストから のみ使用できるようになっていて、実質上ゲスト OS からは使用不可になっています。 WS3.x/GSX2.5 ではそのような制限なく使用可能です。

TOP

13h - BIOS UUID 取得

サポート状況
WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0013h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = UUID 先頭の 4 バイト (LSB に先頭バイト)
EBX = 2 番目の 4 バイト (同上)
ECX = 3 番目の 4 バイト (同上)
EDX = 4 番目の 4 バイト (同上)

詳細
現在の仮想マシンの BIOS UUID を取得します。 BIOS UUID は設定ファイル内に以下の書式で記述されています:

	uuid.bios = "56 4d 3e 7a 92 ee 4c 46-e8 0d 86 f3 68 a0 cb e7"
本コマンドを使用すると、上の例の UUID は以下のように返却されます:
	EAX: 7a3e4d56
	EBX: 464cee92
	ECX: f3860de8
	EDX: e7cba068
TOP

14h - メモリーサイズ取得 (MB)

サポート状況
WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0014h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = メモリーサイズ (MB)
EBX = ?
ECX = 変化なし
EDX = 変化なし

詳細
仮想マシンに割り当てられたメモリーサイズを取得します。
EBX にも意味ありげな値が返却されますが、その意味はまだわかっていません (私の知る限りでは常に 00001177h )。

TOP

17h - ホストシステム時刻取得 (GMT)

サポート状況
WS2.x WS3.x WS4.0 WS4.5 WS5.x GSX2.5 GSX3.2

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 無視される
ECX(LO) = 0017h - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ホストシステム時刻 (GMT、unix 形式の32ビット値)
EBX = マイクロ秒
ECX = ?
EDX = WS4.0/GSX2.5 以前:ホストタイムゾーン / WS4.5/GSX3.2 以降:0

詳細
ホストのシステム時刻 (GMT) を取得します。
WS4.0/GSX2.5 以前では EDX にホストのタイムゾーン(GMT からのオフセット、 分、32 ビット符号付整数) が返却されます。これを用いてホストのローカル時刻を 算出することができます:

	localtime = EAX - (EDX * 60)

ECX にも意味ありげな値が返却されますが、意味はまだわかっていません。 参考までに、私の WS5.5 環境ではほとんどの場合 000F4240h (1,000,000) ですが、 時折 1,000,000 から 3,000,000 程度の間で変化します。 おそらくシステムクロックの精度に関する値ではないかと考えているのですが。

TOP

1Eh - ゲスト・ホスト間 RPC

サポート状況
WS2.x WS3.x WS4.0(*) WS4.5(*) WS5.x(*) GSX2.5 GSX3.2(*)

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = サブコマンド固有パラメータ
ECX(HI) = RPC サブコマンド
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = サブコマンド 固有返却値
ECX = サブコマンド 固有返却値
EDX = サブコマンド 固有返却値

詳細
ゲスト・ホスト間の RPC 呼び出しを行います。
RPC コマンドを呼び出すには、以下の RPC サブコマンドを使用します:

(*) WS4.0/GSX3.2 以降では、ESI, EDI, EBP レジスタおよび別の I/O ポート を使用した新規の(おそらくより高速な)データ転送メカニズムが導入されています (従来の方法も使用可能です)。
このメカニズムは エンハンスト RPC セクションで 解説しています。
この情報は Nickolai Zeldovich 氏が報告してくれました。
また追加情報を Kanai Ryoji 氏に報告いただきました。

以下の RPC コマンドが確認されています:

TOP

RPC サブコマンド 00h - RPC チャネルオープン

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 49435052h - RPC オープンマジックナンバー ('RPCI')
ECX(HI) = 0000h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX(HI) = RPC チャネル番号
EDX(LO) = 0000h

詳細
RPC チャネルをオープンします。以降の RPC サブコマンドで EDX の上位ワード に返却されるチャネル番号を使用します。

仮想マシンごとに最大 8 チャネルまで (#0 - #7) 同時にオープンすることが できます。それ以上のチャネルをオープンしようとした場合、チャネル番号 0 に 戻って再利用され、エラーは報告されません。

TOP

RPC サブコマンド 01h - RPC コマンド長送信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = コマンド長 (終端 NULL を含まず)
ECX(HI) = 0001h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 00810000h: 成功 / 00000000h: 失敗
EDX = 変化なし

詳細
RPC コマンド長を送信します。 事前に RPC チャネルをオープンしておく必要があります。

TOP

RPC サブコマンド 02h - RPC コマンドデータ送信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = コマンドデータ中の 4 バイト (LSB に先頭バイト)
ECX(HI) = 0002h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 000010000h: 成功 / 00000000h: 失敗
EDX = 変化なし

詳細
RPC コマンドデータ を 4 バイトずつ送信します。 事前に サブコマンド 01h を用いて RPC コマンド長 を送信しておく必要があります。 一例として、RPC コマンド "machine.id.get" を送信する場合、EBX に以下の値を設定 してこのサブコマンドを 4 回実行します: 6863616Dh ("mach"), 2E656E69h ("ine."), 672E6469h ("id.g"), 00007465h ("et\x00\x00")

TOP

RPC サブコマンド 03h - RPC リプライ長受信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 0003h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = リプライ長 (終端 NULL を含まず)
ECX = 00830000h: 成功 / 00000000h: 失敗
EDX(HI) = リプライID
EDX(LO) = 0000h

詳細
RPC リプライ長を受信します。 RPC リプライデータを受信する際に、EDX の上位ワードに返却されるリプライIDを 使用します。

すべての RPC コマンドは最低 2 バイトのリプライデータ ("1 ":成功、"0 ":失敗) を返却します。VMware が認識しないコマンドの場合でも リプライとして "0 Unknown command" が返却されます。

TOP

RPC サブコマンド 04h - RPC リプライデータ受信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = リプライID (サブコマンド 03h で返却されたもの)
ECX(HI) = 0004h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = リプライデータ中の 4 バイト (LSB に先頭バイト)
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX(HI) = 変化なし
EDX(LO) = 0000h

詳細
直前の RPC コマンドのリプライデータを 4 バイトずつ受信します。
リプライデータの最初の 2 バイトは常に RPC コマンドステータスをあらわします: "1 ":成功、"0 ":失敗。
たとえば "machine.id.get" のリプライデータは、成功時は "1 <virtual machine id>"、失敗時は "0 No machine id" となります。

TOP

RPC サブコマンド 05h - RPC リプライ受信完了

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = リプライID (サブコマンド 03h で返却されたもの)
ECX(HI) = 0005h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX = 変化なし

詳細
このコマンドの機能については実はまだよくわかっていません。ただ、正規の VMware Tools が RPC リプライ受信後にこのサブコマンドを実行していること、 パラメータにリプライIDをとること、リプライデータ受信完了前にこのサブコマンド を実行するとエラーとなることなどから、リプライ受信の一環であると判断しました。

TOP

RPC サブコマンド 06h - RPC チャネルクローズ

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 0006h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX = 変化なし

詳細
RPC チャネルをクローズします。

TOP

エンハンスト RPC

サポート状況
WS4.0 WS4.5 WS5.x GSX3.2

詳細
WS4.0/GSX3.2 で導入されたエンハンスト RPC メカニズムは以下の手順で実行します:

TOP

エンハンスト RPC - チャネルオープン

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = C9435052h - エンハンスト RPC オープンマジックナンバー ('RPCI' | 80000000h)
ECX(HI) = 0000h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = 無視される
EDX(LO) = 5658h - ポート番号
ESI = 無視される
EDI = 無視される
EBP = 無視される

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX(HI) = RPC チャネル番号
EDX(LO) = 0000h
ESI = クッキー#1
EDI = クッキー#2
EBP = 変化なし

詳細
RPC チャネルをエンハンスト RPC 用にオープンします。 以降の RPC 操作ではこのコマンドで返却されたチャネル番号とクッキーを使用します。

TOP

エンハンスト RPC - コマンド長送信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = コマンド長 (終端 NULL を含まず)
ECX(HI) = 0001h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号
ESI = クッキー#1
EDI = クッキー#2
EBP = 無視される

返却
EAX = ?
EBX = 変化なし
ECX = 00810000h: 成功 / 00000000h: 失敗
EDX = 変化なし
ESI = 変化なし
EDI = 変化なし
EBP = 変化なし

詳細
RPC コマンド長を送信します。

TOP

エンハンスト RPC - コマンドデータ送信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 00010000h - データ転送マジックナンバー?
ECX = コマンドデータ長 (サブコマンド 02h で送信したデータ長と同じ値)
EDX(HI) = チャネル番号
EDX(LO) = 5659h - ポート番号 (通常のバックドアポートではありません!!)
ESI = データバッファのアドレス
EDI = クッキー#2
EBP = クッキー#1

返却
EAX = 変化なし
EBX = 00010000h: 成功 / 00000000h: 失敗
ECX = 0
EDX = 変化なし
ESI = データバッファ末尾のアドレス
EDI = 変化なし
EBP = 変化なし

詳細
ここがエンハンスト RPC と従来の RPC で大きく違う部分です。 IN インストラクションを繰り返し実行するのではなく、以下の インストラクションを一度実行することで全データを転送することができます:

	/* Intel 表記 */
	cld
	rep outs dx, esi

	/* AT&T 表記 */
	cld
	rep outsb (%esi),(%dx)

コマンド実行後の ECX および ESI の内容の変化は上記 インストラクションの単なる副作用です。

RPC チャネルはエンハンスト RPC 用にオープンされている必要があります。

TOP

エンハンスト RPC - リプライ長受信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 0003h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号
ESI = クッキー#1
EDI = クッキー#2
EBP = 無視される

返却
EAX = ?
EBX = リプライ長 (終端 NULL を含まず)
ECX = 00830000h: 成功 / 00000000h: 失敗
EDX(HI) = リプライID
EDX(LO) = 0000h
ESI = 変化なし
EDI = 変化なし
EBP = 変化なし

詳細
RPC リプライ長を受信します。 従来の RPC と同様に リプライID が EDX の上位ワードに返却されますが、 データ受信には使用されません。

TOP

エンハンスト RPC - リプライデータ受信

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 00010000h - データ転送マジックナンバー?
ECX = リプライデータ長 (サブコマンド 03h で受信したデータ長と同じ値)
EDX(HI) = チャネル番号
EDX(LO) = 5659h - ポート番号 (通常のバックドアポートではありません!!)
ESI = クッキー#1
EDI = データバッファのアドレス
EBP = クッキー#2

返却
EAX = 変化なし
EBX = 00010000h: 成功 / 00000000h: 失敗
ECX = 0
EDX = 変化なし
ESI = 変化なし
EDI = バッファ末尾のアドレス
EBP = 変化なし

詳細
コマンドデータ送信と同様、この機能は以下のインストラクションで実行します:

	/* Intel 表記 */
	cld
	rep ins edi, dx

	/* AT&T 表記 */
	cld
	rep insb (%dx), (%edi)

コマンド実行後の ECX および EDI の内容の変化は上記 インストラクションの単なる副作用です。

RPC チャネルはエンハンスト RPC 用にオープンされている必要があります。

TOP

エンハンスト RPC - リプライ受信完了

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = リプライID (サブコマンド 03h で返却されたもの)
ECX(HI) = 0005h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号
ESI = クッキー#1
EDI = クッキー#2
EBP = 無視される

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX = 変化なし
ESI = 変化なし
EDI = 変化なし
EBP = 変化なし

詳細
RPC サブコマンド 05h の詳細を参照してください。

TOP

エンハンスト RPC - チャネルクローズ

呼び出し
EAX = 564D5868h - マジックナンバー
EBX = 無視される
ECX(HI) = 0006h - サブコマンド番号
ECX(LO) = 001Eh - コマンド番号
EDX(HI) = チャネル番号
EDX(LO) = 5658h - ポート番号
ESI = クッキー#1
EDI = クッキー#2
EBP = 無視される

返却
EAX = ?
EBX = 変化なし
ECX = 00010000h: 成功 / 00000000h: 失敗
EDX = 変化なし
ESI = 変化なし
EDI = 変化なし
EBP = 変化なし

詳細
エンハンスト RPC チャネルをクローズします。

TOP