Mikrojádro a monolitický operační systém

Od rozhodnutí, jak moc pokročilé funkce bude umět samotné jádro, se odvíjí další postup při návrhu a implementaci. Existují dvě základní možnosti, jak se rozhodnout – buď bude jádro umět minimum, nebo naopak skoro všechno. Obě varianty mají svá pro a proti a výsledný operační systém většinou leží někde mezi těmito možnostmi – samotné jádro disponuje pokročilými funkcemi, ale některé vlastnosti jsou stále implementovány prostřednictvím aplikací uživatelského režimu.

Jak již název napovídá, systémy založené na mikrojádru (mikrokernel), obsahují velmi malé jádro, které implementuje pouze některé základní mechanismy jako virtuální paměť, plánování vláken, obsluhu výjimek a posílání zpráv mezi procesy. Ostatní komponenty (souborové systémy, síťová komunikace, správce procesů) běží v uživatelském režimu jako aplikace.

Mezi výhody architektury založené na mikrojádru patří vyšší stabilita a menší nároky na programátorské schopnosti vývojářů systému. Protože většina součástí běží v uživatelském režimu, selhání jedné z nich nemusí znamenat pád celého systému – například není možné narušit integritu jádra nechtěným přepsáním jeho datových struktur v ovladači souborového systému. Při případné chybě v součásti systému často stačí příslušnou komponentu restartovat a systém může pokračovat ve své činnosti. Malé jádro tedy znamená méně kritického kódu (kódu, který může způsobit selhání celého systému), čímž se zjednodušuje programování celého projektu.

Schéma operačního systému založeného na mikrojádru

mikrokernel

Mikrojádro v podstatě slouží jenom k plánování vláken a k předávání zpráv mezi procesy, reprezentujícími jednotlivé součásti systému. Protože jsou všechny pokročilé funkce implementovány v uživatelském režimu, ke komunikaci mezi procesy dochází velmi často, což vede k velkému počtu přechodů mezi uživatelským režimem a režimem jádra a k častým změnám virtuálního adresového prostoru. Obě tyto operace, zvláště pak ta druhá, jsou náročnější na výkon procesoru. Z tohoto důvodu mohou být systémy založené na mikrojádru pomalejší než systémy monolitické, ačkoliv architektura malého jádra je z teoretického pohledu mnohem čistší a elegantnější.

Monolitické operační systémy jsou přesným opakem mikrokernelů. Disponují velkým jádrem obsahujícím většinu komponent nutných pro běh celého systému – souborové systémy, správu procesů, síťovou komunikaci či bezpečnostní model. Obvykle všechny komponenty jádra sdílejí jeden virtuální adresový prostor, což zrychluje jejich vzájemnou komunikaci, ale na druhou stranu správce procesů například může nechtěně poškodit datové struktury nutné pro správné fungování ovladače souborového systému, což zcela určitě povede k pádu celého systému. Velké jádro tedy s sebou přináší teoreticky nižší stabilitu a bezpečnost, ale vyšší výkon. Větší množství kritického kódu zvyšuje obtížnost implementace celého projektu.

Schéma architektury monolitického operačního systému

monoliticky kernel

Windows NT a jeho součásti

Operační systémy rodiny Windows NT patří spíše do druhé skupiny. Schéma jejich architektury najdete na obrázku 2.3. Většina pokročilých funkcí (souborové systémy, síťová komunikace, správa paměti a procesů) běží v režimu jádra. Systém pro svoji plnohodnotnou činnost vyžaduje běh pouze několika málo procesů, které zajišťují správu služeb či dovolují přihlášení uživatele přes grafické rozhraní. Všechny součásti jádra a ovladače zařízení sdílí stejný virtuální adresový prostor.

windows nt

Vrstva abstrakce hardwaru (Hardware Abstraction Layer — HAL)

Windows jsou psány tak, aby nebylo obtížné upravit celý systém pro běh na dalších platformách – například na nových procesorech či základních deskách. Přenositelnost patří mezi důvody, proč je celé jádro naprogramováno převážně v jazyce C, kterému někteří přezdívají „přenositelný Assembler“. Pouze velmi malou část kódu psali vývojáři v Assembleru, jazyku striktně závislém na konkrétním procesoru či rodině procesorů. Pro přenesení Windows na novu architekturu tedy stačí přepsat některé části jádra a systémových knihoven DLL, které zapouzdřují mechanismy, jejichž implementace závisí na konkrétním druhu procesoru (přepínání kontextu vláken, obsluha stránkovacích tabulek, systémová volání). Jedním z cílů při navrhování nového operačního systému bezesporu je usnadnit programátorům psaní aplikací a ovladačů. Programátoři běžných aplikací by například neměli řešit odlišnosti různých typů procesorů. To platí i o většině ovladačů jádra. Z tohoto důvodu se architektura Windows dělí do několika vrstev. Každá vrstva v sobě skrývá některé specifické vlastnosti a problémy a vrstvám vyšší úrovně poskytuje obecná rozhraní. HAL se v architektuře Windows nachází na nejnižší úrovni a jejím úkolem je odstínit ostatní části operačního systému a aplikace od specifik hardware, jako jsou různé modely procesorů. Odtud také pochází název Vrstva abstrakce hardware (Hardware Abstraction Layer). Vyšším vrstvám poskytuje například rutiny pro komunikaci s periferními zařízeními. Kód HAL se nachází v souboru hal.dll v systémovém adresáři.

Tvrdé jádro

Nad HAL se nachází tenká vrstva, jež implementuje relativně jednoduché mechanismy, kterých vyu- žívají vyšší vrstvy jádra operačního systému pro stavbu složitějších struktur. Kód tvrdého jádra je po- mocí vrstvy HAL odstíněn od většiny specifik hardware, a tudíž zde Assembleru najdete jen málo. Mezi mechanismy implementované v této součásti patří:

  • Algoritmus plánování vláken na procesoru.

  • Odložené volání procedur (Deferred Procedure Call – DPC).

  • Základní synchronizační primitiva jako událost (event), spinlock, semafor či pushlock.

  • Práce s hardwarovými přerušeními.

  • Část obsluhy systémových volání.

Ovladače

Ovladače umožňují správci vstupně/výstupních zařízení, který spolu s dalšími komponentami tvoří vrstvu v této knize označovanou jako exekutiva, komunikovat s různými typy hardware. Jedná se o spustitelné soubory formátu PE a jejich jméno většinou obsahuje koncovku .sys.

Exekutiva

Exekutiva využívá tvrdého jádra k realizaci mnohem složitějších mechanismů, kterých mohou přes systémová volání nepřímo využívat obyčejné aplikace běžící v uživatelském režimu. Obsahuje ještě méně platformně specifického kódu než tvrdé jádro. Exekutiva se skládá z několika navzájem oddělených částí (viz obrázek). Ačkoliv se všechny nachází ve stejném adresovém prostoru, a tudíž by například správce objektů mohl přímo manipulovat s interními datovými strukturami, které náleží správci paměti, komunikují spolu pomocí přesně definovaných rozhraní. Každá komponenta dává k dispozici sadu rutin, které může volat libovolný kód běžící v režimu jádra. Názvy některých funkcí a způsob realizace některých mechanismů připomínají techniky používané v objektově orientovaném programování.

Správce objektů (Object Manager) umožňuje vývojářům psát kód jádra podobně, jako by programovali v jazyce podporujícím konstrukty OOP. Správce objektů například umožňuje jednotným způsobem objekty (otevřené soubory, klíče registru, paměťově mapované soubory)vytvářet a odstraňovat a obsahuje jednotný mechanismus řízení přístupu. Zjednodušeně lze říci, že správce objektů v sobě zapouzdřuje všechny principy, které platí pro většinu druhů objektů (při odstraňování objektu dochází k uvolnění paměti nezávisle na jeho typu, při vytváření nového objektu zase dochází k alokaci paměti, ať už se jedná o otevřený soubor, nebo klíč registru).

Správce paměti (Memory Manager) se stará o všechny činnosti, které nějak souvisí s virtuální a fyzickou pamětí. Přiděluje volné rámce fyzické paměti, zajišťuje správné mapování mezi virtuálními a fyzickými adresami a obsluhuje výpadky stránky. Vyřizování požadavků na přidělování a uvolňování bloků virtuální paměti o proměnlivé velikosti patří též do jeho kompetencí. Dále obsahuje bezpečnostní mechanismy jako ASLR (Address Space Layout Randomization).

Správce vstupně/výstupních zařízení (I/O Manager) zajišťuje většinu funkcí kolem ovladačů jádra a zařízení, ať už fyzických nebo virtuálních. Díky této součástí může jádro za běhu načítat nové ovladače do svého paměťového prostoru a uvolňovat ty, které aktuálně nepotřebuje. Správce vstupně/výstupních zařízení též dovoluje ovladačům komunikovat mezi sebou. Komunikace probíhá přes objekty zvané zařízení (device), které si pro jednoduchost můžete představit jako kanály nebo roury mezi jednotlivými ovladači.

Správce procesů (Process Manager) má na starosti spouštění, běh a ukončení procesů a vláken. Umožňuje ostatním součástem systému a běžným aplikacím zjistit informace o právě běžících procesech, měnit jejich prioritu, násilně je ukončovat a provádět další zajímavé akce.

Windows patří mezi operační systémy, jejichž cílem je plnit co největší množství různorodých úkolů a přizpůsobit své chování co nejvíce požadavkům uživatele. Nastavení různých aspektů systému musí být někde uloženo a systém k němu musí mít snadný přístup. A způsob ukládání a práce s konfiguracemi je parketa pro součást exekutivy s názvem správce konfigurací (Configuration Manager).

Na rozdíl od operačních systémů založených na Unixu, které většinu nastavení ukládají do textových souborů, Windows své konfigurace ukládá v binární podobě – do tzv. registru. Registr funguje jako malá databáze, rychle se v něm vyhledává a manipuluje s jednotlivými položkami. Na rozdíl od textových souborů, dobře čitelných pro obyčejného člověka, pro prohlížení obsahu registru potřebujete speciální programy. Jedním z nich je Editor registru (regedit.exe), který vidíte na obrázku.

Vývojáři Windows se pro binární formu ukládání konfigurací rozhodli pravděpodobně z tohodůvodu, že textové soubory se hůře a pomaleji počítačově zpracovávají a zabírají více místa. Logická struktura registru je téměř totožná s adresářovou strukturou na pevném disku. Adresáře se v této terminologii registru nazývají klíče a souborům se říká hodnoty. Každý klíč může obsahovat libovolné množství dalších klíčů (podadresářů) a hodnot (souborů). Pouze hodnoty mohou obsahovat data.

Editor registru regedit.exe

regedit1

V dřevních dobách operačního systému MS–DOS a v raných verzích Windows se pro ukládání nastavení používaly soubory s příponou .ini . Každý takový soubor se skládá ze sekcí. Každá sekce může obsahovat záznamy. Tvar záznamu vypadá následovně:
<název_položky>=<hodnota

Operační systém také musí zajistit, aby každý mohl provádět jen operace, na které má dostatečná oprávnění. To je úkolem bezpečnostního modelu (security model), který umožňuje pro každého uživatele nastavit, jaké činnosti smí a nesmí provádět. Díky bezpečnostnímu modelu může administrátor systému určit, k jakým objektům mají jednotliví uživatelé přístup. Množina objektů přitom není omezena jenom na soubory a klíče registru; oprávnění lze nastavit i u procesů, vláken, nebo třeba synchronizačních primitiv. Bezpečnostní model Windows dále definuje sadu oprávnění, které uživatel potřebuje, aby mohl vykonávat určitou činnost. Do této kategorie patří například oprávnění vytvořit stránkovací soubor či povolení načíst ovladač do jádra.

Celá exekutiva je implementována v hlavním modulu jádra (ntoskrnl.exe nebo ntkrnlpa.exe). Tento soubor formátu PE exportuje velké množství funkcí. Jejich názvy mají pevně danou strukturu. Jméno se skládá z předpony, která určuje, do jaké kategorie rutina patří, a několika slov, jež popisují její účel. Příklady vidíte v tabulce

Tabulka 1. Rutiny executivy
Předpona Příklady názvů rutin Popis

Cm

CmRegisterCallback, CmRegisterCallbackEx

Rutiny patří k rozhraní, které ovladačům umožňuje monitorovat operace nad registrem. O tuto funkci se stará správce konfigurací.

Ex

ExAllocatePoolWithTag, ExFreePoolWithTag

Rutiny různého druhu, které exekutiva poskytuje ostatním. Některé slouží pro alokaci a uvolňování paměti, jiné třeba pro synchronizaci.

Ke

KeAcquireSpinLock, KeDelayExecutionThread

Poskytované komponentou Tvrdé jádro. Určené pro práci s vlákny, obsluhu přerušení a výjimek a synchronizaci.

Rtl

RtlInitUnicodeString, RtlCopyMemory

Různé pomocné funkce pro práci s řetězci, bloky paměti a dalšími datovými strukturami.

Mm

MmProbeAndLockPages

Rutiny exportované správcem paměti.

Nt

NtCreateEvent, NtOpenProcess, NtClose, NtShutdownSystem, NtTerminateProcess

Tyto funkce mohou být volané z uživatelského režimu přes mechanismus systémových volání. Rutiny jádra s jinou předponou obyčejné aplikace volat nemohou.

Ob

ObReferenceObjectByName, ObDereferenceObject

Rutiny správce objektů.

Ps

PsTerminateSystemThread, PsCreateSystemThread

Exportováno správcem procesů.

Se

SeAccessCheck

Umožňují využít funkcí bezpečnostního modelu.

Zw

ZwClose, ZwCreateKey, ZwMapViewOfSection

Význam je téměř ekvivalentní rutinám s předponou Nt. Na rozdíl od nich jsou však Zw funkce určeny pro volání pouze z režimu jádra.

Subsystémy

Tabulka 1. ukazuje, že některé rutiny exekutivy jsou přes mechanismus systémových volání a nízkoúrovňovou knihovnu ntdll.dll přístupné i obyčejným programům běžícím v uživatelském režimu. Drtivá většina rutin exportovaných touto knihovnou DLL však není oficiálně dokumentovaná, a tudíž by je programátoři neměli používat, pokud nutně nemusejí. Tyto nativní funkce se totiž mohou měnit v závislosti na verzi Windows.

Nad ntdll.dll se nachází vrstva knihoven, která tvoří součást prostředí pro obyčejné aplikace – tzv. subsystému. Rozhraní exportované touto vrstvou je již dobře dokumentováno, což znamená, že i v budoucích verzích Windows bude pravděpodobně fungovat stejně a maximálně jej Microsoft rozšíří. Vývojáři jej mohou používat ve svých aplikacích. Windows obsahuje dva subsystémy – Windows a POSIX. Každý z nich dává programátorům aplikací k dispozici trochu odlišnou množinu funkcí obsažených v ntdll.dll. Například POSIX umožňuje vytvářet nové procesy pomocí rutiny fork , dobře známé z prostředí Unixu. Subsystém Windows takový způsob vytváření procesů neposkytuje. Nutnost implementovat POSIX také donutila vývojáře zavést do souborového systému NTFS hardlinky.

Subsystém POSIX, Windows Subsystem for Linux

POSIX je zkratka z anglického sousloví portable operating system interface based on Unix (přenositelná systémová rozhraní založená na Unixu) a označuje sadu mezinárodních standardů, které popisují aplikační rozhraní v operačních systémech založených na Unixu. Pokud by výrobci operačních systémů tyto standardy implementovali, rozhraní různých operačních systémů by byla definována stejně a stejně by se také chovala, což by ušetřilo práci programátorům aplikací, kteří by neměli tolik problémů s přenositelností na jiné platformy.

Z historických důvodů Windows původně ze všech těchto standardů implementovaly pouze POSIX 1. Windows Vista a Windows Server 2008 s sebou přináší implementaci standardů POSIX v podobně SUA (Subsystem for Unix–based Application – subsystém pro aplikace založené na operačním systému Unix). Tato rozšířená varianta subsystému POSIX implementuje kolem 2 000 funkcí různých unixových aplikačních rozhraní a obsahuje kolem tří set unixových programů. Subsystém SUA je dostupný na Windows Server 2008 a v Ultimate a Enterprise edicích Windows Vista.

Na rozdíl od subsystému Windows, bez kterého celý operační systém nemůže fungovat, POSIX se spouští jenom tehdy, pokud si uživatel přeje spustit proces určený pro tento subsystém. Konfigurace obou subsystémů je uložena v registru pod klíčem
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems

Na Windows 10 byl POSIX nahrazen Windows Subsystem for Linux (WSL). Vzhledem k tomu že Linux je OS POSIX kompatibilní, je možné očekávat, že zde rozhraní POSIX bude implementováno.

Windows 10 bez subsystému POSIX

regedit2

Z obrázku je patrné, že hlavním procesem subsystému POSIX je psxss.exe , který se nachází v systémovém adresáři. Také vidíte, že hlavní proces subsystému Windows nese název csrss.exe a že subsystémy mají i komponentu běžící v režimu jádra. Jedná se o ovladač win32k.sys , který se stará o správu grafického uživatelského rozhraní a grafiky vůbec.

Na tomto místě může vyvstat otázka, proč každý subsystém nemá svůj vlastní ovladač jádra. Důvodem je vysoká duplicita kódu. Vývojáři Windows se rozhodli tomuto nebezpečí předejít, a proto subsystém POSIX využívá funkcí (a knihoven DLL) poskytovaných subsystémem Win- dows včetně ovladače win32k.sys. Situaci znázorňuje obrázek 2.7. Kdyby tomu tak nebylo, musely by existovat dvě sady knihoven DLL a dva různé ovladače pro obsluhu grafického uživatelského rozhraní. Kód obou sad knihoven a ovladačů by však byl na mnoha místech totožný, což je v programování nežádoucí, protože dochází ke zvýšení rizika vzniku chyb.

Subsystém Windows

Struktura subsystému Windows je složitější než v případě POSIXu. Skládá se z následujících komponent: * Hlavní proces subsystému csrss.exe a knihovny DLL, které používá. * Ovladač jádra win32k.sys a drivery grafické karty a videa. * Vrstva knihoven DLL zajišťující překlad volání dokumentovaných funkcí Windows API na volání nativních (a často nedokumentovaných) rutin z knihovny ntdll.dll, která je zodpovědná za volání jádra.
Mezi tyto knihovny patří kernel32.dll, user32.dll, gid32.dll či advapi32.dll.

Mezi úkoly hlavního procesu subsystému patří vykreslování oken konzolových aplikací a podpora 16bitových programů určených původně pro operační systém MS–DOS. Csrss.exe také dostane oznámení, kdykoliv dojde k spuštění nového či ukončení již běžícího procesu nebo vlákna. Ve svém adresovém prostoru si uchovává vlastní kopii seznamu všech běžících procesů a vláken, aby pro ně mohl vyřizovat požadavky, jež mohou vzniknout při volání některých funkcí Windows API.

Informace o tom, že Csrss.exe ve své paměti uchovává vlastní kopii seznamu běžících procesů a vláken, byla zveřejněna na počátku roku 2009 na diskusním fóru Sysinternals (http://forum.sysinternals.com).
Bezpečnostní programy zaměřené na hledání skrytých hrozeb v počítači (například skrytě běžících procesů) mohou této skutečnosti využít ve svůj prospěch a zvýšit svoji efektivitu.
Existence kopie seznamu běžících procesů a vláken uvnitř Csrss.exe pravděpodobně nebyla příliš známa ani mezi autory malware a zejména rootkitů – programů, které se zaměřují na skrývání přítomnosti škodlivého softwaru v systému.

V dobách předcházejících Windows NT 4 do hlavního procesu subsystému patřily i moduly, které se starají o grafické uživatelské rozhraní a grafické kreslení vůbec. Vývojáři se tímto uspořádáním pravděpodobně chtěli přiblížit elegantní struktuře operačních systémů založených na mikrojádru. Taková struktura však vyžadovala velmi častá systémová volání a přepínání kontextu procesů. Ovladače grafické karty a obrazovky totiž běžely v režimu jádra, takže pokud nějaká aplikace chtěla například překreslit okno, bylo nutné přepnout kontext na hlavní proces subsystému, kde sídlil správce grafického uživatelského rozhraní, a následně se přepnout do režimu jádra, aby ten mohl doručit požadavek na překreslení ovladači grafické karty.

Systémová volání a přepínání kontextu mezi procesy patří mezi časově náročné operace, což mělo negativní dopad na výkon systému jako celku. Situace se výrazně nezlepšila ani po provedení mnoha optimalizací (byl upraven plánovač procesů a csrss.exe dokonce mohl číst některé oblasti paměti jádra, aby se ušetřilo kopírování). Vývojáři proto ve Windows NT 4 přesunuli správce grafického uživatelského rozhraní a ostatní grafické funkce do ovladače win32k.sys, čímž se snížil počet systémových volání a přepínání procesů. Jak již víte, jádro systému sdílí společný paměťový prostor a může komunikovat s ovladači grafické karty bez použití systémových volání.

Ovladač win32k.sys se tedy stará o grafické uživatelské rozhraní; spravuje okna, tlačítka, textová pole, obsluhuje myš a klávesnici. Umožňuje také kreslení různých grafických útvarů, jako jsou body, přímky či křivky. Ovladač se postará, aby se požadavky na vykreslování dostaly k správným ovladačům grafiky, tudíž aplikace, jež využívají GUI, vůbec nemusí (a většinou ani nepotřebují) vědět, jakou grafickou kartou počítač disponuje a jak se s ní zachází. Win32k.sys se chová podobně jako HAL – smazává rozdíly mezi různými kusy hardware. Bránu k ovladači win32k.sys tvoří knihovny gdi32.dll a user32.dll. První z nich obsahuje rutiny pro kreslení různých grafických útvarů (body, čáry, křivky) a druhá exportuje funkce pro práci s prvky uživatelského rozhraní, jako jsou okna, menu či ikony.

Mezi velmi důležité knihovny DLL také patří kernel32.dll, jenž exportuje vybrané části exekutivy (práce s procesy a vlákny, správa paměti, synchronizace), a advapi32.dll, která obsahuje rozhraní pro práci se službami a bezpečnostním modelem.

Systémové procesy

Windows patří mezi monolitické operační systémy, které se vyznačují velmi velkým a složitým jádrem, jež disponuje řadou pokročilých funkcí. Přesto běh systému závisí na několika proce- sech, jejichž ukončení (ať je způsobeno úmyslně, nebo v důsledku softwarové chyby) znamená restartování počítače. Tyto kritické procesy se obvykle nazývají jako systémové.

Seznam právě běžících procesů můžete vidět v programu Správce úloh, který spustíte například pomocí známé klávesové zkratky Ctrl+Alt+Del. Na obrázku vidíte okno programu. Systémové procesy, o kterých pojednávají další odstavce, jsou vyznačeny šedou barvou.

Tip: Správce úloh vám nedovolí systémové procesy násilně ukončit. Pokud se o to pokusíte, program zareaguje hláškou „Přístup odepřen“. Zajímavá je zde metoda, jakou Správce úloh rozhoduje, zda cílový proces je systémový. Až do Windows Vista totiž nejsou tyto procesy chráněny žádným bezpečnostním mechanismem, který by bránil jinému procesu, jenž disponuje administrátorským oprávněním, je ukončit. Správce úloh má v sobě „natvrdo“ zakódovány názvy procesů, které považuje za systémové. Tohoto faktu mohou snadno zneužít tvůrci malware. Zkuste si například pojmenovat nějaký program winlogon.exe, spustit jej a následně se jej pokuste násilně ukončit pomocí Správce úloh.

Nečinné procesy (System Idle Processes)

Jedná se pouze o pseudoproces, který nevykonává žádnou činnost v uživatelském režimu. Na disku nenajdete žádný soubor, který by obsahoval jeho kód a data, ani žádné knihovny DLL, jenž by využíval. Úkolem Nečinných procesů je spotřebovávat čas procesoru, když žádná součást operačního systému ani žádná aplikace nemá co na práci. Jádro vytvoří tento proces během raných fází inicializace operačního systému. PID Nečinných procesů je vždy roven nule.

Proces System

Proces System také nevykonává žádný kód v uživatelském režimu, a tudíž nepoužívá žádné knihovny DLL a nenajdete žádný soubor s příponou .exe , který by jej reprezentoval. Už ale nejde čistě o pseudoproces; v jeho kontextu běží skupina vláken známá pod označením pracovní vlákna (worker threads). Jádro tato vlákna vytvoří během bootovacího procesu a jejich úkolem je vykonávat činnosti, jenž jim někdo zadá. Pracovní vlákna stráví většinu času čekáním, až jim nějaká součást jádra (nebo ovladač) určí, co mají vykonat. Jakmile práci dokončí, čekají na další zadání.

Jádro využije služeb pracovních vláken ve chvíli, kdy potřebuje vykonat úkol, který je časově náročný (a tudíž by mohl brzdit výkon systému, kdyby nebyl proveden asynchronně), nebo nemůže být splněn za aktuálních podmínek. V takovém případě jádro předá úkol na bedra této speciální skupině vláken. Vlákna většinou dokončují zpracování požadavků od hardware, které nebylo možné provést při obsluze přerušení. Dále je využívá například správce paměti pro zapisování „špinavých“ (dirty) stránek z vyrovnávací paměti na disk.

Spolu s Nečinnými procesy je System jediným procesem s pevně daným číslem PID. Toto číslo má v jeho případě od Windows 2000 do Windows Serveru 2019 hodnotu 4. V předcházejících verzích neslo hodnotu 1.

Správce úloh

spravce procesu2

Správce relací (Session Manager, Smss.exe)

Smss.exe je spuštěn v poslední fázi startu jádra a jedná se o první proces, který vykonává kód v uživatelském režimu. Provede poslední fázi inicializace operačního systému, který je pak připraven na přihlášení uživatelů.

Jak název napovídá, hlavním úkolem tohoto procesu je vytváření relací. Relaci si můžete představit jako ohradu, ze které ten, kdo je v ní uzavřen, nevidí ven a zároveň nikdo nevidí dovnitř. Tyto ohrady se využívají pro oddělení prostoru jednotlivých uživatelů. Díky nim například každý uživatel může mít namapované disky pod jinými písmeny. Jednotlivé relace se označují číslem.

Smss.exe nejprve vytvoří relaci 0, která se též označuje jako konzolová relace. V rámci ní běží systémové procesy, služby a všechny procesy uživatele, který se přihlásí jako první. Pro každého dalšího uživatele vytvoří správce další relaci.

Pro každou novou relaci správce spustí jednu kopii procesu winlogon.exe. Smss.exe je též zodpovědný za inicializaci hlavního procesu subsystému Windows – csrss.exe. Pro relaci 0 se místo Winlogonu spouští wininit.exe.

Jakmile dokončí svoji práci, správce relací navždy hlídá hlavní proces subsystému Windows a všechny kopie programu winlogon.exe. Pokud zjistí, že některý z těchto procesů byl neočekávaně ukončen, vyvolá modrou obrazovku smrti s kódem STATUS_CRITICAL_SYSTEM_PROCESS_DIED.

Procesy podílející se na přihlašování uživatele (winlogon.exe, LSASS.exe)

Úkolem procesu winlogon.exe je umožnit uživateli přihlášení pomocí grafického uživatelského rozhraní. Může autentizovat uživatele různými způsoby, nejčastěji se ale stále používá zadání uživatelského jména (login) a hesla. Jednotlivé metody autentizace jsou implementovány v oddělených knihovnách DLL.

Winlogon v sobě má zabudovanou jednoduchou metodu ochrany proti programům, které se snaží zachytit údaje, jež uživatel zadal při pokusu o přihlášení. Většinou se jedná o tzv. keyloggery – programy, které zaznamenávají stisky jednotlivých kláves. Aby takový program nemohl přesně určit, kdy uživatel zadává přihlašovací údaje, může být Winlogon nastaven takovým způsobem, že před zobrazením přihlašovací obrazovky je třeba stisknout speciální kombinaci kláves.

Výzva pro stisknutí aktivační kombinace kláves — Windows Server 2019

winlogon1

Výzva pro stisknutí aktivační kombinace kláves — Windows Server 2008

winlogon s2008

Přihlašovací obrazovka i obrazovka, která uživatele vyzývá k stisku této kombinace kláves, se může mírně lišit v závislosti na verzi operačního systému.

Windows Server 2019 winlogon

winlogon2

Windows Server 2008 winlogon

winlogon2 s2008

Jako výchozí kombinace je nastaven známý „trojhmat“ Ctrl+Alt+Del. Trik spočívá v tom, že jakmile Winlogon zjistí, že tato kombinace byla stisknuta, tuto informaci pohltí a zobrazí okno, kam uživatel vyplní přihlašovací údaje. Přesněji, o stisku aktivační kombinace se dozví okno s názvem SAS Window, které je též zodpovědné za její pohlcení.

Pokud tedy keylogger neoperuje v samotném jádře systému nebo neinfiltroval do adresového prostoru procesu winlogon.exe (například v podobě knihovny DLL), nemůže stisk aktivační kombinace přímo detekovat, a tedy přesně zjistit, kdy uživatel zadává přihlašovací údaje.

Jakmile uživatel zadá login a heslo, Winlogon tyto údaje odešle procesu lsass.exe, kde proběhne jejich ověření. Pokud vše dopadne dobře (uživatel zadal správné jméno a heslo), lsass.exe zjistí, jakými oprávněními uživatel disponuje, a vytvoří tzv. token. Jedná se o objekt, kterým se pak uživatel prokazuje, potřebuje-li doložit, že má oprávnění k provedení určité operace.

Pokud má uživatel administrátorská práva a je-li zapnut mechanismus UAC (User Account Control), lsass.exe vytvoří tokeny dva. První z nich v sobě obsahuje všechna oprávnění, kterými uživatel disponuje. Druhý obsahuje jenom vybraná z nich. S pomocí druhého tokenu pak Winlogon vytvoří procesy, které provedou inicializaci prostředí. Token s omezenými právy se použije, kdykoliv uživatel spustí nějakou aplikaci, jež nevyžaduje administrátorská práva.

Pokud se uživatel pokusí spustit program vyžadující oprávnění administrátora, UAC se může dotázat (záleží na nastavení systému), zda chce daný program, který vyžaduje administrátorská práva, a tudíž by mohl být pro systém nebezpečný, spustit. Pokud dá uživatel spuštění zelenou, použije se pro daný program token, který obsahuje všechna uživatelova oprávnění.

Winlogon zůstává aktivní i po úspěšném přihlášení uživatele. Kromě toho, že je jeho povinností zajistit i odhlášení, stále čeká na onu aktivační klávesovou kombinaci a v případě, že zjistí její stisknutí, zobrazí dialog, který vidíte na obrázku 2.11. Winlogon také může být nakonfigurován tak, že spustí rovnou Správce úloh.

Jakmile Winlogon obdrží tokeny od LSASS, může být zahájena inicializace pracovního prostředí uživatele. Tato činnost již nespadá do pravomocí tohoto procesu, ale do kompetence procesů, jejichž názvy jsou uvedeny v hodnotě Userinit v klíči
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current Version\Winlogon.

Winlogon přečte obsah této hodnoty a pokusí se všechny nalezené procesy spustit.

Jediný proces, který by se měl za všech okolností starat o inicializaci pracovního prostředí uživatele, je userinit.exe v systémovém adresáři. Pokud hodnota obsahuje i názvy dalších procesů, jedná se pravděpodobně o malware.

Inicializace pracovního prostředí spočívá v podstatě jen ve spuštění startovacích skriptů a předání řízení shellu, jehož název userinit.exe nalezne pod hodnotou Shell ve stejném klíči, jako Winlogon hledal hodnotu Userinit. Výchozím shellem pro všechny uživatele je Průzkumník Windows (explorer.exe), který zodpovídá za zobrazení pracovní plochy a umožňuje uživateli mimo jiné procházet adresářovou strukturu a spouštět další programy.

Procesy pro podporu služeb (services.exe, svchost.exe)

Mnoho součástí Windows je implementováno jako služby – programy běžící na pozadí, které ve většině případů nepotřebují (a ani nevyhledávají) interakci s uživatelem a jejichž běh nezávisí na tom, zda je přihlášen či nikoliv.

Poznámka: Odhlášení uživatele znamená automatické ukončení všech procesů, které běží pod jeho účtem.

Interně systém Windows mezi služby řadí i ovladače jádra, ačkoliv ty nepatří mezi entity, o které se správce služeb (Service Control Manager – SCM), reprezentovaný procesem services.exe, příliš stará. Jeho hlavním úkolem je instalovat, spouštět a zastavovat služby určené pro běh v uživatelském režimu a posílat jim další druhy příkazů.

Službu tvoří obyčejný spustitelný soubor formátu PE s příponou .exe , který navíc obsahuje speciální kód pro komunikaci se správcem. Na rozdíl od normálních aplikací, více služeb může sdílet virtuální adresový prostor jednoho procesu. Vše záleží na nastavení konkrétní entity. Kód služeb, které nemají vlastní proces, je vykonáván v kontextu instancí procesu svchost.exe, který je pro jejich „hostování“ přímo určen.

Pro pohodlnou kontrolu služeb je připravena aplikace services.msc, která nejen zobrazí seznam všech nainstalovaných služeb a jejich aktuální stav, ale umožňuji s nimi i manipulovat.

services.msc

services.msc

Konfigurace všech služeb se nachází v registru pod klíčem
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services.

Každá nainstalovaná služba má zde vyhrazený jeden podklíč. Ten nese její interní jméno a může obsahovat další klíče s informacemi o jejím nastavení. Na obrázku 2.13 vidíte příklad podklíče pro službu s interním jménem ALG. Mezi nejdůležitější hodnoty patří:

  • Description

  • DisplayName

  • ErrorControl

  • ImagePath

  • Start

  • Type

Hodnoty Description a DisplayName mají pouze informativní charakter. Jejich obsah zobrazuje snap-in services.msc ve sloupcích Název a Popis. Pokud je hodnota DisplayName prázdná, nebo vůbec neexistuje, utilita zobrazí ve sloupci Název interní jméno.

Služby v registru

service alg

Položka ErrorControl určuje, jak se má správce zachovat, když při spouštění služby dojde k chybě. Možné hodnoty a popis chování správce naleznete v tabulce 2.

Tabulka 2. Význam položky ErrorControl
Hodnota Konstanta Význam pro SCM

3

SERVICE_ERROR_CRITICAL

Chyba se zaznamená do systémového protokolu. SCM restartuje počítač a pokusí se postupovat podle poslední známé dobré konfigurace (last known good state). Pokud k chybě dojde i během tohoto pokusu, správce ohlásí chybu a nebude pokračovat v načítání dalších služeb.

0

SERVICE_ERROR_IGNORE

Chyba služby je úplně ignorována. SCM nezapíše nic ani do systémového ptotokolu.

1

SERVICE_ERROR_NORMAL

Správce služeb zapíše informaci o chybě do systémového protokolu, ale dál pokračuje ve své činnosti.

2

SERVICE_ERROR_SEVERE

SCM zapíše zprávu o chybě do systémového protokolu. Pokud k chybě došlo během obnovování z poslední známé dobré konfigurace, pokračuje ve spouštění dalších služeb. Jinak SCM restartuje počítač a pokusí se obnovit nastavení z poslední známé dobré konfigurace.

Hodnota ImagePath v sobě uchovává název souboru služby. Pokud není hodnota přítomna, SCM předpokládá, že soubor služby se nachází v systémovém adresáři a jmenuje se X.exe , nebo X.sys , kde X je interní název služby.

Podle hodnoty Start se SCM rozhodne, kdy může být služba spuštěna. Tabulka 3 popisuje hodnoty, kterých tato položka může nabývat.

Tabulka 3. Význam položky Start
Hodnota Konstanta Význam pro SCM

0

SERVICE_BOOT_START

Platí pouze pro ovladače jádra. Příslušný ovladač je načten do jádra během rané fáze inicializace.

1

SERVICE_SYSTEM_START

Platí pouze pro ovladače jádra. Systém načte služby s touto hodnotou položky Start během volání funkce IoInitSystem, která se nachází v hlavním modulu jádra.

2

SERVICE_AUTO_START

Služba je spuštěna správcem služeb během jeho inicializace. To se děje krátce před vyzváním uživatele, aby zadal své přihlašovací údaje.

3

SERVICE_DEMAND_START

Služba není spuštěna automaticky, ale libovolný program může o její dodatečné spuštění požádat správce služeb. Platí jak pro služby běžící v uživatelském režimu, tak pro ovladače.

4

SERVICE_DISABLED

Službu nelze spustit. Platí i pro ovladače.

Zdroje a odkazy

Kniha Jádro systému Windows Martin Dráb Computer Press, a.s., 2011 ISBN 978-80-251-2731-5