Virtualbox, jak wymusić gościa określony procesor

14

Mam gościa XP w VirtualBox, hoście Windows 8. Gość pokazuje procesor transparentnie tak samo jak host (i5 2500k). Jednak większość instalatorów nie rozpoznaje tych procesorów i nie informuje o nieobsługiwanym procesorze.

Czy istnieje sposób, aby oszukać gościa, że ​​jest to stary procesor? Jeśli poprawnie pamiętam, VMWare ma funkcję maskowania procesora, czy jest coś podobnego w virtualbox?

Nieznany
źródło
Jakie instalujesz oprogramowanie, które sprawdza model procesora?
Darth Android
Kontrole Double Agent, Orca i Wix. Dotyczy to projektu VB6, który próbujemy ożywić.
Nieznany

Odpowiedzi:

19

Podstawy VirtualBox i CPUID

Musisz ustawić VBoxInternal/CPUM/HostCPUIDekstradane maszyny wirtualnej. Spowoduje to, że VirtualBox będzie raportował niestandardowe wyniki dla instrukcji CPUID dla gościa. W zależności od wartości rejestru EAX instrukcja ta zwraca informacje o procesorze - takie jak dostawca, typ, rodzina, stopień, marka, rozmiar pamięci podręcznej, funkcje (MMX, SSE, SSE2, PAE, HTT) itp. Więcej wyników ty się przeklinasz, tym większe są szanse na oszukanie gościa.

Możesz użyć vboxmanage setextradatapolecenia, aby skonfigurować maszynę wirtualną. Na przykład,

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

spowoduje, że CPUID zwróci 50202952₍₁₆₎ w rejestrze EBX, gdy zostanie wywołany z EAX ustawionym na 80000003₍₁₆₎. (Od tej chwili liczby szesnastkowe będą zapisywane jako 0xNN lub NNh.)

Ustawianie ciągu dostawcy procesora

Jeśli EAX ma wartość 0 (lub 80000000h na AMD), CPUID zwraca dostawcę jako ciąg ASCII w rejestrach EBX, EDX, ECX (zwróć uwagę na kolejność). W przypadku procesora AMD wyglądają następująco:

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

(Zaczerpnięte ze specyfikacji AMD CPUID , podsekcja „CPUID Fn0000_0000_E”)

Jeśli połączysz EBX, EDX i ECX, otrzymasz AuthenticAMD.

Jeśli masz Bash i tradycyjne narzędzia uniksowe, możesz łatwo ustawić producenta za pomocą następujących poleceń:

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

Ustawianie ciągu marki procesora

Jeśli EAX to 80000002h, 80000003h, 80000004h, CPUID zwraca 16 znaków ASCII łańcucha marki w rejestrach EAX, EBX, ECX, EDX, łącznie 3 * 16 = 48 znaków; ciąg jest zakończony znakiem zerowym . Zauważ, że ta funkcja została wprowadzona w procesorach Pentium 4. Oto jak ciąg marki może wyglądać na procesorze 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"           |
|-----------------|-----------------|------------------|

(Zaczerpnięte z Rozszerzenia zestawu instrukcji architektury Intel Programowanie , podrozdział 2.9, „Instrukcja CPUID”, tabela 2-30. ☠ jest znakiem pustym (wartość liczbowa 0).)

Jeśli złożysz wyniki razem, otrzymasz Intel(R) Pentium(R) 4 CPU 1500MHz☠.

Jeśli masz Bash i tradycyjne narzędzia uniksowe, możesz łatwo ustawić markę za pomocą następujących poleceń:

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

Jeśli masz wiersz polecenia systemu Windows, możesz ustawić markę na Intel(R) Core(TM)2 CPU 6600 @ 2.40 GHz1 , uruchamiając:

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

Komputer: Intel (R) Core (TM) 2 CPU 6600 @ 2,40 GHz

1 Te HostCPUIDwartości zostały zaczerpnięte z raportu VirtualBox bug # 7865 .

Cristian Ciupitu
źródło
Dzięki. Zepsuła się moja maszyna wirtualna z VERR_CFGM_INVALID_CHILD_PATH.
Ben Sinclair
1
sed musi być używany z flagą G:'s/ //g'
Ben Sinclair
1
Co za świetna odpowiedź! Wraz z pojawieniem się procesorów Kaby Lake nagle stało się to najbardziej interesujące ze względu na pewną politykę Redmond, by nie obsługiwać Windows 7 na tych ... Wydaje się, że brakuje tylko instrukcji, jak ustawić „EAX = 1: Informacje o procesorze i bity funkcji ”, ponieważ nie są to proste ciągi znaków (przy samej marce procesora CPU-Z nadal rozpoznaje procesor jako KL); ktokolwiek wie?
sxc731
1
Na forums.virtualbox.org/viewtopic.php?f=2&t=77211#p359428 może istnieć lepszy (bardziej zwięzły, obsługiwany) sposób ustawiania tych wartości.
Mark Amery
@MarkAmery, dzięki za link. Działa dobrze dla marki, ale nie tak dobrze dla dostawcy, ponieważ nie ma go w rejestrze EAX, a --cpuidpodkomenda wymaga wartości dla rejestru EAX.
Cristian Ciupitu,
5

Oto podejście, które pozwala maskaradować procesor hosta dokładnie jako konkretny procesor zamiast próbować odgadnąć niezbędne ustawienia. Będziesz potrzebował dostępu do maszyny z VirtualBox na CPU hosta, abyś mógł zrzucić jego cpuidrejestry (prawdopodobnie najlepiej wybrać architekturę, która jest dość podobna do architektury twojego CPU jako modelu). Jeśli nie masz ręki, możesz zapytać (na przykład odnoszę sukcesy na Reddicie).

  1. Utwórz plik „modelowy” z procesora, który chcesz emulować:

    vboxmanage list hostcpuids > i7_6600U
    
  2. Na hoście docelowym upewnij się, że maszyna wirtualna, którą chcesz zmodyfikować, nie działa; na wszelki wypadek możesz zrobić kopię zapasową.
  3. Uruchom następujący skrypt, aby załadować plik modelu ( i7_6600Ututaj) do definicji maszyny wirtualnej VBox ( my_vm_nametutaj):

    #!/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. To wszystko, możesz teraz uruchomić swoją maszynę wirtualną i cieszyć się maskaradowym procesorem (uwaga: powyższy skrypt wystarczy uruchomić tylko raz).

Jeśli kiedykolwiek będziesz musiał cofnąć maskaradę procesora, możesz użyć vboxmanage modifyvm $vm --cpuidremove $leafdla każdego z liści w powyższej pętli ( man vboxmanagejest twoim przyjacielem).

Działa to dla mnie bezbłędnie przez kilka miesięcy, udając procesor Kaby Lake (i7_7500U) jako Skylake (i7_6600U) na hoście Ubuntu 17.04 z VBox 5.1.22. Podejście to powinno działać na każdym systemie operacyjnym hosta, pod warunkiem, że można utworzyć odpowiednik powyższego skryptu bash dla tego systemu operacyjnego.

sxc731
źródło
Jeśli chodzi o część „Ustawianie ciągu dostawcy procesora”, mam komentarz: Musisz koniecznie zmienić nazwę dostawcy na „AuthenticAMD” na procesorze AMD i „GenuineIntel” na procesorze Intel. Jeśli użyjesz „GenuineIntel” na procesorze AMD, maszyna wirtualna najprawdopodobniej się zepsuje.
abulhol
Wielkie dzięki za to! Działa jak urok na moim Ryzen 7700K. Użyłem starej płyty głównej AMD Socket SF2, aby uzyskać CPUID, uruchamiając Ubuntu LiveCD, instalując VirtualBox w środowisku na żywo i uruchamiając polecenie vboxmanage. Po stronie hosta zainstalowałem Podsystem Windows dla systemu Linux, aby móc uruchomić monit Bash w systemie Windows 10 i uruchomić udostępniony skrypt. Teraz mogę oszukać moją maszynę wirtualną z systemem Windows 7, aby pomyślała, że ​​korzystam z A8-5600K.
njbair
Cieszę się, że to działa również dla Ciebie! Powinienem był wyjaśnić, że nic z tego nie wymaga hosta Linuksa; nawet nie zbierając pliku „model”, wystarczy VirtualBox działający na tym komputerze. Skrypt bash może wydawać się skomplikowany, ale wszystko, co robi, to odczytuje wiersze z pliku modelu, pomija liście między 0000000bi 00000017(włącznie) i uruchamia je jeden po drugim, dzięki vboxmanage modifyvm my_vm_name --cpuidset <line>czemu można to łatwo zrobić ręcznie, ponieważ jest to jednorazowe.
sxc731,
Nie, biggie, i tak miałem WSL zainstalowany na komputerze-hoście, a Ubuntu LiveCD było po prostu dlatego, że był to najszybszy sposób na podkręcenie starej płyty głównej AMD.
njbair