UEFI utility to spoof the brand string of modern AMD processors via Machine State Registers. (Mirrored from https://github.com/InvoxiPlayGames/amd-brand-string-edit )
···11+# amd-brand-string-edit
22+33+UEFI utility to edit the brand string of AMD processors (Family 10h through
44+Family 19h) via the `Core::X86::Msr::ProcNameString` Machine State Registers.
55+66+This is temporary and doesn't modify the CPU in any way, and the change is
77+purely aesthetic. This does not work on Intel, TransMeta, WinChip, or VIA CPUs.
88+99+
1010+1111+
1212+1313+## Usage
1414+1515+Replace the brand string in `src/main.rs` with your desired brand string, then
1616+run `cargo build --release --target x86_64-unknown-uefi`. Run the output .efi
1717+file (`target/x86_64-unknown-uefi/amd-brand-string-edit.efi`) on the computer
1818+via either an EFI shell or with the boot picker and the file located at
1919+`EFI/Boot/bootx64.efi` on removable storage.
···11+#![no_main]
22+#![no_std]
33+44+// CHANGE ME!
55+// new brand string must be EXACTLY 48 characters (pad with spaces)
66+static NEW_BRAND_STRING: &'static str = "Lappy 486 ";
77+// 48 character reference: ------------------------------------------------
88+99+use uefi::print;
1010+use uefi::prelude::*;
1111+use x86::cpuid::CpuId;
1212+use core::arch::asm;
1313+use core::convert::TryInto;
1414+1515+unsafe fn wrmsr_amd(msr: u32, value: u64) {
1616+ let low = value as u32;
1717+ let high = (value >> 32) as u32;
1818+ // wrmsr with the AMD "secret" key - not necessary for these MSRs
1919+ let secret = 0x9c5a203a as u32;
2020+ unsafe {
2121+ asm!("wrmsr", in("ecx") msr, in("eax") low, in("edx") high, in("edi") secret);
2222+ }
2323+}
2424+2525+pub fn brand_string_to_int64(brand_str: &str) -> Option<[u64; 6]> {
2626+ // make sure we have exactly 48 characters for the brand string
2727+ if brand_str.len() != 48 {
2828+ return None
2929+ }
3030+ let str_bytes = brand_str.as_bytes();
3131+ let mut out = [0u64; 6];
3232+ // convert it to an array of 6 LE integers
3333+ // does rust seriously not support for loops
3434+ let mut i = 0;
3535+ while i < 6 {
3636+ let start = i * 8;
3737+ let chunk: [u8; 8] = str_bytes[start..start + 8].try_into().unwrap();
3838+ out[i] = u64::from_le_bytes(chunk);
3939+ i += 1;
4040+ }
4141+ Some(out)
4242+}
4343+4444+#[entry]
4545+fn main() -> Status {
4646+ uefi::helpers::init().unwrap();
4747+ // get the vendor (we only work on AMD)
4848+ let cpu_id = CpuId::new();
4949+ let vendor_name = cpu_id.get_vendor_info().unwrap();
5050+ print!("CPU vendor: {}\n", vendor_name.as_str());
5151+ if vendor_name.as_str() == "AuthenticAMD" {
5252+ // get the current CPU brand string
5353+ let old_brand_string = cpu_id.get_processor_brand_string().unwrap();
5454+ print!("Current brand: \"{}\"\n", old_brand_string.as_str());
5555+ // convert to integers to set in the MSRs
5656+ match brand_string_to_int64(NEW_BRAND_STRING) {
5757+ None => print!("Invalid format for brand string\n\"{}\".\n", NEW_BRAND_STRING),
5858+ Some(ints) => {
5959+ // set the Core::X86::Msr::ProcNameString registers to our new string
6060+ let mut i = 0;
6161+ while i < 6 {
6262+ unsafe {
6363+ wrmsr_amd(0xC0010030 + i, ints[i as usize]);
6464+ }
6565+ i += 1;
6666+ }
6767+ // verify that the string has actually changed
6868+ let verify_brand_string = cpu_id.get_processor_brand_string().unwrap();
6969+ print!("New brand: \"{}\"\n", verify_brand_string.as_str());
7070+ }
7171+ }
7272+ } else {
7373+ print!("This program only supports AuthenticAMD.\n");
7474+ }
7575+ // stall for 7 seconds to let you read the console output
7676+ boot::stall(7_000_000);
7777+ Status::SUCCESS
7878+}