Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a XP guest in VirtualBox, windows 8 host. The guest shows the processor transparently same as the host (i5 2500k). However most of the installers don't recognize this processors and fail to continue stating non-supported processor.

Is there a way to fool the guest into thinking this is old processor? If I recalll correctly VMWare had a CPU masking feature, is there something similar in virtualbox?

share|improve this question
What software are you installing that checks the CPU model? – Darth Android Jul 29 '13 at 21:27
Double Agent controls, Orca and Wix. This is for a VB6 project which we are trying to revive. – IUnknown Jul 30 '13 at 22:48

VirtualBox and CPUID basics

You need to set the VBoxInternal/CPUM/HostCPUID extradata of the virtual machine. This will make VirtualBox report custom results for the CPUID instruction to the guest. Depending on the value of the EAX register, this instruction returns information about the processor - things like vendor, type, family, stepping, brand, cache size, features (MMX, SSE, SSE2, PAE, HTT), etc. The more results you mangle, the higher the chances to fool the guest.

You can use the vboxmanage setextradata command to configure the virtual machine. For example,

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

will make CPUID return 50202952₍₁₆₎ in the EBX register, when called with EAX set to 80000003₍₁₆₎. (From now on, hexadecimal numbers will be written as 0xNN or NNh.)

Setting the CPU vendor string

If EAX is 0 (or 80000000h on AMD), CPUID returns the vendor as an ASCII string in registers EBX, EDX, ECX (notice the order). For an AMD CPU, they look like this:

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

(Taken from AMD CPUID Specification, subsection "CPUID Fn0000_0000_E")

If you concatenate EBX, EDX and ECX, you'll get AuthenticAMD.

If you have Bash and the traditional Unix utilities, you can easily set the vendor with the following commands:

vm='WinXP'  # UUID works as well
# The vendor string needs to have 12 characters!
if [ ${#vendor} -ne 12 ]; then
    exit 1
registers=(ebx edx ecx)
for (( i=0; i<${#vendor}; i+=4 )); do
    value=`echo -n "${vendor:$i:4}" | od -A n -t x4 | sed 's/ //'`
    vboxmanage setextradata "$vm" \
               VBoxInternal/CPUM/HostCPUID/00000000/${register} 0x${value}
    vboxmanage setextradata "$vm" \
               VBoxInternal/CPUM/HostCPUID/80000000/${register} 0x${value}

Setting the CPU brand string

If EAX is 80000002h, 80000003h, 80000004h, CPUID returns 16 ASCII characters of the brand string in registers EAX, EBX, ECX, EDX, totaling 3 * 16 = 48 characters; the string is terminated with a null character. Note that this feature was introduced with Pentium 4 processors. This is how the brand string can look on a Pentium 4 processor:

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

(Taken from Intel Architecture Instruction Set Extensions Programming Reference, subsection 2.9, "CPUID Instruction", table 2-30. ☠ is the null character (numerical value 0).)

If you put the results together, you'll get Intel(R) Pentium(R) 4 CPU 1500MHz☠.

If you have Bash and the traditional Unix utilities, you can easily set the brand with the following commands:

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
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 ))]}
    value=`echo -n "${brand:$i:4}" | od -A n -t x4 | sed 's/ //'`
    vboxmanage setextradata "$vm" VBoxInternal/CPUM/HostCPUID/${eax}/${register} 0x${value}

If you have a Windows command prompt, you can set the brand to Intel(R) Core(TM)2 CPU 6600 @ 2.40 GHz1 by running:

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

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

1 The HostCPUID values were taken from VirtualBox bug report #7865.

share|improve this answer

Christian's instructions are very helpful, but there is a minor glitch in the "brand string" bash script. The order must be:

registers=(eax ebx ecx edx)

otherwise the string will be all messed up.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .