13

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

Есть ли способ обмануть гостя, думая, что это старый процессор? Если я правильно помню, у VMWare была функция маскировки процессора, есть ли что-то подобное в virtualbox?

2 ответа2

18

Основы VirtualBox и CPUID

Вам необходимо установить дополнительные данные VBoxInternal/CPUM/HostCPUID 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" |

(Взято из спецификации 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

Установка строки марки процессора

Если 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 GHz 1 , запустив:

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® Core ™ 2, процессор 6600 @ 2,40 ГГц

1 Значения HostCPUID были взяты из сообщения об ошибке VirtualBox # 7865.

5

Вот подход, который позволяет маскировать центральный процессор именно под конкретный процессор, а не пытаться угадать необходимые настройки. Вам понадобится доступ к машине, на которой установлен VirtualBox на этом центральном процессоре, чтобы вы могли сбросить его регистры cpuid (вероятно, лучше выбрать архитектуру, которая достаточно похожа на архитектуру вашего фактического процессора в качестве модели). Если у вас нет руки, вы можете поспрашивать (например, у меня был успех на Reddit).

  1. Создайте файл модели из процессора, который вы хотите эмулировать:

    vboxmanage list hostcpuids > i7_6600U
    
  2. На целевом хосте убедитесь, что виртуальная машина, которую вы хотите изменить, не работает; Вы можете сделать резервную копию на всякий случай.
  3. Запустите следующий сценарий, чтобы загрузить файл модели (здесь i7_6600U ) в определение вашей виртуальной машины VBox (здесь 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. Вот и все, теперь вы можете запустить свою виртуальную машину и наслаждаться маскарадным процессором (примечание: вам нужно только запустить вышеупомянутый скрипт один раз).

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .