Virtualbox วิธีบังคับซีพียูเฉพาะให้กับแขก


16

ฉันมีแขก XP ใน VirtualBox โฮสต์ windows 8 แขกแสดงโปรเซสเซอร์อย่างโปร่งใสเหมือนกับโฮสต์ (i5 2500k) อย่างไรก็ตามโปรแกรมติดตั้งส่วนใหญ่ไม่รู้จักโปรเซสเซอร์นี้และไม่สามารถระบุโปรเซสเซอร์ที่ไม่รองรับได้

มีวิธีหลอกแขกให้คิดว่านี่เป็นตัวประมวลผลเก่าหรือไม่ ถ้าฉันจำได้อย่างถูกต้อง VMWare มีคุณสมบัติการปิดบัง CPU มีสิ่งที่คล้ายกันใน virtualbox หรือไม่?


คุณติดตั้งซอฟต์แวร์ใดที่ตรวจสอบรุ่นของ CPU
Darth Android

ตัวควบคุม Double Agent, Orca และ Wix นี่เป็นโครงการ VB6 ที่เราพยายามฟื้นฟู
IUnknown

คำตอบ:


20

VirtualBox และ CPUID พื้นฐาน

คุณต้องตั้งค่าVBoxInternal/CPUM/HostCPUIDextradata ของเครื่องเสมือน สิ่งนี้จะทำให้ 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)

การตั้งค่าสตริงผู้ขาย CPU

หาก EAX เป็น 0 (หรือ 80000000 ชั่วโมงบน 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" |

(นำมาจากข้อกำหนด CPUID ของ AMDส่วนย่อย "CPUID Fn0000_0000_E")

หากคุณ concatenate 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

การตั้งค่าสตริงแบรนด์ CPU

หาก 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 GHz1โดยเรียกใช้:

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 (R) Core (TM) 2 CPU 6600 @ 2.40 GHz

1HostCPUIDค่าถูกนำมาจาก VirtualBox รายงานข้อผิดพลาด# 7865


ขอบคุณ ทำให้ VM ของฉันเสียด้วย VERR_CFGM_INVALID_CHILD_PATH
เบ็นซินแคลร์

1
sed จะต้องใช้กับธง G:'s/ //g'
เบ็นซินแคลร์

1
ช่างเป็นคำตอบที่ยอดเยี่ยม! และด้วยการถือกำเนิดของซีพียู Kaby Lake สิ่งนี้ก็กลายเป็นสิ่งที่น่าสนใจที่สุดเนื่องจากนโยบายบางอย่างจาก Redmond ที่ไม่รองรับ Windows 7 ในบรรดา ... ดูเหมือนว่าทุกสิ่งที่ขาดหายไปคือคำแนะนำในการตั้งค่า "EAX = 1: ข้อมูลตัวประมวลผลและฟีเจอร์บิต "เนื่องจากไม่ใช่สายอักขระอย่างง่าย (มีเพียงแบรนด์ CPU เท่านั้น CPU-Z ยังคงจดจำ CPU เป็น KL) มีใครรู้บ้าง
sxc731

1
ตามforum.virtualbox.org/viewtopic.php?f=2&t=77211#p359428การตั้งค่าเหล่านี้อาจมีวิธีที่ดีกว่า
Mark Amery

@ MarkAmery ขอบคุณสำหรับลิงค์ มันทำงานได้ดีสำหรับแบรนด์ แต่ไม่ดีสำหรับผู้ขายเพราะผู้ขายไม่ได้ตั้งค่าในการลงทะเบียน EAX และคำ--cpuidสั่งย่อยต้องการค่าสำหรับการลงทะเบียน EAX
Cristian Ciupitu

6

ต่อไปนี้เป็นวิธีการที่ช่วยให้การปลอมแปลง CPU โฮสต์อย่างแม่นยำเป็น CPU ที่เฉพาะเจาะจงแทนที่จะลองเดาการตั้งค่าที่จำเป็นที่สอง คุณจะต้องเข้าถึงเครื่องที่ใช้ VirtualBox บนโฮสต์ CPU นั้นเพื่อให้คุณสามารถถ่ายโอนข้อมูลการcpuidลงทะเบียน (อาจเป็นการดีที่สุดในการเลือกสถาปัตยกรรมที่มีความคล้ายคลึงกับของ CPU จริงของคุณในรูปแบบ) หากคุณไม่มีมือเดียวคุณสามารถถามได้ (ตัวอย่างเช่นฉันเคยประสบความสำเร็จกับ Reddit)

  1. สร้างไฟล์ "model" จาก CPU ที่คุณต้องการจำลอง:

    vboxmanage list hostcpuids > i7_6600U
    
  2. บนโฮสต์เป้าหมายตรวจสอบให้แน่ใจว่า VM ที่คุณต้องการแก้ไขไม่ได้ทำงานอยู่ คุณอาจต้องการสำรองข้อมูลในกรณีที่
  3. รันสคริปต์ต่อไปนี้เพื่อโหลดไฟล์ model ( 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
  4. เพียงเท่านี้คุณก็สามารถเรียกใช้ VM ของคุณและเพลิดเพลินไปกับซีพียูที่ปลอมแปลงได้ (หมายเหตุ: คุณจะต้องรันสคริปต์ด้านบนหนึ่งครั้งเท่านั้น)

หากคุณจำเป็นต้องย้อนกลับมาสควอชของ CPU คุณสามารถใช้vboxmanage modifyvm $vm --cpuidremove $leafใบไม้แต่ละใบในลูปข้างบน ( man vboxmanageเป็นเพื่อนของคุณ)

สิ่งนี้ได้ผลอย่างไม่มีที่ติเป็นเวลาสองสามเดือนสำหรับฉันการปลอมตัว Kaby Lake CPU (i7_7500U) เป็น Skylake one (i7_6600U) บน Ubuntu 17.04 โฮสต์ที่ใช้ VBox 5.1.22 วิธีการนี้ควรใช้กับโฮสต์ระบบปฏิบัติการใด ๆ ก็ได้หากคุณสามารถสร้างสคริปต์สคริปต์ทุบตีเล็ก ๆ น้อย ๆ ข้างต้นสำหรับระบบปฏิบัติการนั้นได้


เกี่ยวกับส่วน "การตั้งค่าสตริงผู้จำหน่าย CPU" ฉันมีความคิดเห็น: คุณต้องตรวจสอบให้แน่ใจว่าได้เปลี่ยนชื่อผู้จัดจำหน่ายเป็น "AuthenticAMD" บน CPU AMD และ "GenuineIntel" บน Intel CPU หากคุณใช้ "GenuineIntel" บน CPU ของ AMD เครื่องเสมือนอาจเสียหายได้มาก
abulhol

ขอบคุณมากสำหรับสิ่งนี้! มันทำงานเหมือนมีเสน่ห์บน Ryzen ของฉัน 7700K ฉันใช้เมนบอร์ด AMD Socket SF2 รุ่นเก่าเพื่อรับ CPUID โดยใช้ Ubuntu LiveCD ติดตั้ง VirtualBox ในสภาพแวดล้อมจริงและเรียกใช้คำสั่ง vboxmanage ในด้านโฮสต์ฉันติดตั้งระบบย่อย Windows สำหรับ Linux เพื่อให้ฉันสามารถเรียกใช้คำสั่ง Bash ใน Windows 10 และเรียกใช้สคริปต์ที่คุณแชร์ ตอนนี้ฉันสามารถหลอกลวง Windows 7 VM ของฉันโดยคิดว่าฉันใช้ A8-5600K
njbair

ดีใจที่มันเหมาะกับคุณเช่นกัน! ฉันควรชี้แจงว่าไม่มีสิ่งนี้ต้องการโฮสต์ Linux; แม้จะไม่ได้รวบรวมไฟล์ "model" สิ่งที่จำเป็นต้องมีก็คือ VirtualBox ที่รันบนเครื่องนั้น สคริปต์ทุบตีอาจดูซับซ้อน แต่สิ่งที่มันทำก็คืออ่านบรรทัดปิดไฟล์รูปแบบการข้ามไประหว่าง0000000bและ00000017(รวม) แล้วเรียกใช้ทีละตัวvboxmanage modifyvm my_vm_name --cpuidset <line>เพื่อให้สามารถทำด้วยมือได้อย่างง่ายดายเนื่องจากเป็นแบบครั้งเดียว
sxc731

ไม่มีเรื่องใหญ่เลยฉันติดตั้ง WSL ไว้ในคอมพิวเตอร์แม่ข่ายแล้วและ Ubuntu LiveCD ก็เป็นเพราะมันเป็นวิธีที่เร็วที่สุดในการหมุนมาเธอร์บอร์ด AMD รุ่นเก่า
njbair
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.