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 )
at master 78 lines 2.8 kB view raw
1#![no_main] 2#![no_std] 3 4// CHANGE ME! 5// new brand string must be EXACTLY 48 characters (pad with spaces) 6static NEW_BRAND_STRING: &'static str = "Lappy 486 "; 7// 48 character reference: ------------------------------------------------ 8 9use uefi::print; 10use uefi::prelude::*; 11use x86::cpuid::CpuId; 12use core::arch::asm; 13use core::convert::TryInto; 14 15unsafe fn wrmsr_amd(msr: u32, value: u64) { 16 let low = value as u32; 17 let high = (value >> 32) as u32; 18 // wrmsr with the AMD "secret" key - not necessary for these MSRs 19 let secret = 0x9c5a203a as u32; 20 unsafe { 21 asm!("wrmsr", in("ecx") msr, in("eax") low, in("edx") high, in("edi") secret); 22 } 23} 24 25pub fn brand_string_to_int64(brand_str: &str) -> Option<[u64; 6]> { 26 // make sure we have exactly 48 characters for the brand string 27 if brand_str.len() != 48 { 28 return None 29 } 30 let str_bytes = brand_str.as_bytes(); 31 let mut out = [0u64; 6]; 32 // convert it to an array of 6 LE integers 33 // does rust seriously not support for loops 34 let mut i = 0; 35 while i < 6 { 36 let start = i * 8; 37 let chunk: [u8; 8] = str_bytes[start..start + 8].try_into().unwrap(); 38 out[i] = u64::from_le_bytes(chunk); 39 i += 1; 40 } 41 Some(out) 42} 43 44#[entry] 45fn main() -> Status { 46 uefi::helpers::init().unwrap(); 47 // get the vendor (we only work on AMD) 48 let cpu_id = CpuId::new(); 49 let vendor_name = cpu_id.get_vendor_info().unwrap(); 50 print!("CPU vendor: {}\n", vendor_name.as_str()); 51 if vendor_name.as_str() == "AuthenticAMD" { 52 // get the current CPU brand string 53 let old_brand_string = cpu_id.get_processor_brand_string().unwrap(); 54 print!("Current brand: \"{}\"\n", old_brand_string.as_str()); 55 // convert to integers to set in the MSRs 56 match brand_string_to_int64(NEW_BRAND_STRING) { 57 None => print!("Invalid format for brand string\n\"{}\".\n", NEW_BRAND_STRING), 58 Some(ints) => { 59 // set the Core::X86::Msr::ProcNameString registers to our new string 60 let mut i = 0; 61 while i < 6 { 62 unsafe { 63 wrmsr_amd(0xC0010030 + i, ints[i as usize]); 64 } 65 i += 1; 66 } 67 // verify that the string has actually changed 68 let verify_brand_string = cpu_id.get_processor_brand_string().unwrap(); 69 print!("New brand: \"{}\"\n", verify_brand_string.as_str()); 70 } 71 } 72 } else { 73 print!("This program only supports AuthenticAMD.\n"); 74 } 75 // stall for 7 seconds to let you read the console output 76 boot::stall(7_000_000); 77 Status::SUCCESS 78}