U.K. flag click here for English version

Co je ROMOS?    Požadavky    Instalace    Download    Technické detaily    Moderní BIOSy    FAQ

Projekt ROMOS


logo


      ROMOS je samostatný strojový kód x86, který umožňuje spouštět vlastní binární kód nebo binární kód třetích stran. Využívá pouze funkcí BIOSu, takže je nezávislý na operačním systému. Hlavním účelem je jeho umístění do ROM, odkud může během POSTu při bootování počítače (Power-On Self Test) spouštět další programy, např. bootmanažera, diagnostiku či speciální řídicí software. Mimo jiné může také nabootovat operační systémy založené na DOSu (možná i jiné) jako třeba FreeDOS, uložené v ROM spolu s ROMOSem. Z toho plyne, že není potřeba žádná disková mechanika, což může být velmi výhodné v případě různých kompaktních bezdiskových PC systémů. Dobře také poslouží jako rezervní operační systém v případě, že se něco stane a počítač přestane bootovat. Další využití je na vás.

      Jsou dvě možnosti kam lze ROMOS umístit. Jednak může být vložen jako ISA ROM modul do systémového BIOSu, který je ve FlashROM na základní desce. Pak není potřeba žádný další hardware, ale jsme limitováni volným místem ve flešce. Nebo lze ROMOS vypálit do paměti EPROM, kterou zastrčíme do speciální ISA karty. Levnější je ale použít jakoukoliv síťovku s paticí na BootROM. Pak bude možná potřeba ještě BootROM povolit v nastavení pomocí konfigurační utility od výrobce síťové karty. Tyto nastavění (jako např. MAC a další) se ukládají do malé paměti EEPROM na kartě.
Tady jsou požadavky na systém:

-PC s BIOSem uloženým ve FlashROM (EPROM nelze [snadno] modifikovat)
-operační systém MS-DOS 7.0 a vyšší (ten z Win9X) nebo FreeDOS
-dostatek volného místa ve FlashROM (min. 2 kB pro samotný ROMOS + další kód)
 (přeložený ROMOS s FreeDOSem potřebuje 64 kB), jak uvolnit více místa je popsáno níže.
-Award BIOS 4.51/6.00 (AMI BIOS jsem nezkoušel, ale nové verze už neporporují ISA ROM moduly)
-soubor s BIOSem pro vaši základní deskou (lze ho dumpnout z flešky pomocí awdflash.exe)
-programy cbrom.exe a awdflash.exe umožňující vložení ROMOSu do image BIOSu a jeho flashnutí.

Pokud chcete používat ROMOS na samostatné ISA kartě, stačí jen:
-ISA karta podporující paměťové čipy do velikosti 64 kB
-Programátor FlashROM nebo EPROM pamětí

Pokud si chcete udělat vlastní ROMOS build, bude ještě třeba:
-disketová mechanika 1,44 MB a jedna disketa (na modifikaci image virtuálního ROM disku)
-překladač assembleru NASM
-romchk.exe a zalign.exe na výrobu ROM image souboru
-fdimg.exe na práci s image souborem virtuálního ROM disku
(všechny potřebné programy jsou v ZIP balíčku zde)

NO LAMERZ
VAROVÁNÍ PRO LAMY:
Buďte si jisti, že víte přesně co děláte! Experimentováním se zde popisovanými programy si totiž můžete snadno zmrvit BIOS tak, že vaše PC už nenabootuje. Pokud k tomu dojde, bude potřeba vyndat FlashROM čip a přeflashovat ho v programátoru nebo zkusit hotflash. Takže mějte při ruce zálohu!
ROMOS je poskytován tak jak je, bez žádných záruk. Zkoušel jsem ho pouze na svém počítači takže nemůžu zaručit, že bude fungovat i na ostatních počítačích.
Doporučuji si přečíst sekci technické detaily. U nových Award BIOSů může dojít k nečekaným komplikacím, viz moje zkušenosti se základní deskou Gigabyte GA-P31-DS3L.
NO LAMERZ

      Před instalací je potřeba nejdříve získat soubor s image vašeho BIOSu. Můžete si ho stáhnout z webu výrobce vaší desky nebo ho dumpnout pomocí awdflash.exe /pn /sy bios.bin. Přesuňte soubor bios.bin do adresáře, kam jste rozbalili ZIP balíček s ROMOSem a udělejte si záložní kopii. Pokud chcete modifikovat obsah virtuálního ROM disku, vložte 1,44MB disketu bez vadných sektorů do mechaniky A: (pokud ji máte jako B:, je třeba upravit cesty v dávkových souborech) a spusťte putimg.bat (z DOSu, ne z Windows). Program FDIMG přenese image soubor romdisk.img na disketu. Díky specifickému formátu diskety (63 kB s jednou FATkou) s ní lze pracovat jen v novější verzi MS-DOS 7.0+ nebo FreeDOS. Potom už lze jednoduše na disketě kopírovat/mazat soubory, přenášet systém příkazem sys, prostě stejně jako s jinými disketami. Taky lze z diskety zkusit nabootovat a otestovat, zdali vše správně funguje. Když je disketa odladěná, stačí spustit getimg.bat (předtím si zálohujte původní romdisk.img) a FDIMG vytvoří image soubor diskety.
      Pak můžete zeditovat zdroják romos.asm. Je zde pár důležitých nastavení:
řádka 17 odkomentováním definice MAKE_PCI_MODULE se do ROM modulu vloží PCIR a $PnP hlavička nutná pro tvorbu PCI ROM modulu. Některé hodnoty v těchto hlavičkách je třeba po překladu nakonfigurovat pomocí přiloženého programu bromcfg.exe.
řádka 18 odkomentováním definice HOOK_INT19H se povolí pověšení na INT 19h.
řádka 19 definuje velikost ROM modulu v kB (včetně romdisk.img), minimální velikost je 2 kB.
řádka 20 definuje kterou jednotku bude ROMOS emulovat. Pokud jednotka v systému existuje, bude přístup k ní znemožněn. Pokud máte jednu disketovou jednotku vyberte B:, pokud žádnou vyberte A:.
řádky 21-23 definují formát diskety použité pro virtuální ROM disk. Pokud použijete dodávaný image soubor romdisk.img není potřeba nic editovat.
řádka 24 definuje offset v bootsektoru, kde se nachází byte udávající číslo bootovací jednotky. V případě operačních systémů typu DOS není třeba editovat, neb je tento byte vždy na offsetu 24h a ROMOS ho automaticky přepíše podle hodnoty ROMDISK_DRIVE nastavené na řádku 14.
řádky 25-26 definují adresu, kam bude bootsektor nahrán před jeho spuštěním. BIOS tak obvykle činí na 0000:07C00h.
řádka 27 definuje dobu zobrazení hlášky o bootování ROMOSu v 55ms ticích časovače.
řádka 28 definuje horkou klávesu, kterou se ROMOS aktivuje (ScrollLock/NumLock/CapsLock).
řádka 34 odkomentováním definice USE_PCI_REG_PATCH se aplikuje patch pro modifikaci určitého PCI konfiguračního registru v určitém PCI zařízení (provede se při každém spuštění), viz níže v changelogu.
      Po editaci romos.asm spusťte rcompile.bat pro přeložení do strojového kódu. Soubor romdisk.img je automaticky inkludován. Také je upraven kontrolní součet (offset 0Dh) a velikost romos.bin je zarovnána na celočíselný násobek 512B. Výsledkem je tedy image soubor ISA ROM, který lze přímo napálit do EPROMky, zastrčit do ISA karty a bootovat. Nebo ho lze jako ISA ROM modul vložit do systémového BIOSu. Pokud jste váš soubor s BIOSem nakopírovali jako bios.bin do adresáře ROMOSu, stačí spustit insromos.bat a CBROM vloží ROMOS na adresu D000:0000h (pokud jste vybrali jinou adresu, upravte parametr v dávkovém souboru). Nyní se podívejte na výpis CBROMu, jestli se modul správně vložil. Pokud napíše něco jako 'not enough space', přečtěte si sekci technické detaily, jak nějaké místo ve flešce uvolnit vyjmutím nepotřebných modulů BIOSu.
      Nakonec stačí váš modifikovaný bios.bin naflashovat pomocí awdflash.exe bios.bin a restartovat počítač. Pokud používáte ROMOS PCI jako náhradu BOOTROM onboard síťové karty nezapomeňte v SETUPu aktivovat její BOOTROM a popř. povolit hook INT 19h pokud je tam taková volba. Po restartu a poté, co BIOS provede POST, by se měla na horním řádku obrazovky zobrazit bíle hláška 'Press [ScrollLock] to boot ROMOS !'. Defaultně se zobrazí po dobu 1,6 vteřiny. Pokud nic neprovedete, BIOS bude pokračovat v bootování z diskových jednotek jako normálně a uvolní oblast ROM pro jiné využití (např. UMB paměť, rámec EMS paměti, apod.). Pokud zmáčknete ScrollLock (můžete ho stisknout i před zobrazením hlášky), ROMOS vypíše nějaká debugovací hlášení, nainstaluje vlastní obsluhu přerušení INT 13h (která zprostředkuje přístup k virtuálnímu ROM disku), překopíruje bootsektor z virtuálního ROM disku na danou adresu a předá mu řízení. Ten pak natáhne z ROM disku operační systém. Nadále pak budete mít k virtuálnímu ROM disku přístup pouze pro čtení pod jmenovkou definovanou proměnnou ROMDISK_DRIVE.

      Zde si můžete stáhnout poslední verzi ROMOSu. Je to volně šiřitelný software a můžete ho modifikovat podle libosti, ale nechte mi tam prosím copyright. Jakýkoliv software založený na ROMOSu by měl být dán též volně k dispozici i se zdrojáky. Pokud vytvoříte nějakou podstatnou modifikaci nebo narazíte na chybu, dejte mi laskavě vědět.

romos.asm [35 kB] - ROMOS 1.06 ISA/PCI zdrojový kód v assembleru, poslední modifikace 7.12.2017

romos.101 [28 kB] - ROMOS 1.01 zdrojový kód, starší verze

romos.094 [14 kB] - ROMOS 0.94 zdrojový kód, starší verze

romos.001 [7 kB] - ROMOS 0.01 zdrojový kód, ještě starší verze ;-)

romos.bin [64 kB], romospci.bin [64 kB] - ROMOS 1.05 ISA a PCI přeložený modul (k umístění na adresu D000:0000h, emulující jednotku B:) obsahující FreeDOS jádro 2035, Mikro Manažer 1.0 eng. (nyní po rekompresi ~ o 2 kB menší), Dynaload pro dynamické zavádění ovladačů, SeeMem na prohlížení paměti a pár dalších drobností. PCI verzi je třeba před použitím nakonfigurovat pomocí bromcfg.exe (součást zip balíčku).

romos16k.bin [16 kB] - ROMOS 1.02 PCI přeložený modul (k umístění na adresu D000 - DC00:0000h, nakonfigurovaný pro PCI síťovou kartu Realtek 8029, emulující jednotku A:) obsahující DF-DOS 0.04b - www.dftech.cwc.net/osdev, prohlížeč paměti a pár demíček. Zde je videoukázka s DF-DOSem a několika starými hrami.

romos.zip [906 kB] - ROMOS 1.06 vývojový balíček se vším potřebným včetně překladače NASM.

rjdos.zip [12 kB] - RJDOS 0.01a od Richarda L. Jamese je malá náhrada za command.com (9746 bytes), kterou lze vložit do romdisku.

Pokud se chcete právě teď na vlastní oči podívat, jak to funguje, tady je animace bootujícího ROMOSu na mém PC od Borg Number One, která by snad vašemu počítači neměla ublížit ;-)

Bootovací proces s ROMOSem na mojem PC

      22.2.2004 Verze 0.95 byla výrazně přepracována. Hlavní kód ROMOSu je nyní jako obslužná funkce INT 19h. V první fázi během POSTu, kdy BIOS provádí ROM-scan, se pouze zobrazí dotaz, zdali spustit ROMOS. V kladném případě nainstaluje obsluhu INT 13h a na hlavní kód nasměruje vektor INT 19h. Pak předá ROMOS řízení zpět BIOSu, který korektně dokončí POST. Po kompletní inicializaci BIOS zavolá INT 19h, čímž se znovu spustí ROMOS (pokud byl INT 19h přesměrován), který tentokrát provede zavedení systému z virtuálního ROM disku.

      4.3.2004 byl updatován FreeDOS kernel na verzi 2033 (obsažený v romos.bin a romos.zip), který přeložil Luchezar Georgiev pomocí BC pro 386, čímž se zmenšila jeho velikost na 42518 B. Díky tomu je nyní v ROM disk image o 1 kB více místa pro uživatelské programy.

      22.9.2004 Nová verze 0.97 obsahuje četné změny a optimalizace kódu. Nejpodstatnější změnou je uložení pár potřebných permanentních dat do volných míst v tabulce vektorů přerušení místo do segmentu ROMOSu. Tím je umožněn běh z pamětí skutečně pouze pro čtení (EPROM na kartě bez shadowingu) a v PC emulátoru BOCHS, kde lze ROMOS pohodlně ladit. Nyní není kód vázán na konkrétní segment, v praxi ale v PC stejně nemáme moc na výběr, buď D000h nebo E000h (jen u starších PC). Dále byla přepracována struktura obsluhy INT 13h tak, aby šly jednoduše přidávat nové podslužby. Byla přidána podslužba 03 (zapisuj sektor), která vrací chybový kód. Pro rychlou orientaci jsem na konec zdojového kódu přidal i stručný vývojový diagram. Pak jsem ještě na image ROM disku nahrál nový kernel 2035.

      23.10.2004 Verze 1.00 obsahuje další optimalizace kódu a obsluha INT 13h byla rozšířena o podporu funkce 15h. Dále jsem se zabýval úpravou zdrojáků a překladem FreeDOS kernelu 2035. Díky odebrání některých nepotřebných částí kódu (fdconfig.sys - jen config.sys, break, numlock, echo, switches, country, menus), optimalizaci překladače a packeru se mi podařilo dosáhnout velikosti jen 39390 B pro kernel s podporou FAT32. Díky tomu se na ROMDISK vejde i USB ovladač pro mass-storage zařízení (flashdisky a pod.), odkud lze tahat další soubory. Např. pomocí loadlin.exe by bylo možno natáhnout z flashdisku Linux - bohužel nemám na čem vyzkoušet. ROMDISK image s USB driverem je obsažen v zip balíčku jako romdusb.img spolu se standardním romdisk.img.

      18.3.2006 Hlavní novinkou verze 1.02 je přidaná podpora Plug&Play PCI ROM. Většina nových základních desek bez ISA slotů má totiž BIOS ochuzen o podporu ISA ROM modulů a proto tam ROMOS nefungoval. Nyní lze tedy ROMOS přeložit i jako PCI ROM modul (PCI ROM lze použít i jako ISA ROM, nikoliv naopak). PCI ROM ve své hlavičce obsahuje ID výrobce, ID zařízení a třídu zařízení která musí odpovídat skutečným hodnotám nějakého PCI zařízení přítomného v systému, jinak se ROM nespustí. Některé BIOSy navíc dovolují PCI ROM přiřadit pouze PCI zařízením, která skutečně disponují nějakou ROM nebo paticí (např. síťová karta). Alespoň v mojem systému to fungovalo pouze s ID síťové karty (zkoušel jsem např. PIIX4, PCI-PCI můstek, USB řadič...). Pro toto nastavení přeloženého PCI ROM modulu slouží program bromcfg.exe od Arneho, který je v zip balíčku.

      15.7.2007 Ve verzi 1.03 je jen pár drobnějších změn, nyní lze ve zdrojovém kódu pomocí definice HOOK_INT19H vypnout/zapnou pověšení na INT 19h. Pokud je definice zakomentovaná, tak se ROMOS spustí ihned po dotazu a stisku klávesy (s tím, že se případně nedokončí POST, ale někdy se to může hodit). Dále byly obměněny některé programy na ROMDISKu. ROMOS jsem úspěšně otestoval na AMI BIOSu desky Asus P5LD2 a pro AMI BIOSy přikládám v zip balíčku potřebný program AMI MMTool 3.12 pro vložení ROMOS modulu do BIOS image.

      22.6.2009 Verze 1.04 obsahuje pouze jedno vylepšení zdrojového kódu - optimalizace rutiny pro výpis hexadecimálních čísel a úpravu souvisejících rutin, čímž jsem ušetřil 17 B strojového kódu.

      13.5.2012 Verze 1.05 obsahuje další optimalizace, které vedly k úspoře 16 B strojového kódu. Také jsem změnil způsob zřetězeného volání původní obsluhy přerušení INT 13h z modifikovaného FAR JMP na volání dalšího přerušení. Tím jsem v IVT ušetřil jednu pozici pro vektor INT 84h, kam se dříve vkládal opkód instrukce FAR JMP před vektor INT 85h. Nyní se tedy v IVT obsazuje pouze vektor INT 85h (jeho číslo je možno snadno změnit ve zdrojáku).

      7.12.2017 Do verze 1.06 jsem přidal speciální funkci pro změnu určitého PCI konfiguračního registru v určitém PCI zařízení, která se může provést při každém startu PC. Slouží jako patch pro případ, že BIOS něco špatně inicializoval nebo opomenul inicializovat a potřebujeme si to upravit po svém ještě před bootem operačního systému. Napsal jsem to speciálně jako workaround chyby špatně nastaveného PCI2PCI můstku na základní desce Gigabyte GA-P67-DS3-B3, kde nebyl zapnutý VGA 16-bit I/O Space Decoding Enable bit, ale třeba se to bude hodit i někomu dalšímu pro řešení jiného problému s PCI zařízením. Funkce patche se nastavuje pomocí následujících definic konstant: PPCI_BUS, PPCI_DEV, PPCI_FUNC definují PCI adresu daného zařízení (dle lspci či SMB /pci a pod.), PPCI_REG definuje adresu 32-bitového PCI konfiguračního registru (Bytový offset 0 - 252, musí být zarovnaný na 4 Byte) v daném zařízení a PPCI_REG_ORMSK definuje masku bitů, které mají být ve 32-bitovém registru nastaveny na hodnotu 1. Pokud potřebujete nějaké bity vynulovat, nastavte masku PPCI_REG_ANDMSK a odkomentujte její použití (řádek AND EAX,PPCI_REG_ANDMSK) níže v kódu.

      20.11.2020 Jeden známý se inspiroval mým projektem a vytvořil vlastní ROM bootloadery BootVinyl a BootLPT/86. Jako první napsal BootLPT/86 (vejde se do 2kB ROM), přes nějž nabootoval staré diskless PC, které mělo pouze ARCNET síťovku, pomocí kříženého 4-bitového LapLink kabelu připojeného k druhému PC s DOSem nebo Windows, na němž běží serverová aplikace starající se o přenos bootovacího image s FreeDOSem. BootVinyl (vejde se do 1kB ROM) je spíše taková kuriozita, kterou napsal pro své IBM 5150 PC XT, využívající analogový vstup pro kazetový magnetofon, krmený audiosignálem z gramofonu, jenž přehrává desku s analogovým záznamem bootovacího image.

Technické detaily (hákování BIOSu, ROM moduly, ASM...)

      Od čtenáře budu předpokládat určité znalosti ohledně hardwéru PC, BIOSu (implicitně se vše vztahuje k AWARD BIOSu), DOSu a assembleru. Pokud jste windouzácký klikálek, běžte si raději hrát s panem Sponkou z M$ Mordu... :)
      Dobrá, shrňme si pár faktů o BIOSu (Basic Input Output System). Je to základní software (měli bychom říkat firmware) uložený v permanentní paměti na základní desce, poskytující základní funkce jako třeba přístup k diskům, obrazovce, klávesnici, portům, časovači, atd. Operační systém pak může nebo nemusí těchto funkcí využívat. Operační systémy založené na DOSu je vždy využívají. BIOS přebírá řízení pokaždé, když zapneme (nebo tvrdě resetujeme) počítač, na své vstupní adrese F000:FFF0h. Pak provede POST (Power-On Self Test) - různé inicializace a testy (např. nastavení registrů chipsetu, rychlosti CPU [přes PLL], test operační paměti, hledání diskových jednotek, hledání dalších ROM a spoustu dalších věcí). BIOS také obsahuje program SETUP, který umožní uživateli provést různé hardwarové nastavení, které posléze uloží do paměti CMOS zálohované baterkou.
      Dříve byl BIOS uložen v jednom nebo dvou paměťových čipech EPROM. 486tky používaly obvykle jednu paměť typu 27C512 (64 kB) a 286tky a 386tky dvě paměti typu 27C256 (32 kB) - sudá a lichá část (dáno 16-bitovým adresováním). Poznamenejme, že paměti typu EPROM je možno vymazat pouze ozářením UV světlem - proudem vysokoenergetických fotonů. Pro tento účel mají keramická pouzdra pamětí nahoře okénko z křemičitého skla, které je obvykle přelepeno nějakou samolepkou. Ovšem existují i levné verze EPROM pamětí bez okénka (ano, ty v epoxidových pouzdrech), které lze vymazat pouze rentgenovým zářením, ale nedoporučuji to zkoušet doma :). Díky tomu je aktualizace BIOSu dosti obtížná, pokud nemáte náhodou mazačku a programátor EPROM. V pamětech byl uložen přímo binární kód BIOSu, který byl celý vidět v adresovém rozsahu F0000 - FFFFFh.
      Systémy s Pentiem (a také některé moderní 486 a 5x86) přinesly podstatné vylepšení tím, že pro uložení BIOSu byla použita paměť typu Flash EPROM. To umožnilo uživateli elektricky vymazat a přeprogramovat kód BIOSu bez nutnosti vyjmutí čipu ze základní desky. První FlashROM paměti jako třeba 28F001 vyžadovaly zvlášť 12V napájení pro mazání a programování. Novější, jako třeba 29F020, si už vystačí s jediným napájením 5V. Nyní se prosazují různé LV varianty na 3,3 V, které jsou k vidění zejména na grafických kartách. Nejstarší základní desky podporovaly pouze 12V FlashROM paměti, novější měly jumper pro výběr 5 / 12 V a nejnovější už zas podporují jen 5V nebo 3,3V čipy. Kapacita paměti se zvětšovala od 128 kB přes 256 kB po 512 kB a zřejmě dál poroste. Na některých nejnovějších motherboardech je k vidění paměť v pouzdru SMD PLLC místo klasického DIL. V extrémních případech je pak PLLC čip připájen přímo na plošný spoj, takže ho v případě problémů nelze snadno vyjmout a přeprogramovat v programátoru. Myslím, že to není nejlepší trend. Jistě, pro výrobce desek je to jednodušší a levnější řešení a některé HW servisy si na tom pak snadno namastí kapsu. K ochraně před nechtěným přepsáním BIOSu bývá v okolí FlashROM na desce jumper s nápisem 'programming enable' nebo 'write protect'. Tak ho nyní přepněme.
      Také struktura kódu BIOSu se změnila. Místo formy jednoho binárního kódu došlo k rozdělení na dvě části - 8kB nekomprimovaný bootblock a modul(y) komprimované LHA. Bootblock dostane řízení jako první a postará se o překontrolování a rozbalení LHA komprimovaných modulů na dané adresy RAM. Pokud je vše v pořádku, předá řízení hlavnímu modulu. Avšak je-li nějaký modul poškozen a nesedí jeho kontrolní součet, bootblock akorát vydá chybové zapípání. Ale zachovejte paniku :), pokud je bootblock v pořádku umožní vám přeflešovat BIOS pomocí DOSové bootovací diskety s funkčním BIOS image souborem, flashovacím programem a správně napsaným souborem autoexec.bat. Pravděpodobně na obrazovce nic neuvidíte, protože bootblock neinicializuje PCI a AGP. A tak můžete aspoň sledovat LED na disketové mechanice. Pokud použijete starší ISA VGA kartu, měly by být výpisy BIOSu normálně vidět. Jednoduše strčte disketu do mechaniky a restartujte. Bootblock z ní nabootuje DOS a autoexec.bat zavolá awdflash.exe, který přeflešuje BIOS funkční verzí a mělo by to být OK :).
      Pokud všechny ostatní snahy selžou, je třeba čip vytáhnout z patice a nechat ho přeprogramovat v programátoru. Nebo můžete vyzkoušet metodu hotflash, pokud ovšem máte po ruce záložní FlashROM čip. Já jsem vždy používal tuhle metodu, protože programátory pamětí jsou kur..... drahý. Ale je zde větší či menší riziko odpálení paměti nebo rovnou celé desky. To záleží, jak moc věříte Murphyho zákonům ;-). Já jsem na svojí desce dělal asi 50 hotflashů a podařilo se mi odkouřit jednu paměť. To je 98% úspěšnost - to jde ne? Ale nová fleška mě pak stála asi dvě kila. Hotflash je v podstatě velmi jednoduchá záležitost. Pro vytvoření zálohy nejprve potřebujeme paměť stejné kapacity (může být od jiného výrobce). Vypneme počítač, vytáhneme stávající čip a znovu ho vložíme zlehka do patice. Vyndáme nepotřebné karty, kabely a další harampádí, které nám brání ve snadném přístupu k patici s čipem. Zapnem počítač a nabootujem čistý DOS. Pak opatrně vytáhneme čip z patice (pokud jste ho předtím vyndali a zandali, jak jsem vám radil, nebudete nyní muset použít příliš násilí) a vložíme prázdný. Systém nespadne, protože BIOS je stínovaný v RAM. Naflashujeme funkční soubor BIOSu do paměti a restartujeme počítač. Nyní máme k dispozici záložní čip. Pokud se něco těžce zesere, stačí čipy prohodit a udělat postup znovu.
      Nyní něco ohledně modulů BIOSu. Lze je prohlížet/přidávat/odebírat pomocí programu cbrom.exe. Nebo je lze taky všechny najednou vyextrahovat pomocí awarddec.exe. Pro AMI BIOSy existuje podobný nástroj amibcp.exe pro DOS & Windows a mmtool.exe pro Windows. Tady je listing mojeho BIOS fajlu:


 No. Item-Name         Original-Size   Compressed-Size Original-File-Name
================================================================================
  0. System BIOS       20000h(128.00K) 14E93h(83.64K)  original.tmp
  1. XGROUP CODE       082F0h(32.73K)  05877h(22.12K)  awardext.rom
  2. ACPI table        02214h(8.52K)   00E51h(3.58K)   ACPITBL.BIN
  3. VRS ROM           02280h(8.62K)   014BBh(5.18K)   ANTI_VIR.BIN
  4. EPA LOGO          0279Ch(9.90K)   0132Ah(4.79K)   SKULL4.EPA
  5. CPU micro code    0A800h(42.00K)  060D8h(24.21K)  cpucode.bin
  6. ISA ROM[A]        10000h(64.00K)  0F437h(61.05K)  romos.bin

  Total compress code space  = 34E93h(211.64K)
  Total compressed code size = 3324Fh(204.58K)
  Remain compress code space = 01C44h(7.07K)

                          ** Micro Code Information **
Update ID  CPUID  |  Update ID  CPUID  |  Update ID  CPUID  |  Update ID  CPUID
------------------+--------------------+--------------------+-------------------
SLOT1  13   0630  |  SLOT1  20   0632  |  SLOT1  36   0633  |  SLOT1  37   0634
SLOT1  40   0650  |  SLOT1  40   0651  |  MOBILE 2D   0652  |  SLOT1  10   0653
SLOT1  0A   0660  |  PPGA   03   0665  |  MOBILE 07   0670  |  SLOT1  03   0671
SLOT1  10   0672  |  SLOT1  0E   0673  |  SLOT1  14   0680  |  PPGA   14   0681
PPGA   14   0683  |  PPGA   08   0686  |  PPGA   01   068A  |  SLOT1  07   06B0
SLOT1  1D   06B1  |

a zde jak to vypadá v případě nového AMI BIOSu:
AMI MMTool BIOS modules listing

Hlavní modul je original.tmp (na řádce 0.). Obsahuje rezidentní kód, program SETUP a POST rutiny. Je vždy dlouhý 128 kB. Prvních 64 kB original.tmp se nahraje dočasně na adresy E000:0000 - E000:FFFFh. Po proběhnutí POSTu se tato paměť uvolní. Druhých 64 kB original.tmp je permanentně umístěno na F000:0000 - F000:FFFFh a po POSTu se uzamkne proti zápisu. CBROM neumožňuje extrahovat/vkládat hlavní modul original.tmp. To lze udělat pomocí awarddec.exe (pouze extrakce) nebo modbin.exe. Modifikace original.tmp není žádná legrace, protože je chráněn dvěma kontrolními součty. Naštěstí je MODBIN umí spočítat. Také vložení modifikovaného souboru zpět do BIOS image není snadné a já sám nemám zaručený postup. Ale podařilo se mi to pomocí prográmku awdhack.exe.
      Díky tomu, že se BIOS stává čím dál více komplexnější a větší, tak se už celý nevejde do original.tmp a proto byl rozdělen na víc částí - XGROUP a YGROUP CODE moduly. Můj BIOS je už relativně starý a tak obsahuje pouze XGROUP code reprezentovaný awardext.rom. Tento modul se obvykle rozbaluje na adresu 4100:0000h. Lze ho snadno modifikovat, ale po jeho vložení do BIOS image souboru je třeba nechat MODBINem přepočítat kontrolní součet (načíst soubor a zvolit update).
      Dále můžeme v listu vidět CPU micro code modul jako cpucode.bin. To je aktualizace mikrokódu, kterým lze modifikovat chování (opravovat chyby) složitějších instrukcí složených z více mikroinstrukcí jako je např. fsin, zatímco jednodušší instrukce by měly být kvůli rychlosti zadrátované natvrdo. Cpucode.bin se skládá z několika bloků pro každý deskou podporovaný CPUID o velikosti min. 2 kB a násobku 1 kB, jednoduše poskládaných za sebe do jednoho souboru (s výjimkou ASUS BIOSů). Každý blok mikrokódu má svoji hlavičku:


dd 000000001h ; Header Version
dd 000000013h ; BIOS Update ID
dd 008271996h ; Date (BCD)
dd 000000630h ; CPUID of target processor
dd 0f316fc3bh ; Checksum (zero-align to DWord sum)
dd 000000001h ; Loader Version
dd 000000010h ; CPU Flags
dd 000000000h ; Size of pure microcode data (for >2048 B only)
dd 000000000h ; Total size (for >2048 B only)
dd 000000000h ; reserved
dd 000000000h ; reserved
dd 000000000h ; reserved

Následují vlastní data, která jsou šifrovaná SHA1/SHA2 a digitálně podepsaná RSA 2048. Samozřejmě se to už řada lidí pokoušela hacknout, ale nikomu se to zatím nepodařilo. Intel si tyto informace jistě velmi pečlivě střeží. Zde je popsáno shrnutí jedné takové zajímavé analýzy. Je tam také zmínka o tom, že existují 2 různé formáty mikrokódů pro starší a novější CPU (změna nastala od novějších typů Core 2). Zajímavé je, že se v průběhu let může velikost mikrokódu pro určitý CPUID měnit, např. pro CPUID 206A7h má první update z 28.12.2010 velikost 8192 B a poslední z 12.6.2013 už má 10240 B. Takže intel dopředu počítal s nějakou rezervou. U starších procesorů AMD K7 - K10, které ještě neměly šifrované mikrokódy, se podařilo reverzní analýzou odhalit, jak to uvnitř procesoru funguje a dokonce do něj nahrát vlastní mikroprogramy. UPDATE: nyní už je možno dešifrovat i mikrokódy některých intelích CPU, avšak není je možné modifikovat a podepsat, tak aby je CPU akceptoval.
      V novějších Award BIOSech se mikrokódy ukládají nekomprimovaně do modulu NCPUCODE.BIN, který leží v image až za komprimovanými bloky. Jelikož jsou data díky šifrování hodně entropická, tak zde komprese nemá smysl. Tento modul nemá na začátku hlavičku, ale na konci má patičku s řetězcem *ALIN16* za níž následuje DWord velikost modulu. S tímto modulem umí pracovat novější CBROM32 verze 1.xx pomocí parametru /nc_cpucode. Avšak při pokusu o aktualizaci mikrokódu v BIOSu pro moji novou desku Gigabyte GA-P67-DS3-B3 jsem narazil na jisté problémy. Když jsem chtěl modul z BIOSu extrahovat pomocí poslední dostupné verze CBROM32 1.99 (zkoušel jsem i starší verze) příkazem cbrom MY_F5.BIN /nc_cpucode Extract, se nejen že nevytvořil žádný soubor, ale modul mikrokódů se z BIOS image vymazal, jako kdybych použil parametr Release. Nicméně pomocí své utility AWDLS jsem ho vykopíroval ven. Při pokusu o vložení modifikovaného mikrokódu do BIOS image došlo k dalšímu problému, že CBROM mi soubor NCPUCODE.BIN smazal (resp. jeho délka se zmenšila na 0) a do BIOS image nic nevložil. Překvapivě pomhola finta nastavit souboru NCPUCODE.BIN atribut read-only a pak už ke smazání nedošlo a jeho obsah byl korektně vložen do BIOS image, který po flashnutí normálně fungoval. Později jsem přišel na trik, jak CBROMem modul mikrokódů z BIOS image vyextrahovat, stačí zadat příkaz cbrom MY_F5.BIN /nc_cpucode NUL a vytvoří se soubor NCPUCODE.BIN. Datum a čas BIOS image se změní, ale nemělo by dojít ke změně jeho obsahu (radši image předem zazálohujte a pak porovnejte).
      V BIOSu stačí mít pouze mikrokód pro aktuálně nainstalovaný CPU (číslo CPUID). Případně ho úplně vypustit, protože většina moderních OS (Windows/Linux) si zavádí potřebný update mikrokódu ze souboru při bootu. UPDATE: řada novějších CPU je už tak zabugovaná, že bez microcode update ani nenabootuje, takže je nutné ho zavést už z BIOSu. Zde je tedy jedna možnost, jak ve FlashROM uvolnit nějaké místo. Po vložení upraveného cpucode.bin pomocí CBROM není třeba dále provádět žádné opravy kontrolních součtů. Pro práci s mikrokódy jsem napsal dva programy. CPU Microcode Loader vypíše aktuální ID mikrokódu nahraného v CPU a umožní za běhu nahrát mikrokód ze souboru do CPU (tato změna má účinnost pouze do vypnutí nebo studeného restartu PC). Mikrokód se do CPU nahrává následující sekvencí: do EAX se vloží lineární adresa ukazující na začátek načtených dat mikrokódu (včetně hlavičky), do ECX se vloží konstanta 00000079h, do EDX se vloží 0 a nakonec se provede privilegovaná instrukce WRMSR. Procesor si mikrokód zkontroluje a v případě neshody CPUID nebo jiných parametrů ho odmítne. Dovoluje nahrát pouze novější nebo stejnou verzi mikrokódu než ta, která je aktuálně v procesoru. Některé BIOSy také podporují rozšířenou službu INT 15h (funkce D042h), která umožňuje mikrokód zapsat/přečíst přímo do/z FlashROM, podrobnosti viz Pentium Pro Processor BIOS Writer’s Guide. Druhý program Binary CPU Microcode file info umožňuje prohlížet informace o mikrokódech v souborech a rozdělit soubor cpucode.bin na dílčí soubory pojmenované podle odpovídajícího CPUID. Codemake.bat pak spojí vybrané soubory s mikrokódy do jednoho, který lze použít jako nový cpucode.bin.
      ACPI table modul má co dočinění s ACPI, ale nemám bližší informace. VRS ROM modul je potřeba pro vestavěný antivir, který mám stejně vypnutý. Myslím, že může být klidně odstraněn, pokud tuto funkci nepoužíváte. EPA LOGO je Energy Star logo zobrazované v pravém horním rohu během POSTu. Ve starších BIOSech je pouze dvoubarevné (EPA 1.0), v novějších pak 16-ti barevné (EPA 2.0, signatura "AWBM" na začátku souboru). Logo si můžete přehrát svým výtvorem. Pro tento účel jsem napsal vlastní BMP -> EPA convertor, kde jsem využil poznatky získané při hackování EPA 2.0 formátu (V té době jsem nikde na Internetu žádnou specifikaci nenašel). V AMI BIOSech, se kterými se můžeme setkat třeba na novějších deskách P4/C2D od Asusu se používá 16-ti barevný formát intel GRFX. Pro něj jsem napsal též vlastní BMP -> GRFX convertor. Můžete si je stáhnout tady, viz /PROGRAMOVÁNÍ. OEM LOGO modul je velké celoobrazovkové bitmapové logo zobrazované místo klasického výpisu POSTu. Lze ho najít na některých počítačích compaq, intel, aj. velkých firem. Jeho smazáním lze uvolnit ve FlashROM hodně místa. Pak taky můžeme vidět malé modré logo 'Award medal' v levém horním rohu, které není uloženo v žádném samostatném modulu, ale nejspíš v original.tmp. Zatím jsem nepřišel na to kde.
      Dále zde můžou být další moduly, jako třeba VGA videobios integrované grafické karty (tuto možnost lze použít v případě, že špatně naflashujete BIOS na VGA kartě), bootrom síťové karty, BIOS IDE/SCSI raid řadiče a další... Také jsem našel jeden podobný projekt ATA Security eXtension BIOS, který rozšiřuje BIOS o modul zabezpečení haddisku heslem. Moderní disky totiž už dobu podporují ATA příkazy pro nastavení uživatelského a administrátorského hesla, kterými lze účinně ochránit obsah disku, ale programátoři BIOSů toho zatím moc nevyužívají (vyjma notebooků).
      Pokud chcete spustit vlastní kód během POSTu, můžete snadno vytvořit ISA ROM modul a vložit ho do BIOS image souboru. Musíte přitom vybrat adresu pro váš modul tak, aby nekolidovala s ostatními ROM, nebo kódem BIOSu. Na obrázku níže je mapa obsazení paměti dolního megabajtu v typickém PC:

memory map

Obvykle máme k dispozici volnou oblast paměti na D0000 - DFFFFh (64 kB), kterou lze použít pro náš ISA ROM modul. Během POSTu provádí BIOS tzv. ROM-scan, kdy hledá v paměti externí ROMky. ISA ROM musí začínat prvními dvěma bajty 55 AAh následované třetím bajtem určujícím velikost ROM v 512B blocích. Avšak minimální velikost ISA ROM modulu je 2 kB. Protože BIOS hledá hlavičku ROM po adresovém kroku 2 kB, tak ROMka musí začínat na adrese, jenž je celistvým násobkem 2048 (800h). ISA ROM modul má svůj kontrolní součet. Ten spočítáme tak, že do proměnné typu byte posčítáme všechny bajty ROM modulu včetně hlavičky 55 AA (o přetečení se nestaráme). Tato hodnota pak musí být nulová. Pokud kontrolní součet nesedí, tak BIOS danou 2kB oblast přeskočí a pokračuje v hledání dále. Jinak začne provádět kód ROM počínaje čtvrtým bajtem. Sem můžeme vložit náš strojový kód, který vypadl z překladače NASM. Program musí být ukončen instrukcí RETF. Soubor s výsledným ISA ROM modulem by měl být zarovnán nulami na celočíselný násobek 512-ti na velikost danou třetím bajtem. Tady je šablona ROM:


DB 55		; header 1st byte
DB AA		; header 2nd byte
DB xx		; size in 512B blocks
JMP xxxx	; jump to our code
DB 0		; reserved byte for checksum
xxxx		; our code
.
.
.
RETF 		; return from ROM code

      Pro jistotu je dobré si hned na začátku uložit všechny registry CPU. Zásobník má obvykle nastavenou malou hloubku, proto jsem si ho přenastavil na 4000:FFFEh. Je třeba mít na paměti, že pokud se v kódu dopustíme chyby, která způsobí zatuhnutí nebo restart počítače, tak není způsob, jak spuštění ROM kódu zabránit. Pak je třeba přeflešovat BIOS v programátoru nebo použít hotflash! Takových chyb jsem se taky dopustil, neb je kód téměř nemožné debugovat. Proto jsem jako první napsal část kódu (label BEGIN), která mi dá na výběr, jestli pokračovat dál v provádění ROM kódu nebo ho ukončit. K tomu jsem využil testování vlajky klávesy ScrollLock na adrese 0000:0417h bit 4. Pokud ScrollLock nebyl stisknut, ROMOS obnoví uložené registry a vrátí kontrolu zpět BIOSu. Jinak pokračuje v provádění kódu ROM. Pokud se tak v dalším kódu vyskytne chyba (za labelem BOOT), jednoduše stačí PC restartovat a chybu opravit.
      ROMOS poskytuje pár základních funkcí: DELAY počká AH*55ms, GOTOXY nastaví kurzor na pozici dle DL,DH, WHEREXY načte pozici kurzoru do DL,DH, WRITE vypíše na aktuální pozici kurzoru nulou ukončený řetězec z adresy CS:SI atributem daným v BL, WCRLF vytiskne CR,LF, čímž odřádkuje, WHEXW vytiskne hexa slovo z DX, WHEXB vytiskne hexa bajt z AL, WREGS vytiskne hexa obsah registrů F, CS, SS, ES, DS, DI, SI, BP, SP na jednu řádku, SET_KBD_FAST nastaví rychlost klávesnice na 30 CPS a prodlevu opakování po prvním znaku na 250 ms, INSTALL_NEW_INT13 nastaví vektor přerušení INT 13h na novou obsluhu NEW_INT13 a uloží starý vektor INT 13h. Hlavní část programu je mezi labely BOOT a EXIT. Obsluha NEW_INT13 podporuje pouze funkci 02 - čti sektory. Ale mělo by to stačit na úspěšné nabootování a přístup pouze ke čtení k virtuálnímu ROM disku umístěnému na labelu IMG_BEGIN (za kódem ROMOSu). NEW_INT13 odchytí každé volání INT 13h, ověří pokud číslo disku odpovídá našemu virtuálnímu ROM disku a jestli číslo funkce je 02. Pak vypočítá lineární adresu v paměti podle daných diskových parametrů CHS a překopíruje požadovaný počet sektorů (512B bloků) z virtuálního image disku (RAM) do daného bufferu na ES:BX. Taky pro vizuální kontrolu, zda-li bylo přerušení řádně obslouženo, vypíše znak * do pravého horního rohu. Pokud je přerušení voláno s číslem jiného disku či jinou funkcí, je předáno původní obsluze INT 13h (pokud číslo disku sedí, ale neodpovídá funkce, tak je vypsán znak !). Nebyl by asi velký problém udělat přístup k ROM disku i pro zápis, možná v některé další verzi ROMOSu.
      Pokud opustíme kód ROM pomocí RETF aniž bychom smazali hlavičku 55 AA, tak paměť zůstane zaplácaná nevyužitým kódem. Přitom by mohla být využita jako oblast HMA, nebo okno EMS, a pod. pro zvětšení volné konvenční paměti DOSu. To je důvod, proč ROMOS při běžném bootu PC (kdy nebyl aktivován klávesou) před svým ukončením zapíše DW 0 přes hlavičku. Pokud ji tam však schválně necháme (kód ROM tak zůstane v paměti) a přenastavíme vektor přerušení INT 18h nebo INT 19h na ROMOS, pak můžeme ROMOS spustit i po bootu zavoláním tohoto přerušení. Pokud chcete této možnosti využít, stačí odkomentovat řádku %define HOOK_INT18_BY_ROMOS.
      A jak funguje virtuální ROM disk? Účelem bylo maximálně využít 64 kB prostor pro uživatelská data na ROM disku. Standardní 1,44MB disketa je naformátovaná takto: 80 cylindrů, 2 hlavy, 18 sektorů na stopu a 512 B na sektor. Jednoduše vyjádřeno CHS = 80 / 2 / 18. Pokud vynásobíme všechna tato čísla, dostaneme 1474560 bajtů. A tak jsem si hrál se zmenšováním počtu cylindrů a hlav, abych dostal optimální velikost disku a došel jsem k tomuto: CHS = 7 / 1 / 18 (126 sektorů) to jest 64512 bajtů. Zbývá 1 kB pro kód ROMOSu. Pro efektivní využití disku jsem zvolil 1 sektor na cluster a 16 záznamů v kořenovém adresáři. Ze 126 sektorů je první použit na bootsektor, druhý a třetí na dvě kopie FAT tabulky a čtvrtý pro kořenový adresář. Zbývá tedy 62464 bajtů (122 sektorů) pro uživatelské soubory. Abych ještě trochu zvětšil využitelné místo na disku, odstranil jsem nadbytečnou kopii FAT pomocí DISKEDITORu a opravil údaje v bootsektoru. Tak jsem získal 62976 bajtů (123 sektorů) pro uživatelská data. Nevýhodou je, že takový disk je pak čitelný pouze v novějších verzích MS-DOSu (>6.22), proto je třeba použít DOS z Win9X nebo FreeDOS. A nezapomeňte, že i když váš soubůrek je velký jen jeden bajt, tak zabere na disku celý sektor.
      Doufám, že se mi to podařilo popsat dostatečně srozumitelně. Mohl bych napsat ještě mnoho detailů (to snad necháme někam k pivu ;), ale myslím, že by se pak hlavní myšlenky ztratily v moři slov. Snad to pomohlo lidem, kteří se o tuto problematiku vážně zajímají, nováčkům asi moc ne. Ale nic si z toho nedělejte, pokud jste zde něčemu nerozuměli. Já jsem to taky nepochopil za jediný den. Sháním tyto informace už několik let z různých internetových zdrojů a stále je zde co objevovat. Moje poděkování si zaslouží vyhledávač Google, Darmawan Mappatutu Salihun - Award BIOS Reverse Engineering, Jan Steunebrink, Daemorhedron, Sunil Shrestha, Luchezar Georgiev, Eric Auer, Jakub Chalupník, komunita FreeDOS, Miroslav Němeček (MikroManažer), Datalight, Rebels Haven BIOS modding fórum.

Moderní BIOSy a jejich součásti (ME)

      Zhruba od roku 2005 se na základních deskách začaly používat malé FlashROM čipy pro BIOS se sériovou sběrnicí SPI připojené k jižnímu můstku (ICH) o kapacitě 0,5 - 2 MB, nyní (v roce 2016) běžně 8 - 16 MB. Nabízí tak spoustu místa pro další rozšíření. V případě poškození BIOSu lze tento typ pamětí snadno přeprogramovat s použitím minima součástek přes paralelní port. Často jsou osazovány varianty v pouzdru SMD, ale odpájet a připájet těch 8 nožiček zas není takový problém. Výrobce základních desek Gigabyte přišel s vylepšením Dual BIOS, které osazuje na vyšších třídách MB. Na takové desce jsou 2 stejné paměti s hlavním a záložním BIOSem. Když dojde k poškození hlavního BIOSu, měl by se automaticky aktivovat ten záložní. V případě potřeby je možno záložní BIOS aktivovat manuálně.
      Dnes v této paměti nesídlí jen kód BIOSu vykonávaný hlavním CPU tak, jak byl popsán výše, ale nezávisle na něm též firmware pro speciální pomocný mikrokontrolér, tzv. EC (Embedded Controller), příp. FW pro onboard LAN řadič. EC býval dříve samostatný čip na MB (hlavně v noteboocích), později se integroval do chipsetu (u intelu se nazývá ME - Management Engine) - severního můstku (MCH/GMCH), pak PCH a nakonec do hlavního CPU. Konkrétně v MCH intel P35 je to 32-bitový MCU ARC4, u AMD zas nějaký klon 51 nebo LatticeMico32 a nově ARM Cortex-A5 přímo v CPU. ME je aktivní i ve stand-by (trvale napájený z ATX zdroje) a v případě potřeby umí PC zapnout a vypnout. ME řeší hodně low-level věci jako power management, řízení hodin a napájení CPU, řízení větráků, může opravovat některé HW chyby v PCH, atd. - jak je popsáno zde, takže bez něj PC nemůže plnohodnotně běžet (vyjma starší generace Core 2). Hlavní CPU komunikuje s ME přes HECI (Host Embedded Controller Interface) - PCI MMIO, ke kterému intel dodává MEI (Management Engine Interface) ovladače pro Windows. S HECI ovladačem pak může komunikovat OS a aplikace. ME je součástí technologie intel vPro s nadstavbou AMT, která umožňuje vzdálenou správu PC přes VNC (zahrnuje též malý integrovaný webserver s podporou šifrování), včetně možnosti vzdálené konfigurace BIOSu, (re)instalace OS ze vzdáleného image disku, či vzdáleného zablokování a smazání dat z ukradeného PC (Anti-Theft system). Záleží, jestli máte ořezanou verzi AMT pro domácí PC (typ. 1,5 MB) nebo plnou verzi AMT (typ. 5 MB) pro korporáty. Aby fungovaly i síťové funkce, musí mít deska LAN řadič od intelu s validním GBE Regionem v SPI FlashROM (ten obsahuje např. MAC adresu a další nastavení, viz datasheet, sekce 10.0 NVM). Síťování funguje OOB (Out-Of-Band) tak, že se v LAN řadiči síťový tok rozdvojí na 2 rozhraní pro ME a pro host PC, které o přítomnosti ME neví. Obě rozhraní používají stejnou IP adresu, AMT pracuje s portem v rozsahu 16992 - 16994 (pokud je aktivní, měl by jít běžným port scannerem objevit). Praktická ukázka práce s AMT jde zde a zde.

intel ME architecture diagram

      Úroveň, na níž běží firmware v EC, byla klasifikována jako ring -3 (ring -2 je SMM režim procesoru, ring -1 je hypervisor při použití virtualizace a ring 0 je klasicky jádro OS). Zajímavou funkcí je, že EC může libovolně přistupovat do operační paměti či na PCI sběrnice a resetovat hlavní procesor. Každá takováhle úžasná BigBrotherovská funkce je zneužitelná, viz tato zajímavá prezentace: Introducing Ring -3 Rootkits. Kamarád Ruik se zabýval analýzou FW pro AMD SMU (System Management Unit) v hlavním CPU, kterou prezentoval předloni na CCC 2014. Více informací o intel ME FW se můžete dozvědět z prezentací Igora Skochinskyho zde a zde a od dalších ruských hackerů zde (video) a zde. V roce 2014 vyšla dokonce o ME celá kniha: Xiaoyu Ruan - Platform Embedded Security Technology Revealed, Safeguarding the Future of Computing with Intel Embedded Security and Management Engine.
      Nemusím asi dodávat, že ME FW je proprietární closed-source binární blob o jehož vnitřnostech toho kromě intelu nikdo moc neví, typické security by obscurity. Navíc část ME FW (bootloader, základní libC funkce, rutiny ThreadX RTOS a low-level HW drivery) je uložená přímo v ROM EC a nelze ji snadno vyčíst (možná tak odbroušením čipu). Pro testovací účely při vývoji chipsetu lze prý nějakým způsobem zavést i ROM kód z SPI FlashROM (bylo objeveno pár ME FW image z roku 2014 a 2014, které obsahovaly modul ROMB). Bootloader při nahrávání ME FW modulů (podrobnější popis částí ME blobu zde) z SPI FlashROM provádí dekompresi (LZMA/Huffman/žádná) a kontrolu digitálních RSA podpisů, takže není možné zavést neautorizovaný kód. Není známý ani slovník pro dekompresi Huffmana, který je též zadrátovaný v chipsetu. Jelikož MCU nemá dost vlastní RAM, jsou dekomprimovaná data uložena do vyhrazené části RAM hlavního CPU, kterou BIOS po POSTu zamkne proti čtení a zápisu (odemknout lze jedině resetem). Do verze ME FW 7.1 a novějších byl přidán modul DAL (Dynamic Application Loader), který umožňuje ve VM na EC spouštět digitálně podepsané Java applety ve starém formátu JEFF.
      UPDATE: objevil jsem OpenSource utilitu Unhuffme 2.4, která umí dekomprimovat Huffmanovské moduly ze starších verzí ME FW. Stačí jako parametr zadat název souboru ME blobu a utilita vytvoří adresář mod, kam rozbalí všechny ME FW moduly se spustitelným kódem ME (nikoliv datové oddíly). Moduly komprimované LZMA mají příponu .lzma a je potřeba je dále rozbalit pomocí XZ Utils. Zkusil jsem to aplikovat na svém ME FW 8.1.65.1586 blobu. Program z něj vybalil 20 modulů a v každém z nich jsem našel nějaké čitelné textové řetězce. Zkusil jsem nějaký modul načíst do IDA Pro (nutno vybrat procesor "Argonaut RISC Core ARCompact [arcmpct]" a na první pohled to vypadalo, že to něco zdisassemblovalo. Od verze 11 pro CPU Skylake se změnil slovník a zatím není znám. UPDATE: skupině ruských hackerů se podařilo slovník sestavit a dekomprimovat nový ME FW, jejich nástroj unME11 je volně k dispozici na GitHubu. A nejen to, dokonce se jim podařilo napojit se na běžící OS v ME pomocí debuggeru přes DFx (intelí implementace JTAGu), který je na nových chipsetech řady 100 tunelovaný skrze USB 3.0 proprietárním protokolem DCI (Direct Connect Interface) - stačí PC s obyčejným USB 3.0 kabelem. Tuto funkci může UEFI zamknout po dokončení POSTu, ale někteří výrobci MB ji nechávají povolenou. Taktéž úpravou UEFI FW image je možné zámek vypnout. Více info na prezentacích zde, zde a zde. To umožňuje hackerům hledat v kódu ME FW díry, které by šly využít pro vzdálený útok. Intel tvrdí, že je vše v pohodě, že útočníci nemohou spustit nepodepsaný kód. No uvidíme, s čím přijdou hackeři na prosincové konferenci BlackHat 2017 v Londýně. Mezitím také přišli na to, jak neutralizovat tuto novou verzi ME 11.x pomocí nastavení skrytého konfiguračního bitu reserve_hap, který ME přepne do omezeného minimalistického režimu. Tuto úpravu si u intelu objednala NSA pro svůj vládní program HAP (High Assurance Platform). U starších verzí ME (ověřeno na ME 8.x) byl objeven bit Alt ME Disable podobného významu. Podpora pro nastavení těchto bitů byla přidána do nové verze ME cleaneru.
UPDATE: konference Blackhat již proběhla a ruští hackeři zbořili poslední zbytky mýtů o nedobytnosti intel ME, když obešli mechanismus digitálního podpisu a runtime kontroly běžících vláken a spustili v ME vlastní kód. Tato zranitelnost se týká nového ME 11.x založeného na OS MINIX 3 x86 pro 6. - 8. generaci intel Core (Skylake, Kaby Lake a Cofee Lake) a nepomůže ani nastavení reserve_hap bitu. Pro exploitaci je však nutný lokální přístup k SPI FlashROM nebo aspoň odemčený Flash Descriptor, aby šlo ME FW přepsat.
      ME region obsahuje nejen kód, ale ukládají se tam i specifická konfigurační a provozní data. Pokud uděláte dump SPI FlashROM na 2 stejných PC se stejnou verzí ME FW, budou se některé oblasti v ME regionu lišit. Zkusil jsem na svém PC udělat 2 dumpy, mezi nimiž jsem PC vypnul a znovu nabootoval a rozdíl byl ve 102 Bytech ME regionu a 132 Bytech v oblasti BIOSu. Napadá mě zajímavá otázka, jak by se systém choval, kdyby se SPI paměť hardwarově zamkla jen pro čtení, jestli by se vůbec systém korektně spustil? Intel dodává výrobcům desek ME FW image, které mají vymazané konfigurační a provozní datové oblasti. Výrobce pak provede specifickou konfiguraci a při prvním spuštění ME FW na PC se zinicializují další datové struktury. Postup, jak tyto datové struktury z ME FW dumpu odstranit je popsán zde.
      Pokud by se v ME FW objevila nějaká zranitelnost, bude zneužitelná na velkém počtu PC a potrvá dlouho, než všichni výrobci MB vydají aktualizace BIOSů (na starší MB se vykašlou a stejně většina domácích uživatelů BIOS neaktualizuje, protože ani neví, co to je). Otázkou je, zda-li ME FW neobsahuje úmyslně nějaký backdoor (třeba pro americkou NSA), intel tvrdí, že nikoliv. Zatím nikdo analýzou síťového provozu neprokázal, že by k nějaké podezřelé komunikaci docházelo. Při výjimečném a úzce cíleném použití by asi šance na odhalení byla dost malá. Každopádně je to potenciální bezpečnostní díra. Podobné řešení IPMI pro servery se v minulosti také ukázalo býti nepříliš bezpečné. Veškeré zabezpečení OS a aplikací je k ničemu, pokud nemůžeme věřit HW a FW. Proto lidé, kteří berou bezpečnost vážně a příznivci OpenSource, se snaží vytvořit otevřené řešení bez závislosti na proprietárních binárních blobech (ať už intelu nebo AMD). Už před lety vznikla alternativní OpenSource náhrada BIOSu Coreboot / Libreboot, kterou používají např. notebooky Librem, Libreboot X220, System76, či miniPC 86Duino. Podařilo se analyzovat některé bloby, které mají za úkol inicializaci řadiče pamětí a napsat alternativní free variantu. Ukázku kompilace a instalace Corebootu na notebook Lenovo ThinkPad X230 jste mohli vidět na přednášce LinuxDays 2019. Také Goole se bojí ME a UEFI a proto začal vyvíjet pro PC do svých datacenter alternativní firmware NERF (Non-Extensible Reduced Firmware) založený na ořezaném ME FW, Corebootu či silně redukovaném UEFI a Linuxu. Nedávno Google objevil zranitelnost také v AMD PSP (Platform Security Processoru).

      1.5.2017 Jak už jsem spekuloval výše, pokud by se v ME FW objevila bezpečnostní díra, tak bude mít intel velký problém. A protože je u tak komplexního software výskyt nějaké chyby prakticky jistý, tak se také stalo a intel dnes oznámil, že vydal opravu chyby v ME FW/AMT, která umožňovala vzdáleně získat kontrolu nad PC se zapnutým AMT, více podrobností zde. Chyba je o to závažnější, že postihuje celou řadu verzí ME FW od verze 6.x (Nehalem) po 11.6.x (Kaby Lake), tedy všechny verze ME založené na architektuře ARC používané cca 9 let. Avšak týká se to pouze korporátní verze ME FW s plnou podporou AMT (5MB ME FW blob - převážně serverové desky, desktopové desky velkých výrobců pro firemní prostředí a některé notebooky), nikoliv běžných desktop desek. Intel předal opravené verze ME FW OEM, kteří jej integrují do svých BIOSů, jenže nelze čekat, že se by se podpory dočkaly i desky staré třeba 8 let. Bohužel intel nenabízí ME FW volně ke stažení, aby si mohli aktualizaci provést i zkušenější uživatelé nezávisle na výrobcích desek. Šokující na celém případu je to, že intel byl na tuto zranitelnost upozorňován už několik let, ale nijak nekonal, zřejmě se to někomu hodilo. Také nás může napadnout otázka, jestli s jednou opravenou chybou nevznikly v novém ME FW chyby další nebo dokonce pečlivěji ukrytý backdoor :)

      S intel ME FW je to kvůli silnému šifrování a kompresi složitější. Proběhla celá řada pokusů o odstranění ME FW z SPI FlashROM a dá se říci, že čím novější CPU a chipset, tím je vazba na ME silnější. Na starších platformách intel Core 2 (LGA 775) lze ME FW bez problémů úplně vyhodit. Některé chipsety jako intel P31 a P41 ještě ME ani neměly. Na platformách pro první procesory intel Core i-5/7 Nehalem lze též ME FW odstranit bez vážnějších dopadů. U novějších procesorů intel Core i-3/5/7 Sandy Bridge/Ivy Bridge se podařilo ME FW alespoň neutralizovat pomocí skriptu ME cleaner (nově podporuje i ME 11 - Skylake a od verze 1.2 také ME 12 - Coffe a Cannon Lake na chipsetech 3xx). Avšak úplně odstranit nejde, protože ROM kód v ME si hlídá přítomnost určitých struktur ME FW v SPI FlashROM a pokud je nenajde, tak běží pouze dočasně v recovery režimu a po půl hodině PC vypne. Také se tím můžou znefunkčnit funkce Turbo Boost / EIST a PC může být nestabilní. Při použití ME cleaneru by s tím být problémy neměly.
      intel ME se postupně vyvíjel a jsou známé 4 generace, které se zásadně liší. ME 1. generace (verze 1.x - 5.x) pro Core 2 (LGA 775) je založen na 32-bitovém jádře ARCTangent-A4, 2. generace (verze 6.x - 11.x) pro Core i3/5/7 je založena patrně na 16/32-bitovém jádře ARC 600 (podpora pro disassemblování ARC kódu byla přidána do IDA Pro 6.4), 3. generace, nově pojmenovaná TXE (Trusted Execution Engine, verze 1.x) pro mobilní Atomy, Celerony, Pentia a Core M Bay Trail a Broadwell je založena patrně na 32-bitovém jádře SPARC V8 a 4. generace CSE/ME 11.x, TXE 3.x, SPS 4.x (v PCH řady 100 pro CPU Skylake), kde bylo v roce 2017 objeveno, že přešla na architekturu x86 a to hned 3 jádra typu Quark (využitá pro ME, ISH - Integrated Sensors Hub a IE - Innovation Engine) a běží na upraveném operační systému MINIX 3. I pro jeho autora Andrewa S. Tanenbauma to bylo docela překvapení a tak napsal do intelu otevřený dopis. Jelikož je však MINIX šířen pod BSD licencí, nemusí intel zveřejňovat zdrojové kódy.
      Pro každou řadu chipsetů je určená pouze 1 nebo 2 major verze ME FW. Např. pro PCH 6x (Sandy Bridge/Ivy Bridge) lze použít ME FW 7.x a 8.x. Taktéž nástroje pro manipulaci s ME FW musí být odpovídající verze. MEI ovladač pro Windows může pracovat s více verzemi ME FW, např. PCH 8x a novější fungují s poslední verzí MEI 11.6, PCH 6x/7x fungují nejvýše s verzí 11.0 a pro PCH 5x a starší je potřeba dohledat odpovídající starší verzi ovladače. Struktura SPI FlashROM image:

Flash Descriptor
(GBE Region)
ME Region
BIOS Region
(Platform Data Region)

      Dále popíšu postup identifikace verze, aktualizace a kontrolu funkčnosti ME FW. Všechny potřebné nástroje, ME FW image a MEI ovladače najdete zde a zde. Jak už jsem zmínil výše, SPI FlashROM image obsahuje více nezávislých částí. Na začátku je vždy Flash Descriptor, který obsahuje offsety a velikosti dalších oblastí a také přístupová práva. Je možné, že výrobce vaší desky zamknul ME FW region a nebude ho možné aktualizovat běžnou flashovací utilitou (dovolí aktualizaci pouze oblasti BIOSu). Tento zámek v chipsetu typicky aktivuje BIOS až při bootu, takže to možná půjde přes flashovací utilitu vestavěnou v BIOSu. Pokud ne, zbývá jedině externí programátor. Na mé desce Gigabyte GA-P67-DS3-B3 je ME region odemčený a normálně šel přeprogramovat DOSovou utilitou flashspi.exe stejně jako Q-Flashem přímo z BIOSu. Podrobný popis organizace SPI paměti a Flash Descriptoru je v "tajné" dokumentaci intelu SPI Programming Guide pro PCH 5x, 6x a 7x.
      Pokud netušíte, jakou major verzi ME FW máte nebo potřebujete zjistit verzi z SPI flash image souboru či extrahovaného ME FW blobu, je dobré začít utilitou ME Analyzer, která si poradí se všemi verzemi ME FW. Např.: mea.exe p67ds_f5.bin -dfpt -skip vypíše:


File:     P67DS_F5.BIN

Name: FOVD  Owner: KRID  Offset: 0x00000400  Size: 0x00000C00
Name: MDES  Owner: MDID  Offset: 0x00001000  Size: 0x00001000
Name: FCRS  Owner: OSID  Offset: 0x00002000  Size: 0x00001000
Name: EFFS  Owner: OSID  Offset: 0x00003000  Size: 0x00034000
Name: NVCL  Owner: ----  Offset: ----------  Size: 0x000095D9
Name: NVJC  Owner: ----  Offset: ----------  Size: 0x00005000
Name: NVKR  Owner: ----  Offset: ----------  Size: 0x0000FC13
Name: NVQS  Owner: ----  Offset: ----------  Size: 0x00000DEF
Name: NVTD  Owner: ----  Offset: ----------  Size: 0x00001E44
Name: FTPR  Owner: ----  Offset: 0x00037000  Size: 0x0006A000
Name: NFTP  Owner: ----  Offset: 0x000A1000  Size: 0x000DC000

Family:   ME
Version:  7.1.20.1119
Release:  Production
Type:     Region, Extracted
FD:       Unlocked
SKU:      1.5MB
Date:     08/08/2011
Size:     0x17D000
Platform: CPT
Latest:   No

Blist 1:  <= 7.0.10.1203
Blist 2:  <= 7.1.13.1088

Z výpisu je vidět, že ME region je ve Flash Descriptoru odemčený a umožňuje tedy budoucí aktualizace. Pokud chcete zjistit informace o ME na běžícím systému, stačí spustit utilitu MEInfo.exe odpovídající verze od intelu:


Intel(R) MEInfo Version: 7.1.50.1166
Copyright(C) 2005 - 2011, Intel Corporation. All rights reserved.

GBE Region does not exist.
Intel(R) ME code versions:

BIOS Version:                           F5
MEBx Version:                           Not available
Gbe Version:                            Unknown
VendorID:                               8086
PCH Version:                            5
FW Version:                             7.1.20.1119

FW Capabilities:                        1051712

    Intel(R) Capability Licensing Service - PRESENT/ENABLED
    Intel(R) Dynamic Application Loader - PRESENT/ENABLED

CPU Upgrade State:                      Upgrade Capable
Cryptography Support:                   Disabled
Last ME reset reason:                   Power up
Local FWUpdate:                         Enabled
BIOS and GbE Config Lock:               Disabled
Host Read Access to ME:                 Enabled
Host Write Access to ME:                Enabled
SPI Flash ID #1:                        C22016
SPI Flash ID VSCC #1:                   20052005
SPI Flash BIOS VSCC:                    20052005
BIOS boot State:                        Post Boot
OEM Id:                                 00000000-0000-0000-0000-000000000000
OEM Tag:                                0x00000000

I zde vidíme, že ME region je odemčený a updatu tedy nic nebrání. Novější ME FW pro odpovídající verzi chipsetu lze stáhnout z výše zmíněného fóra v odstavci "B1. Consumer Systems". V mém případě chipsetu P67 se nabízí 2 verze: 7.1.80.1214 a 8.1.65.1586, zkusil jsem tu novější. Stažený ME FW je určený k integraci pro všechny výrobce MB a má tedy výchozí nastavení. Proto je nutné ho před vložením do SPI flash image souboru nakonfigurovat pomocí utility FIT (Flash Image Tool) odpovídající verze od intelu a nastavit všechny volby podle starší verze ME FW, kterou máte v SPI flash image souboru pro vaši desku (pokud přesně nevíte, co která volba dělá). Postup je podrobně popsán zde.

Flash Image Tool - view of ME settings

      Nejlepší je otevřít si 2 okna FITu vedle/pod sebe a proklikat všechny položky ME Regionu. Jelikož jsem přecházel na vyšší major verzi, spustil jsem si v 1. okně FIT 7.1.60.1191 v němž jsem otevřel svůj stávající SPI flash image soubor a potom jsem spustil v 2. okně FIT 8.1.40.1456, kde jsem otevřel generický ME FW blob 8.1.56.1541. Při otevření SPI flash image chce FIT zadat modelovou řadu chipsetu (vybral jsem "6 Series Chipset") a po otevření ME FW je potřeba nastavit stejný typ konkrétního chipsetu jako je stávající. V mém případě tam byl nastaven z nějakého důvodu "Z68 - Desktop", tak jsem to v novém ME FW nastavil stejně. Při otevření image souboru se automaticky vytvoří adresář stejného jména s podadresářem Decomp, v němž jsou jednotlivé regiony vykopírované do samostatných souborů. V 1. okně klikněte na "Descriptor Region|Descriptor Region Length" a zapište si někam jeho velikost. Pokud nemáte GBE Region síťovky, tak je to zároveň offset na pozici začátku starého ME FW v SPI flash image souboru, v mém případě 1000h (4096 B). V druhém okně s novým ME FW nastavte položku "Descriptor Region|Descriptor Map|Number of Flash Components" na 0, aby se následně buildoval jen ME Region. Dále je třeba si pohlídat shodná nastavení v "ME Region|Configuration|ME Debug Event Service|Event Filters", kde by položka Filter Group 1 měla mít hodnotu 0x00000001 a položka Filter Group 76 by měla mít hodnotu 0x000000FE. Jsou zde také určité závislosti položek, jako např. pro vypnutí položky "ME Region|Configuration|ME|M3 Power Rails Availability" je potřeba napřed vypnout položku "ME Region|Configuration|Power Packages|Power Pkg 2 Supported". Důležitá nastavení jsou v menu "ME Region|Configuration|ICC Data", kde bude potřeba zkopírovat řadu položek. Po důkladné kontrole pak můžete v druhém okně s ME FW vybrat v hlavním menu "Build|Build Image" a měl by se vám vytvořit adresář Build s ME FW souborem outimage.bin. Ten si přejmenujte nějak srozumitelně, abyste věděli pro jakou desku/chipset je ME FW nakonfigurovaný.

Hexa view of SPI flash image with ME region start

      Pak už jen stačí tento soubor v oblíbeném hexaeditoru nakopírovat do SPI flash image souboru na offset, kde začínal starý ME FW. Jeho začátek též poznáte podle sekvence 20 20 80 0F a 16 B od začátku bude vidět čitelný řetězec $FPT (hlavička ME FW partition tabulky). Není potřeba řešit žádný checksum a můžete upravený SPI flash image soubor rovnou flashnout. Po flashnutí je potřeba PC na chvilku vypnout, protože EC je trvale napájený a tím se vynutí nový boot ME FW. Pokud PC normálně nabootuje, spusťte znovu utilitu MEInfo.exe odpovídající verze (dle nového ME FW), zkontrolujte verzi ME FW a případný výskyt chyb. Pak spusťte utilitu MEManuf.exe od intelu, která spustí řadu interních testů ME a vypíše výsledek, který by měl být:


Intel(R) MEManuf Version: 8.1.56.1541
Copyright(C) 2005 - 2014, Intel Corporation. All rights reserved.

MEManuf Test Passed

Pro podrobnější výpisy jednotlivých testů použijte parametr -verbose. Další funkce BIOSu nesouvisející s ME si můžete otestovat utilitou BITS (BIOS Implementation Test Suite), kterou si můžete stáhnout v podobě ISO image bootovacího CD. Také můžete ve Windows aktualizovat MEI ovladače.

      22.11.2017 Na fóru win-raid jsem objevil o něco novější verzi ME FW 8.1.70.1590, kterou jsem aktualizoval svůj BIOS na desce Gigabyte GA-P67-DS3-B3. Stačilo stažený ME FW image načíst do FIT 8.1.40.1456, k tomu načíst konfigurační XML soubor, který jsem si uložil dříve pro verzi 8.1.65.1586 a zkonfigurovaný ME FW blob vložit do SPI flash image souboru. Všechny testy v MEManuf 8.1.56.1541 proběhly v pořádku.
      Dále jsem vyzkoušel novou verzi ME cleaneru, pomocí které jsem přepnul ME FW do Alt Disable Mode, v němž se provede pouze základní inicializace a další moduly ME FW, kde se můžeu potenciálně nacházet bezpečnostní díry, se nespustí. To se provede pomocí parametru -s, jenž nastaví bit 7 v PCH Strap 10 ve Flash Descriptoru (v mém případě uložený na offsetu 128h SPI flash image souboru):


me_cleaner.py -s MY_F5ME8.BIN
Full image detected
The ME/TXE region goes from 0x1000 to 0x181000
Found FPT header at 0x1010
Found 15 partition(s)
Found FTPR header: FTPR partition spans from 0x94000 to 0x109000
ME/TXE firmware version 8.1.65.1586
Setting the AltMeDisable bit in PCHSTRP10 to disable Intel ME...
Checking the FTPR RSA signature... VALID
Done! Good luck!

      Po flashnutí a power off/on cyklu takto upraveného image přestal být ME FW identifikovatelný utilitou MEInfo a MEManuf hlásí ModeOfOperation: Alt Disable Mode. ME je stále viditelné na PCI sběrnici jako zařízení 8086:1C3Ah, ale ve Windows selže spuštění MEI ovladače (ve správci zařízení je označeno vykřičníkem, avšak ničemu to nevadí). Dále je patrné, že nebyl nastaven OEM ICC (Integrated Clock Control) profil (ICC je generátor hodin v PCH, který z 25MHz krystalu generuje frekvence BCLK, PCIe, LPC, DP, atd.). Nicméně na funkce EIST, Turbo Boost a suspend to RAM to nemělo vliv, ani jiné změny v chování PC jsem nepozoroval.


Intel(R) MEManuf Version: 8.1.56.1541
Copyright(C) 2005 - 2014, Intel Corporation. All rights reserved.

FW Status Register1: 0x1E020191
FW Status Register2: 0x160A0100

  CurrentState:                         Init
  ManufacturingMode:                    Enabled
  FlashPartition:                       Valid
  OperationalState:                     Bring Up
  InitComplete:                         Initializing
  BUPLoadState:                         Success
  ErrorCode:                            No Error
  ModeOfOperation:                      Alt Disable Mode
  ICC:                                  No valid OEM data, ICC not programmed
  PhaseStatus:                          CHECK_ME_STRAP_DISABLED

Error 9256: Communication error between host application and Intel(R) ME FW

Error 9255: Internal error

Could not determine FW features information

Error 9296: MEManuf Test Failed

Intel(R) MEInfo Version: 8.1.56.1541
Copyright(C) 2005 - 2014, Intel Corporation. All rights reserved.

Error 9458: Communication error between application and Intel(R) ME module (FW Update client)
Error 9459: Internal error (Could not determine FW features information)

SMM/SMI

      Už v dávných dobách v roce 1993 byl do procesorů intel 386SL a 486 přidán speciální režim SMM (System Management Mode) připomínající Unreal mode, do nějž procesor vstupuje při SMI (System Management Interrupt), které lze aktivovat hardwarově pinem SMI# procesoru na základě signálu z chipsetu. Někdy bývá tento režim označovaný jako ring -2, protože je níže než hypervisor (ring -1) a kernel OS (ring 0). V SMM režimu se typicky řeší low-level věci kolem power managementu, obsluha HW chyb a výjimek a také je možno emulovat určité periferie pomocí I/O trapů. Je totiž možné nastavit registry v chipsetu tak, aby při přístupu na určitou I/O adresu či rozsah I/O adres bylo vygenerováno SMI. Procesor okamžitě přeruší svou činnost (pokud běží v ring > -2), uloží celý kontext na speciální zásobník a řízení je předáno SMI handleru. Jeho dispatcher musí napřed zjistit, čím bylo SMI vyvoláno (může existovat spousta původců SMI dle nastavení chipsetu, každý zdroj má svůj enable a flag bit v registrech SMI_EN a SMI_ST) a pokud zjistí, že bylo způsobeno aktivací I/O trapu na určité I/O adrese, skočí na příslušnou obslužnou rutinu. Nakonec instrukcí RSM obnoví původní kontext a vrací se zpět. Takto lze např. emulovat standardní klávesnici na portech 60h a 64h pomocí dnes běžných USB klávesnic, takže i starý OS, který nemá USB ovladače, může vesele s USB klávesnicí pracovat. Dnes lze také běžně bootovat z USB disků a flashek emulujících klasický HDD nebo FDD. AMD zas na svých procesorech Geode umí pomocí SMM modulu VSA (Virtual System Architecture) emulovat zvukovou kartu Sound Blaster 16 na AC'97 kodeku. To jsem si vyzkoušel na tenkém klientu Compaq EVO T20 a opravdu to fungovalo. SMI lze také obvykle aktivovat libovolným zápisem do I/O portu B2h (APM Control Port).
      Obsluha SMI by měla trvat jen pár µs či méně, takže běžící OS by neměl nic poznat. Praxe je ale bohužel taková, že některé prasácké implementace SMI handleru při práci s USB způsobují latence i stovky µs, což může způsobit vážné problémy u Real-time systémů. Někdy pomůže v SETUPu povypínat všechny USB legacy podpory a pak se latence výrazně zkrátí. Taktéž bývají v SMI handlerech chyby, které třeba při použití emulace klávesnice přes USB způsobí zatuhnutí či pád nějaké aplikace, která přitom s nativní PS/2 (DIN) klávesnicí normálně funguje. Proto dávám přednost připojení myši a klávesnice nativním rozhraním před USB. U své nové desky Gigabyte GA-P67-DS3-B3 jsem si musel druhý PS/2 port trochu vybojovat.
      SMI handler je uložený ve FlashROM jako součást BIOSu a nemá žádný separátní modul, s kterým by bylo možno pracovat třeba pomocí CBROMu či MMToolu. Ale neměl by být šifrovaný, takže modifikovat se dá. BIOS během POSTu nahraje SMI handler do speciální vyhrazené oblasti operační paměti SMRAM, která obvykle sídlí na adrese SMBASE: A0000h nebo 30000h. Na adresy SMBASE+7E00h - 7FFFh se ukládá kontext a z adresy SMBASE+8000h se spouští SMI handler. SMRAM se na dané adresy dynamicky mapuje při vstupu do SMM (zajišťuje hardwarově chipset - MCH), jinak adresy A0000h - BFFFFh používá běžně VGA jako videopaměť. Taktéž adresu SMBASE (MSR 9Eh) je možné měnit pouze v SMM režimu (při pokusu o čtení/zápis MSR 9Eh mimo SMM režim vyhodí výjimku GPF). Přístup k paměti SMRAM zamkne BIOS po POSTu nastavením bitu D_LCK v registru SMRAM v MCH chipsetu, který se odemkne jedině resetem. Dříve ale některé BIOSy SMRAM nezamykaly a bylo tak možné SMRAM přečíst a modifikovat. Později se ukázalo, že i v případě nastaveného bitu D_LCK lze SMRAM modifikovat útokem přes cache (pokud ji SMI handler při návratu neflushne, což běžně nedělá), kdy se modifikuje hodnota SMBASE v uloženém kontextu cachované SMRAM tak, aby ukazovala na jinou adresu s podvrženým SMI handlerem mimo ochranu MCH. Tato díra byla patrně zavřena s příchodem nové architektury core Nehalem, který integruje MCH do CPU.
      SMI handler je docela zajímavým cílem útoku různé havěti a šmíráků (viz některé exploity NSA), kde se můžou snadno schovávat před antiviry a vesele zasahovat do běhu OS. Generování SMI je možné konfigurací chipsetu nastavit i při čtení SPI FlashROM, takže rootkit může přečtená data modifikovat a skrýt tak svoji přítomnost v BIOSu, jak bylo zmíněno zde. Další zajímavé čtení na toto téma najdete v článku: A Real SMM Rootkit: Reversing and Hooking BIOS SMI Handlers. Napsal jsem si jednoduchý program SMINFO, který vypíše pár zajímavých informací o SMM/SMI a umožňuje uložit obsah SMRAM do souboru (není-li zamčená).
      Koncem roku 2020 se na Phoronixu objevila informace, že intel a Micro$oft spolupracují na vývoji nového standardu PRM (Platform Runtime Mechanism) v rámci UEFI a ACPI, který by měl přenést většinu kódu SMI handleru běžícím v SMM do kontextu operačního systému a byl by tak více pod kontrolou a v SMM by měla zůstat jen nezbytná část kódu, která skutečně potřebuje běžet s úrovní oprávnění SMM. V současnosti je už WIP podpora pro Windows Insider buildy a počítá se i s Linuxem. K dispozici by měla být OpenSource implementace PRM infrastruktury a ukázkových modulů v TianoCore EDK. Finální standard by mohl být v roce 2021.

UEFI (Unified Extensible Firmware Interface)

      Intel začal vyvíjet proprietární EFI pro svoje nové 64-bitové procesory Itanium (architektura IA-64, nekompatabilní s x86) coby náhradu klasického BIOSu už v 90. letech. V roce 2005 si přestal hrát na svém písečku a připojil se ke skupině Unified EFI Forum, která pak vydala první specifikaci UEFI 2.0 v roce 2006. Apple po přechodu na x86 v roce 2006 zůstalo u EFI do kterého později přidalo některé funkce UEFI, ale není s ním plně kompatabilní.
      UEFI je zcela nový koncept firmware, který nemá s klasickým BIOSem nic moc společného. Nepoužívá reálný mód procesoru, ale hned startuje do 32 nebo 64-bitového režimu. Architektura UEFI je mnohem komplexnější. Zahrnuje specifické ovladače pro HW, boot služby a runtime služby (ty může za běhu používat OS), podporu souborového systému FAT, UEFI Shell, boot manager, Secure Boot, který už byl obejit a další. Je možno vytvářet vlastní UEFI aplikace využívající UEFI služby, které mohou být uložené ve FlashROM nebo načítané z FAT oddílu HDD či jiných médií. Kvůli kompatabilitě se staršími OS, které neznají UEFI runtime služby, se běžně přidává CSM (Compatibility Support Module) emulující runtime služby klasického BIOSu. Bohužel se intel rozhodl, že od roku 2020 přestane CSM podporovat, tak doufám, že alespoň u konzervativních výrobců MB jako Gigabyte či ASRock vydrží podpora co nejdéle, příp. by měl jít zkompilovat OpenSource SeaBIOS jako UEFI modul. Uživatel Tkchia vytvořil pokusný OpenSource projekt biEFIrcate, který se snaží přidat podporu bootování 16-bitových legacy OS na UEFI systémech bez CSM. Ke své funkci však potřebuje VGA legacy BIOS. Vyzkoušel jsem to na pracovním notebooku HP ZBook Fury s 11. generací Core, který je už kompletně legacy-free (class 3 bez CSM) a biEFIrcate se mi nepodařilo nastartovat právě kvůli chybějící podpoře VGA BIOSu. U dedikovaných grafických karet (v současnosti i např. nVidia RTX 4090) zatím výrobci dodávají hybridní firmware, který obsahuje jak PCI VGA legacy BIOS, tak UEFI firmware s GOP driverem.
      V roce 2023 intel přichází s návrhem nové platformy x86-S (S jako simplified, plná specifikace zde), která se má zbavit 16 a 32-bitového režimu a dalších legacy funkcí přímo z CPU. Je to celkem logický krok po zavedení 64-bitového UEFI, kdy už CPU startuje 64-bitový OS v 64-bitovém režimu. Snad by měla být zachována alespoň podpora 32-bitového režimu pro virtualizaci s odpovídající podporou hypervisoru. Zatím není jasná finální podoba tohoto řešení ani časový horizont, kdy by ho měl intel zavést, ale předpokládám, že pro embedded segment by mohla zůstat alespoň nějaká varianta Atomu s legacy x86 architekturou.
      UEFI standardně bootuje z disků s novým typem tabulky rozdělení GPT (GUID Partition Table), která umožňuje detailnější definici více oddílů a prolamuje 2TB limit velikosti oddílu. Avšak není to jen výsada UEFI, i klasický BIOS může implementovat zavádění OS z disku s GPT. UEFI 2.5 přináší standardizované rozhraní pro flashování FW, které bude použitelné i pod Linuxem. Zde je shrnutí různých tříd platforem podle stupně přechodu od BIOSu k čistému UEFI:

class 0 Klasický (legacy) BIOS s podporou služeb INT 10h a MBR bootem.
class 1 První implementace EFI/UEFI s CSM na vrchu, který emuloval klasický BIOS a podporoval tak pouze legacy OS, zvenku se neliší od třídy 0.
class 2 Pokročilá implementace UEFI s volitelně zapínatelným CSM, umožňuje tak bootovat jak legacy OS přes MBR, tak UEFI OS/aplikace s podporou GPT.
class 3 Pokročilá implementace UEFI bez CSM, neumožňuje bootovat legacy OS neboť nepodporuje služby BIOSu, lze bootovat pouze UEFI OS/aplikace s podporou GPT. Např. v práci jsem vyfasoval nový HP ZBook s intel Core i7 11. generace, který je bohužel této třídy.

      Existuje více implementací UEFI, ta od intelu se jmenuje Tianocore a zdrojáky jsou k dispozici na GitHubu. To je ovšem pouze vyšší vrstva, pod níž je proprietární inicializační kód HW od intelu. Bez těchto binárních blobů by UEFI nemohlo nabootovat. Částečně tento problém řeší Coreboot, který může spouštět Tianocore jako payload místo SeaBIOSu. Existují i další implementace UEFI, jako např. Aptio od AMI nebo InsydeH2O od insyde. Pro své nedostatky v designu je UEFI občas terčem kritiky různých linuxáků.
      Bohužel se najdou výrobci, jako nedávno firma LeHovno, která UEFI/ACPI zneužila pro instalaci vlastního perzistentního rootkitu či mallware, které zákazník nemůže z koupeného PC jednoduše odstranit. Lenovo už dříve čelilo kritice kvůli svému addware Superfish, který byl integrovaný do OS a pomocí instalace vlastní CA odposlouchával šifrovanou komunikaci některých webových prohlížečů pro reklamní účely a kvůli bezpečnostnímu spyware Computrace. To jim ale nestačilo, tak vytvořili rootkit LSE, jenž využívá modifikace ACPI tabulky WPBT (Windows Platform Binary Table) k tomu, že před bootem Windows automaticky kontroluje na disku soubor C:\Windows\system32\autochk.exe, jestli je to modifikovaná verze od Lenova nebo originální verze od Micro$oftu a v případě, že najde originální M$ verzi, tak ji hned přepíše vlastní Lenovo verzí z FLashROM. Tento program pak kontroluje přítomnost (a případné automatické doinstalování) dalších souborů LenovoUpdate.exe a LenovoCheck.exe, které samy komunikují po Internetu, stahují a instalují ovladače a odesílají kdo ví co... Tzn. že i čistá instalace Windows je při prvním bootu ihned infikovaná tímto mallwarem. nutno podotknout, že k tomu významně dopomohl i Micro$oft, který prosadil WPBT v dobré víře, že ji budou výrobci využívat k instalaci důležitých specifických ovladačů a pod. Po té, co se tohle svinstvo provalilo, následovala vlna negativních reakcí uživatelů a Lenovo bylo donuceno vydat nástroj Lenovo Service Engine (LSE) Disabler Tool k vypnutí této funkce a do nových PC už LSE nedává. A to je jenom začátek, nechci ani domýšlet, kde budou podobné technologie za 10 či 20 let (zejména ve spojení s IoT)...
      Zatím nemám k dispozici žádný PC s UEFI na pokusy, takže nemám ani žádné zkušenosti s modifikací UEFI image. Ale neměl by to být problém. Zde je popis formátu UEFI Capsule a zde jsou potřebné nástroje: UEFITool, UBU (UEFI BIOS Updater) a UEFI repair FTK. UEFI se skládá ze stovek malých modulů s jednoznačným identifikátorem GUID. Např. modul s mikrokódy má GUID: 17088572-377F-44EF-8F4E-B09FFF46A070 a můžeme ho snadno vyextrahovat UEFIToolem nebo si rozbalit celou strukturu modulů na disk pomocí UEFIExtractu.
      19.11.2018 Obecně s tím, jak se moderní technologie komplikují, přibývá chyb a potenciálních zranitelností, tak se také objevil první virus, resp. rootkit pro UEFI pojmenovaný LoJax pocházející od hackerské skupiny Sednit na který upozornila firma ESET. LoJax je schopný přes různé díry zapsat do SPI FlashROM svůj perzistentní kód jako UEFI modul, který se pak spustí při každém bootu, tím získá nad PC kontrolu a zároveň je obtížně detekovatelný a odstranitelný. O zranitelnosti UEFI se vědělo již dříve, např. možnost exploitovat UEFI boot script table. Tato tabulka obsahuje pseudokód vytvořený během bootu sloužící k uložení stavu hardwaru pro případ přechodu do režimu spánku ACPI S3 a následného probuzení, kdy je pseudokód interpretován a provede obnovení původního stavu HW. Útočník může v paměti tento pseudokód pozměnit a následně vynutit přechod do režimu spánku a pomocí RTC se zas za pár vteřin probudit. Tento typ útoku však funguje jen na konkrétní typ HW/FW o kterém si napřed útočník zjistil podrobnosti disassemblováním FW. Koncem roku 2021 objevila firma Kaspersky další, patrně čínský, UEFI rootkit MoonBounce schopný infikovat SPI FlashROM.

Jak vyzrát na UEFI Secure Boot

      Celá řada PC s UEFI má dnes aktivní Secure Boot, který komplikuje spouštění neMicro$oftích OS a bootloaderů, např. při potřebě spustit z USB flash nějaké diagnostické nástroje. Dříve banalita se dnes změnila v onanii s certifikáty a hashi. Naštěstí existuje řešení, jak si to zjednodušit, aniž by bylo nutné Secure Boot vypnout (což vyžaduje změnu v SETUPu, která není vždy možná / povolená). Linux Foundation vydala PreLoader podepsaný Micro$oftem, který umožňuje načíst libovolný další UEFI modul pojmenovaný jako loader.efi. Při prvním spuštění takového modulu je třeba nejprve spočítat jeho hash (to zařídí modul HashTool) a uložit ho do databáze v NVRAM. UEFI standardně při bootu z paměťového média načítá a spouští modul \EFI\BOOT\bootX64.efi, Takže stažený PreLoader.efi je třeba přejmenovat na bootX64.efi a umístit do daného adresáře spolu s HashTool.efi a uživatelským loader.efi. Takto ale nelze jednoduše bootovat více UEFI modulů.
      Naštěstí je tu elegantní toolkit Super UEFIinSecureBoot Disk, který obsahuje podepsaný 2-stage preloader a známý bootloader GRUB2, kterým lze bez omezení zavádět další nepodepsané UEFI moduly a operační systémy. Jako první se zavede modul bootx64.efi, tzv. shim, který je podepsaný Micro$oftím klíčem. Ten při prvním bootu na daném PC spustí modul MokManager.efi, kterým je třeba ručně naimportovat do databáze certifikát ze souboru ENROLL_THIS_KEY_IN_MOKMANAGER.cer (umožňuje k němu vybrat cestu). Dále pak zavede preloader grubx64.efi, který nainstaluje allow-all UEFI security policy, což umožní spouštění dalších UEFI modulů i mimo GRUB2, např. z UEFI Shellu a dále zavede samotný GRUB2 modul grubx64_real.efi. Jeho konfigurace je v souboru \EFI\GRUB\grub.cfg. Aby to nebylo všechno tak růžové, je třeba upozornit na to, že UEFI se zapnutým Secure Bootem kontroluje blacklist databázi (DBX) nechtěných modulů. Do této databáze můžou zapisovat i Windows 10 při automatických aktualizacích, takže Micro$oft má tu moc kdykoliv takovýto shim/preloader zabít.


FAQ, poznámky pod čarou

Q: Proč nefunguje ROMOS v PC emulátoru BOCHS?
A: Je to způsobeno tím, že BOCHS (resp. jeho BIOS) nepodporuje ROM shadowing (kopírování obsahu ROM do RAM) a oblast ROM, kam si ROMOS při startu ukládá původní vektor INT 13h, INT 19h a SS:SP, je přístupná pouze pro čtení. Při obnově SS:SP či volání starých vektorů tedy dojde ke skoku na neplatnou adresu a fatální chybě. Není problém tyto důležitá data uložit do oblasti RAM (00000 - 9FFFFh), ale nevím jakou pro ně vybrat bezpečnou adresu, aby je následně nahraný operační systém, ovladače nebo aplikace nepřemazaly.
Nově od verze 0.97 bylo změněno ukládání těchto dat na volná místa v tabulce vektorů přerušení a tím padla nutnost zapisovat do ROM segmentu. Nyní ROMOS funguje v emulátoru BOCHS.

Q: Je možno zvětšit kapacitu ROM disku na více než 62 kB?
A: Možné to je. Celkem jednoduše by se dalo [EDIT:] nedalo získat dalších 32 kB rozdělením image ROM disku na dvě části s využitím prázdné ROM díry na adrese B0000 - B7FFFh. S tím počítám v další verzi ROMOSu. Další zvětšování by bylo asi možné jen tím způsobem, že by ROMOS při startu nahrál image ROM disku (složený z několika ROM modulů-kvůli omezení max. 64 kB / modul) někam na vyšší adresy nad 1 MB a pak by právě potřebné sektory stránkoval v okně na nižších adresách pod 1 MB. To by ale vyžadovalo progamování v chráněném módu a s tím nemám v assembleru žádné zkušenosti. Otázka je, zdali by se to vůbec vyplatilo, protože stejně zůstáváme omezeni relativně malým volným prostorem ve FlashROM. Pro náročnější aplikace je vhodnější použít např. paměťovou kartu CompactFlash s redukcí na IDE.

Q: Lze tedy použít adresy B0000 - B7FFFh nebo ne?
A: Bohužel jsem zjistil že nikoliv! Když jsem nahrál prázdnou 4kB ROM (jedinou instrukcí bylo RETF) na adresu B000:0000h (zkoušel jsem i B400h), tak při POSTu PC zatuhlo a musel jsem provést hotflash. Takže jediný použitelný rozsah je D0000 - DFFFFh (64 kB), nic víc.



rayer^seznam*cz

zpět na hlavní stránku

aktualizováno 21.2.2024 v 6:03