Answers:
您需要设置VBoxInternal/CPUM/HostCPUID
虚拟机的额外数据。这将使VirtualBox 向来宾报告CPUID指令的自定义结果。根据EAX寄存器的值,此指令返回有关处理器的信息-如供应商,类型,系列,步进,品牌,缓存大小,功能(MMX,SSE,SSE2,PAE,HTT)等信息。更多结果捣蛋,欺骗客人的机会就越高。
您可以使用该vboxmanage setextradata
命令配置虚拟机。例如,
vboxmanage setextradata WinXP VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x50202952
当EAX设置为80000003₍₁₆₎时,将使EBX寄存器中的CPUID返回50202952₍₁₆₎。(从现在开始,十六进制数字将被写为0xNN或NNh。)
如果EAX为0(在AMD上为80000000h),则CPUID将供应商作为ASCII字符串返回给寄存器EBX,EDX,ECX(请注意顺序)。对于AMD CPU,它们如下所示:
| 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将在寄存器EAX,EBX,ECX,EDX中返回品牌字符串的16个ASCII字符,总计3 * 16 = 48个字符; 字符串以空字符结尾。请注意,此功能是奔腾4处理器引入的。这是品牌字符串在奔腾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" |
|-----------------|-----------------|------------------|
(摘自《英特尔体系结构指令集扩展程序设计参考》的小节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
1这些HostCPUID
值取自VirtualBox错误报告#7865。
's/ //g'
--cpuid
子命令需要EAX寄存器的值。
这是一种允许将主机CPU精确地伪装成特定CPU的方法,而不是试图猜测必要的设置。您将需要访问在该主机CPU上运行VirtualBox的计算机,以便转储其cpuid
寄存器(最好选择与实际CPU作为模型的体系结构相当的体系结构)。如果您没有人,可以询问一下(例如,我在Reddit上取得了成功)。
从要模拟的CPU创建一个“模型”文件:
vboxmanage list hostcpuids > i7_6600U
运行以下脚本以将模型文件(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
就是这样,您现在可以运行虚拟机并享受伪装的CPU(请注意:您只需运行一次以上脚本)。
如果您需要回滚CPU伪装,则可以vboxmanage modifyvm $vm --cpuidremove $leaf
在上面的循环中使用每个叶子(man vboxmanage
是您的朋友)。
这对我来说已经完美地工作了几个月,在运行VBox 5.1.22的Ubuntu 17.04主机上伪装了Kaby Lake CPU(i7_7500U)作为Skylake处理器(i7_6600U)。只要您可以为该操作系统创建与上面的little bash脚本等效的方法,该方法就可以在任何主机OS上使用。
0000000b
和00000017
(包括)之间的叶子,并逐个运行它们,vboxmanage modifyvm my_vm_name --cpuidset <line>
因此这很容易手动完成,因为它是一次性的。