
पहला विश्लेषण ढांचा CPU माइक्रोकोड के लिए
Custom Processing Unit पहला गतिशील विश्लेषण ढांचा (dynamic analysis framework) है जो सॉफ़्टवेयर स्तर पर CPU माइक्रोकोड को hook, patch और trace करने में सक्षम है।
यह Intel CPUs में मौजूद अप्रलेखित निर्देशों का लाभ उठाकर काम करता है, जो CRBUS तक पहुँच की अनुमति देते हैं। हमारे माइक्रोकोड डीकंपाइलर का उपयोग करके हमने यह पता लगाया कि CPU CRBUS का उपयोग कैसे करता है, और अंतःक्रियाओं की नकल करके हमें CPU का पूर्ण नियंत्रण प्राप्त होता है।
स्थैतिक विश्लेषण ढांचे को उपवृक्ष (subtree) के रूप में इस फ़ोल्डर में, या https://github.com/pietroborrello/ghidra-atom-microcode पर पाएँ।
इस कार्य का वर्णन करने वाली हमारी स्लाइड्स यहाँ देखें।
नोट: Custom Processing Unit के लिए Red-Unlocked CPU आवश्यक है: वर्तमान में, केवल Goldmont CPUs (GLM) के पास सार्वजनिक Red Unlock है। हमने CPU stepping 0x9 और 0xa (cpuid 0x000506C9 और 0x000506CA) के साथ Gigabyte GB-BPCE-3350C का परीक्षण किया।
Custom Processing Unit एक UEFI एप्लिकेशन और कुछ लाइब्रेरियों से मिलकर बना है। UEFI एप्लिकेशन GLM CPU के साथ अंतःक्रिया करता है, जबकि लाइब्रेरियाँ माइक्रोकोड को UEFI एप्लिकेशन में संकलित करने और उसके आउटपुट का विश्लेषण करने के लिए विभिन्न सहायक उपकरण प्रदान करती हैं।
GNU_EFI_DIR=<path_to_gnu_efi> make
यह स्रोत माइक्रोकोड फ़ाइलों और UEFI एप्लिकेशन को cpu.efi में बनाएगा।
cpu.efi को USB कुंजी के \EFI\ फ़ोल्डर में कॉपी करें, इसे GLM में लगाएँ और EFI शेल में बूट करें।
EFI शेल में map -r चलाकर USB कुंजी डिवाइस की पहचान करें और उसे माउंट करने के लिए <deviceid>: चलाएँ।
सहायता प्रिंट करने के लिए ./cpu.efi चलाएँ:
Usage:
patch: <tool> p
patch & exec: <tool> x
perf: <tool> f
zero out m&p: <tool> z
hook: <tool> h [m&p idx] [uop addr] [patch addr]
template: <tool> m
dump imms: <tool> di
dump rom: <tool> dr
dump msrs: <tool> dm
dump SMM: <tool> ds [address] [size]
cpuid: <tool> c [rax] [rcx]
rdmsr: <tool> rm [msr]
wrmsr: <tool> wm [msr]
read: <tool> r [cmd] [addr]
write: <tool> w [cmd] [addr] [value]
invoke: <tool> i [addr]
update ucode: <tool> u [size]
ldat read: <tool> lr [port] [array] [bank] [idx] [addr] [optional size]
ldat write: <tool> lw [port] [array] [bank] [idx] [addr] [value]
cpu कमांड लाइन से सरल निर्देश चलाने के लिए सहायक उपकरण प्रदान करता है:
cpu जटिल CPU रूटीनों के लिए इंटरफ़ेस प्रदान करता है, जिन्हें CPU व्यवहार का अध्ययन करने के लिए निष्पादित करना दिलचस्प है:
u: दिए गए (हस्ताक्षरित) पैच के साथ CPU ucode को अपडेट करेंf: माइक्रोकोड चलाते समय प्रदर्शन काउंटर एकत्र करेंcpu अप्रलेखित निर्देशों udbrd और udbgwr के लिए रॉ इंटरफ़ेस प्रदान करता है।
वे जो सबसे दिलचस्प कमांड प्रदान करते हैं वे हैं:
cpu पढ़ने और लिखने के लिए LDAT पहुँच रूटीन प्रदर्शित करता है। वहाँ पढ़ने या लिखने के लिए पैरामीटर [port] [array] [bank] [idx] [addr] निर्दिष्ट करें।
दिलचस्प पोर्ट हैं:
कृपया ध्यान दें कि इनमें से कुछ आंतरिक घटकों तक पहुँचने से CPU फ़्रीज़ हो सकता है।
cpu माइक्रोकोड में पैच स्थापित करने की कार्यक्षमताएँ प्रदान करता है।
bios/ucode_patches/ucode_patch.u में लिखें (उदाहरणों के लिए अन्य पैच देखें).org में दिए गए पते पर पैच स्थापित करने के लिए cpu.efi p निष्पादित करें।ध्यान दें कि माइक्रोकोड में, केवल 0x7c00 और 0x7e00 के बीच के पते ही लिखने योग्य और पैच करने के लिए सार्थक हैं।
cpu.efi x चलाने पर, यह पैच किए गए माइक्रोकोड को भी निष्पादित करेगा और परिणामस्वरूप rax, rbx, rcx, rdx रजिस्टर प्रिंट करेगा।
कुछ CPU घटनाओं या माइक्रोकोड बिंदुओं पर स्वचालित रूप से माइक्रोकोड निष्पादित करने के लिए, cpu मैच और पैच का लाभ उठाता है।
यह हुक करने के लिए एक माइक्रोकोड पता और हुक ट्रिगर होने पर कूदने के लिए माइक्रोकोड पता परिभाषित करता है।
z: सभी मैच और पैच रीसेट करता है।h: एक इंडेक्स (0-0x20), हुक करने के लिए एक पता (0-0x7c00) और निष्पादित करने के लिए एक लक्ष्य पता (0x7c00-0x7e00) दिए जाने पर एक हुक स्थापित करता है।कई हुक स्थापित करके और एक निर्देश को लगातार निष्पादित करके, cpu ऐसे निर्देश द्वारा किए गए माइक्रो-ऑपरेशनों को ट्रेस करने और उन्हें डंप करने में सक्षम है। ट्रेस करने के लिए:
get_trace_clock_at() में // [TRACED INSTRUCTION HERE] के बाद ट्रेस किया जाने वाला निर्देश लिखें।cpu.efi m।
यह एक trace.txt फ़ाइल बनाएगा जिसमें सभी हिट किए गए पते शामिल होंगे।uasm-lib/uasm.py -t trace.txt > parsed_trace.txt निष्पादित करें।
यह निर्देश के दौरान निष्पादित माइक्रोकोड का पूर्ण ट्रेस उत्पन्न करेगा।ध्यान दें कि uasm.py निष्पादित माइक्रो-निर्देशों का डिसअसेंबली उत्पन्न करने के लिए अपने फ़ोल्डर में ms_arrayX.txt फ़ाइलों का लाभ उठाएगा। ये stepping 0x9 (cpuid 0x000506C9) वाले GLM के लिए हैं। यदि आपके पास अलग stepping है तो कृपया उचित ऐरे उत्पन्न करें।
आप इस उद्देश्य के लिए LDAT डंप कार्यक्षमताओं का उपयोग कर सकते हैं।
CPU के पास आर्किटेक्चर से भिन्न दुर्गम बफ़र होते हैं, जिनके लिए हम डंप करने हेतु रूटीन प्रदान करते हैं:
smm: SMROM (या SMM सुरक्षा अक्षम करते समय कोई अन्य पता)rom: आंतरिक ROMimms: CPU हार्डकोडेड इमीडिएटmsrs: आंतरिक MSRs कॉन्फ़िगरेशनहम एक असेंबलर प्रदान करते हैं जो cpu.efi UEFI एप्लिकेशन में संकलित होने वाली हेडर फ़ाइलें उत्पन्न करता है।
सिंटैक्स के लिए bios/ucode_patches में दिए गए पैच देखें।
यह सरल ऑपरेशन और लेबल का समर्थन करता है।
uasm.py -i ucode_patch.u -o ucode_patch.h के साथ एक माइक्रोकोड पैच असेंबल करें।
cpu.efi संकलित किया जाएगा और स्वचालित रूप से उस माइक्रोकोड पैच को शामिल करेगा जिसे आप लागू करना चाहते हैं।
फ़ाइल: code_patch.u
.org 0x7c00
rax:= ZEROEXT_DSZ32(0x00001337)
rbx:= ZEROEXT_DSZ32(0x00001337)
rcx:= ZEROEXT_DSZ32(0x00001337)
rdx:= ZEROEXT_DSZ32(0x00001337)
पुनर्संकलन करें, फिर GLM में चलाएँ:
cpu.efi z # zero out match & patch
cpu.efi p # apply the patch
cpu.efi h 0 0x0428 0x7c00 # rdrand entry point
अब जब भी rdrand निष्पादित होगा, यह रजिस्टरों में 0x1337 लौटाएगा।
@inproceedings{Borrello2023CustomProcessingUnit,
title = {{CustomProcessingUnit}: Reverse Engineering and Customization of Intel Microcode},
author = {Borrello, Pietro and Easdon, Catherine and Schwarzl, Martin and Czerny, Roland and Schwarz, Michael},
booktitle = {IEEE Workshop on Offensive Technologies (WOOT 23)},
year = {2023},
}
पेपर में वर्णित प्रयोगों को इसके साथ चलाया जा सकता है:
cpu.efi e [exp_idx]
जहाँ [exp_idx]: