Virtualbox, як змусити конкретного процесора до гостя


14

У мене є гість XP у VirtualBox, Windows 8 хост. Гість показує процесор прозоро таким же, як і хост (i5 2500k). Однак більшість установців не розпізнає цей процесор і не може продовжувати заявляти про непідтримуваний процесор.

Чи є спосіб обдурити гостя думати, що це старий процесор? Якщо я пригадую правильно, VMWare мав функцію маскування процесора, чи є щось подібне у virtualbox?


Яке програмне забезпечення ви встановлюєте, що перевіряє модель процесора?
Darth Android

Подвійний агент управління, Orca та Wix. Це для проекту VB6, який ми намагаємося відродити.
Невідомий

Відповіді:


19

Основи VirtualBox та CPUID

Потрібно встановити VBoxInternal/CPUM/HostCPUIDдодаткові дані віртуальної машини. Це дозволить VirtualBox звітувати власні результати для інструкції CPUID . Залежно від значення реєстру EAX, ця інструкція повертає інформацію про процесор - такі речі, як постачальник, тип, сімейство, ступінчастість, бренд, розмір кеша, функції (MMX, SSE, SSE2, PAE, HTT) тощо. Більше результатів ти мандриш, тим вище шанси обдурити гостя.

Ви можете використовувати vboxmanage setextradataкоманду для налаштування віртуальної машини. Наприклад,

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

зробить CPUID повернення 50202952₍₁₆₎ в регістр EBX, коли його виклик з EAX встановлено на 80000003₍₁₆₎. (Відтепер шістнадцяткові числа записуватимуться як 0xNN або NNh.)

Встановлення рядка постачальника процесора

Якщо EAX дорівнює 0 (або 80000000h на AMD), CPUID повертає постачальника як рядок ASCII в регістри EBX, EDX, ECX (зверніть увагу на порядок). Для процесора AMD вони виглядають так:

| 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" |

(Взято із специфікації CPUID AMD , підрозділ "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 повертає 16 символів ASCII рядка марки в регістри EAX, EBX, ECX, EDX, загальною сумою 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 , підрозділ 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 ГГц

1 У HostCPUIDзначенні було взято з VirtualBox Повідомлення про помилку # 7865 .


Спасибі. Мій VM зламано з VERR_CFGM_INVALID_CHILD_PATH.
Бен Сінклер

1
sed слід використовувати з прапором G:'s/ //g'
Ben Sinclair

1
Яка чудова відповідь! І з появою процесорів Kaby Lake це раптом стало найцікавішим завдяки певній політиці Redmond щодо не підтримувати Windows 7 щодо цих ... Здається, що всього цього не вистачає - це інструкції щодо встановлення "EAX = 1: Інформація про процесори та біти функцій ", оскільки вони не є простими рядками (лише з маркою процесора CPU-Z все ще розпізнає процесор як KL); хтось знає?
sxc731

1
На forums.virtualbox.org/viewtopic.php?f=2&t=77211#p359428 може бути кращий (більш стислий, більш підтримуваний) спосіб встановлення цих значень.
Марк Амерді

@MarkAmery, дякую за посилання. Це добре працює для бренду, але не так добре для постачальника, оскільки постачальник не встановлений у реєстрі EAX, а --cpuidпідкоманда вимагає значення для регістра EAX.
Крістіан Ciupitu

5

Ось підхід, який дозволяє маскувати хост-процесор саме як конкретний процесор, а не намагатися вдруге відгадати необхідні настройки. Вам знадобиться доступ до машини, що працює на цьому віртуальному процесорі VirtualBox, щоб ви могли скинути його cpuidрегістри (можливо, найкраще вибрати архітектуру, яка буде досить схожа на модель вашого фактичного процесора). Якщо у вас немає під рукою, ви можете поцікавитися (наприклад, я мав успіх у Reddit).

  1. Створіть "модельний" файл з центрального процесора, який ви хочете наслідувати:

    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 і насолоджуватися маскарадним процесором (зверніть увагу: вам потрібно запустити вищезазначений сценарій лише один раз).

Якщо вам коли-небудь доведеться відкинути маскарад процесора, ви можете використовувати vboxmanage modifyvm $vm --cpuidremove $leafдля кожного з листів у вищезгаданому циклі ( man vboxmanageце ваш друг).

Це працює бездоганно протягом двох місяців для мене, маскуючи процесор Kaby Lake (i7_7500U) як Skylake (i7_6600U) на хості Ubuntu 17.04 під управлінням VBox 5.1.22. Підхід повинен працювати на будь-якій хостній ОС, за умови, що ви можете створити еквівалент маленького сценарію bash для цієї ОС.


Щодо частини "Налаштування рядка постачальника процесора", у мене є коментар: Ви повинні переконатися, що змініть ім'я постачальника на "AuthenticAMD" на процесорі AMD та "GenuineIntel" на процесорі Intel. Якщо ви використовуєте "GenuineIntel" на процесорі AMD, віртуальна машина зламається дуже ймовірно.
abulhol

Дякую за це! Це спрацювало як шарм на моєму Ryzen 7700K. Я використовував стару материнську плату AMD Socket SF2, щоб отримати CPUID, запустивши Ubuntu LiveCD, встановивши VirtualBox в реальному середовищі та запустивши команду vboxmanage. На стороні хоста я встановив підсистему Windows для Linux, щоб я міг запустити підказку Bash в Windows 10 і запустити сценарій, яким ви поділилися. Тепер я можу підманути свій Windows 7 VM думати, що я працюю на A8-5600K.
njbair

Радий, що це працює і для вас! Я повинен був уточнити, що для цього нічого не потрібен хост Linux; навіть не збираючи "модельний" файл, все, що йому потрібно, це VirtualBox, що працює на цій машині. Сценарій bash може виглядати складно, але все, що він робить, це прочитати рядки з файлу моделі, пропускаючи листя між 0000000bта 00000017(включно) та запускаючи їх по черзі, vboxmanage modifyvm my_vm_name --cpuidset <line>так що це легко зробити вручну, оскільки це одноразово.
sxc731

Нічого не зробив, у мене все одно був встановлений WSL на хост-комп'ютері, і Ubuntu LiveCD був лише тому, що це був найшвидший спосіб відкрутити стару материнську плату AMD.
njbair
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.