Saltar al contenido

Virtualbox, cómo forzar una CPU específica al invitado

Después de tanto batallar hemos encontrado la respuesta de esta pregunta que algunos de nuestros usuarios de este sitio han presentado. Si deseas aportar algo puedes dejar tu comentario.

Solución:

Conceptos básicos de VirtualBox y CPUID

Necesita configurar el VBoxInternal/CPUM/HostCPUID extradata de la máquina virtual. Esto hará que VirtualBox informe resultados personalizados para el CPUID instrucción al huésped. Dependiendo del valor del registro EAX, esta instrucción devuelve información sobre el procesador – cosas como proveedor, tipo, familia, paso, marca, tamaño de caché, características (MMX, SSE, SSE2, PAE, HTT), etc. Más resultados destrozas, mayores serán las posibilidades de engañar al invitado.

Puedes usar el vboxmanage setextradata comando para configurar la máquina virtual. Por ejemplo,

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

hará que CPUID regrese 50202952₍₁₆₎ en el registro EBX, cuando se llame con EAX configurado en 80000003₍₁₆₎. (A partir de ahora, los números hexadecimales se escribirán como 0xNN o NNh).

Configuración del proveedor de CPU string

Si EAX es 0 (o 80000000h en AMD), CPUID devuelve el proveedor como ASCII string en los registros EBX, EDX, ECX (observe el pedido). Para una CPU AMD, se ven así:

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

(Tomado de la especificación AMD CPUID, subsección “CPUID Fn0000_0000_E”)

Si concatenas EBX, EDX y ECX, obtendrás AuthenticAMD.

Si tiene Bash y las utilidades tradicionales de Unix, puede configurar fácilmente el proveedor con los siguientes comandos:

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()  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

Configuración de la marca de la CPU string

Si EAX es 80000002h, 80000003h, 80000004h, CPUID devuelve 16 caracteres ASCII de la marca string en los registros EAX, EBX, ECX, EDX, totalizando 3 * 16 = 48 caracteres; los string se termina con un null personaje. Tenga en cuenta que esta función se introdujo con los procesadores Pentium 4. Así es como la marca string puede buscar en un procesador 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"           |
|-----------------|-----------------|------------------|

(Tomado de la Referencia de programación de extensiones del conjunto de instrucciones de la arquitectura Intel, subsección 2.9, "Instrucción CPUID", tabla 2-30. null carácter (valor numérico 0).)

Si junta los resultados, obtendrá Intel(R) Pentium(R) 4 CPU 1500MHz☠.

Si tiene Bash y las utilidades tradicionales de Unix, puede configurar fácilmente la marca con los siguientes comandos:

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 

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

Si tiene un símbolo del sistema de Windows, puede configurar la marca en Intel(R) Core(TM)2 CPU 6600 @ 2.40 GHz1 mediante la ejecución:

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

Computadora: Intel (R) Core (TM) 2 CPU 6600 @ 2.40 GHz

1 los HostCPUID los valores se tomaron del informe de error de VirtualBox # 7865.

Aquí hay un enfoque que permite enmascarar la CPU del host precisamente como una CPU específica en lugar de intentar adivinar la configuración necesaria. Necesitará acceso a una máquina que ejecute VirtualBox en esa CPU host para poder volcar su cpuid registros (probablemente sea mejor elegir una arquitectura que sea razonablemente similar a la de su CPU real como modelo). Si no tiene uno a mano, puede preguntar (he tenido éxito en Reddit, por ejemplo).

  1. Cree un archivo de "modelo" a partir de la CPU que le gustaría emular:

    vboxmanage list hostcpuids > i7_6600U
    
  2. En el host de destino, asegúrese de que la máquina virtual que desea modificar no se esté ejecutando; es posible que desee realizar una copia de seguridad por si acaso.
  3. Ejecute el siguiente script para cargar el archivo de modelo (i7_6600U aquí) en la definición de su VBox VM (my_vm_name aquí):

    #!/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. Eso es todo, ahora puede ejecutar su VM y disfrutar de la CPU enmascarada (nota: solo necesita ejecutar el script anterior una vez).

Si alguna vez necesita revertir la mascarada de la CPU, puede usar vboxmanage modifyvm $vm --cpuidremove $leaf para cada una de las hojas en el ciclo anterior (man vboxmanage es tu amigo).

Esto ha funcionado perfectamente durante un par de meses para mí, enmascarando una CPU Kaby Lake (i7_7500U) como una Skylake (i7_6600U) en un host Ubuntu 17.04 que ejecuta VBox 5.1.22. El enfoque debería funcionar en cualquier sistema operativo host, siempre que pueda crear un equivalente del pequeño script bash anterior para ese sistema operativo.

Si te ha sido útil nuestro artículo, agradeceríamos que lo compartas con más juniors y nos ayudes a difundir este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *