Virtualbox、特定のCPUをゲストに強制する方法


13

VirtualBoxのWindows 8ホストにXPゲストがいます。ゲストは、ホストと透過的に同じプロセッサを表示します(i5 2500k)。ただし、ほとんどのインストーラーはこのプロセッサーを認識せず、サポートされていないプロセッサーの表示を続行できません。

ゲストをだましてこれを古いプロセッサだと思わせる方法はありますか?VMWareにCPUマスキング機能があったことを正しく思い出せば、virtualboxに似たようなものがありますか?


CPUモデルをチェックするソフトウェアをインストールしていますか?
ダースアンドロイド

ダブルエージェントコントロール、OrcaおよびWix。これは、私たちが復活させようとしているVB6プロジェクト用です。
IUnknown

回答:


18

VirtualBoxとCPUIDの基本

VBoxInternal/CPUM/HostCPUID仮想マシンの追加データを設定する必要があります。これにより、VirtualBoxはCPUID命令のカスタム結果をゲストに報告します。EAXレジスタの値に応じて、この命令はプロセッサに関する情報を返します-ベンダー、タイプ、ファミリ、ステッピング、ブランド、キャッシュサイズ、機能(MMX、SSE、SSE2、PAE、HTT)などのようなもの。あなたがマングルすると、ゲストをだます可能性が高くなります。

このvboxmanage setextradataコマンドを使用して、仮想マシンを構成できます。例えば、

vboxmanage setextradata WinXP VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x50202952

EAXを80000003に設定して呼び出した場合、CPUIDはEBXレジスターに50202952を返します。(今後、16進数は0xNNまたはNNhとして書き込まれます。)

CPUベンダーストリングの設定

EAXが0(またはAMDでは80000000h)の場合、CPUIDはベンダーをレジスタEBX、EDX、ECXのASCII文字列として返します(順序に注意してください)。AMD CPUの場合、次のようになります。

| Register | Value      | Description                    |
|----------|------------|--------------------------------|
| EBX      | 6874_7541h | The ASCII characters "h t u A" |
| ECX      | 444D_4163h | The ASCII characters "D M A c" |
| EDX      | 6974_6E65h | The ASCII characters "i t n e" |

AMD CPUID仕様のサブセクション「CPUID Fn0000_0000_E」から取得)

EBX、EDX、ECXを連結すると、が得られAuthenticAMDます。

Bashと従来のUnixユーティリティがある場合は、次のコマンドで簡単にベンダーを設定できます。

vm='WinXP'  # UUID works as well
# The vendor string needs to have 12 characters!
vendor='AuthenticAMD'
if [ ${#vendor} -ne 12 ]; then
    exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }

registers=(ebx edx ecx)
for (( i=0; i<${#vendor}; i+=4 )); do
    register=${registers[$(($i/4))]}
    value=`echo -n "${vendor:$i:4}" | ascii2hex`
    # set value to an empty string to reset the CPUID, i.e.
    # value=""
    for eax in 00000000 80000000; do
        key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
        vboxmanage setextradata "$vm" $key $value
    done
done

CPUブランドストリングの設定

EAXが80000002h、80000003h、80000004hの場合、CPUIDはレジスタEAX、EBX、ECX、EDXにブランド文字列の16個のASCII文字を返し、合計3 * 16 = 48文字です。文字列はヌル文字で終了します。この機能はPentium 4プロセッサで導入されたことに注意してください。これは、ブランド文字列がPentium 4プロセッサでどのように見えるかです。

| EAX Input Value | Return Values   | ASCII Equivalent |
|-----------------|-----------------|------------------|
| 80000002h       | EAX = 20202020h | "    "           |
|                 | EBX = 20202020h | "    "           |
|                 | ECX = 20202020h | "    "           |
|                 | EDX = 6E492020h | "nI  "           |
|-----------------|-----------------|------------------|
| 80000003h       | EAX = 286C6574h | "(let"           |
|                 | EBX = 50202952h | "P )R"           |
|                 | ECX = 69746E65h | "itne"           |
|                 | EDX = 52286D75h | "R(mu"           |
|-----------------|-----------------|------------------|
| 80000004h       | EAX = 20342029h | " 4 )"           |
|                 | EBX = 20555043h | " UPC"           |
|                 | ECX = 30303531h | "0051"           |
|                 | EDX = 007A484Dh | "☠zHM"           |
|-----------------|-----------------|------------------|

Intel Architecture Instruction Set Extensions Programming Referenceのサブセクション2.9「CPUID命令」、表2-30から引用。.はヌル文字(数値0)です。)

結果をまとめると、が得られ Intel(R) Pentium(R) 4 CPU 1500MHz☠ます。

Bashと従来のUnixユーティリティがある場合は、次のコマンドでブランドを簡単に設定できます。

vm='WinXP'  # UUID works as well
# The brand string needs to have 47 characters!
# The null terminator is added automatically
brand='              Intel(R) Pentium(R) 4 CPU 1500MHz'
if [ ${#brand} -ne 47 ]; then
    exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }

eax_values=(80000002 80000003 80000004)
registers=(edx ecx ebx eax)
for (( i=0; i<${#brand}; i+=4 )); do
    eax=${eax_values[$((${i} / 4 / 4))]}
    register=${registers[$((${i} / 4 % 4 ))]}
    key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
    value=`echo -n "${brand:$i:4}" | ascii2hex`
    # set value to an empty string to reset the CPUID, i.e.
    # value=""
    vboxmanage setextradata "$vm" $key $value
done

Windowsコマンドプロンプトがある場合は、次を実行してブランドをIntel(R) Core(TM)2 CPU 6600 @ 2.40 GHz1に設定できます。

set vm=your-vm-name-or-uuid
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/eax 0x65746e49
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ebx 0x2952286c
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ecx 0x726f4320
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/edx 0x4d542865
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/eax 0x43203229
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x20205550
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ecx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/edx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/eax 0x30303636
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ebx 0x20402020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ecx 0x30342e32
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/edx 0x007a4847

コンピューター:Intel(R)Core(TM)2 CPU 6600 @ 2.40 GHz

1HostCPUIDの値は、VirtualBoxのバグ報告から採取した#7865


ありがとう。VERR_CFGM_INVALID_CHILD_PATHでVMが壊れました。
ベンシンクレア

1
:Gフラグと一緒に使用しなければならないのsed's/ //g'
ベン・シンクレア

1
なんて素晴らしい答えでしょう!そして、Kaby Lake CPUの出現により、レドモンドから特定のポリシーがWindows 7をサポートしないため、これが突然最も興味深いものになりました...欠落しているのは、「EAX = 1:プロセッサ情報と機能ビット」は単純な文字列ではないため(CPUブランドだけでも、CPU-ZはCPUをKLとして認識します)。誰もが知っていますか?
sxc731

1
パーforums.virtualbox.org/viewtopic.php?f=2&t=77211#p359428、これらの値を設定するより良い(より多くのサポート、より簡潔)の方法があるかもしれません。
マークアメリー

@MarkAmery、リンクをありがとう。ブランドにとってはうまく機能しますが、ベンダーはEAXレジスタに設定されておらず、--cpuidサブコマンドにはEAXレジスタの値が必要なので、ベンダーにとってはそれほどうまくいきません。
クリスチャン・シウピトゥ

5

これは、必要な設定を推測するのではなく、ホストCPUを特定のCPUとして正確にマスカレードできるアプローチです。そのホストCPUでVirtualBoxを実行しているマシンにアクセスして、そのcpuidレジスタをダンプできるようにする必要があります(モデルとして実際のCPUのアーキテクチャにかなり近いアーキテクチャを選択することをお勧めします)。手元に持っていない場合は、尋ねることができます(たとえば、Redditで成功しました)。

  1. エミュレートするCPUから「モデル」ファイルを作成します。

    vboxmanage list hostcpuids > i7_6600U
    
  2. ターゲットホストで、変更するVMが実行されていないことを確認します。万が一の場合に備えてバックアップを取ることをお勧めします。
  3. 次のスクリプトを実行して、モデルファイル(i7_6600Uここ)をVBox VMの定義(ここ)にロードしますmy_vm_name

    #!/bin/bash
    vm=my_vm_name
    model_file=i7_6600U
    
    egrep -e '^[[:digit:]abcdef]{8} ' $model_file |
    while read -r line; do
        leaf="0x`echo $line | cut -f1 -d' '`"
        # VBox doesn't like applying leaves between the below boundaries so skip those:
        if [[ $leaf -lt 0x0b || $leaf -gt 0x17 ]]; then
            echo "Applying: $line"
            vboxmanage modifyvm $vm --cpuidset $line
        fi
    done
  4. これで、VMを実行して、マスカレードCPUを楽しむことができます(注:上記のスクリプトを実行する必要があるのは1回だけです)。

CPUマスカレードをロールバックする必要がある場合vboxmanage modifyvm $vm --cpuidremove $leafは、上記のループ内の各リーフに使用できます(man vboxmanage友人です)。

これは、私にとっては数か月間、VBox 5.1.22を実行しているUbuntu 17.04ホストでKaby Lake CPU(i7_7500U)をSkylakeのもの(i7_6600U)に見せかけながら、完璧に機能しています。上記の小さなbashスクリプトと同等のOSを作成できる場合、このアプローチはどのホストOSでも動作するはずです。


「CPUベンダー文字列の設定」の部分に関して、コメントがあります。AMDCPUではベンダー名を「AuthenticAMD」に、Intel CPUでは「GenuineIntel」に変更する必要があります。AMD CPUで「GenuineIntel」を使用すると、仮想マシンが壊れる可能性が非常に高くなります。
-abulhol

これをどうもありがとう!それは私のRyzen 7700Kの魅力のように働きました。Ubuntu LiveCDを実行し、ライブ環境にVirtualBoxをインストールし、vboxmanageコマンドを実行して、古いAMD Socket SF2マザーボードを使用してCPUIDを取得しました。ホスト側では、Linux用のWindowsサブシステムをインストールしたため、Windows 10でBashプロンプトを実行し、共有したスクリプトを実行できました。これで、Windows 7 VMをだまして、A8-5600Kを実行していると思わせることができます。
njbair

これがあなたにも役立つことを嬉しく思います!Linuxホストを必要としないことを明確にすべきでした。「モデル」ファイルを収集しなくても、必要なのはそのマシンで実行されているVirtualBoxだけです。bashスクリプトが複雑に見えるかもしれないが、それがないすべては、モデルファイルをオフラインに読み込まれ、間葉スキップ0000000bし、00000017(包括的に)とを1つずつ、それらを実行しているvboxmanage modifyvm my_vm_name --cpuidset <line>、それは一回限りだと、このように手で簡単に行うことができます。
sxc731

とにかく、ホストコンピューターにWSLをインストールしました。UbuntuLiveCDは、古いAMDマザーボードを起動する最も速い方法だからです。
-njbair
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.