DLL peklo

Z Wikipedie, otevřené encyklopedie
Skočit na: Navigace, Hledání

DLL peklo (anglicky DLL hell) je v počítačích termín pro komplikace, které vznikají při práci s dynamickými knihovnami (DLL), používaných v operačním systému Windows. Zejména u starší 16bitové verze, která běží celá v jednom paměťovém prostoru. DLL peklo se může projevovat mnoha různými způsoby. Obvykle aplikace nejdou spustit nebo nefungují správně. DLL peklo je specifická forma obecného konceptu závislostního pekla (anglicky Dependency hell).

Problémy[editovat | editovat zdroj]

Existuje velké množství problémů ohledně DLL knihoven. Speciálně pokud na svém systém nainstalujete a odinstalujete několik aplikací. Počínaje konflikty mezi knihovnami, shánění knihoven až po spoustu nevyužívaných kopií knihoven.

Nekompatibilní verze[editovat | editovat zdroj]

Určitá verze knihovny může být kompatibilní s určitými verzemi softwaru, které jí používají. Bohužel nemusí být kompatibilní s jinými verzemi softwaru. Windows byl zvláště zranitelný, protože kladl velký důraz na dynamické linkovaní C++ knihoven a OLE objektů. C++ třídy obsahovaly velké množství metod a malá změna v jedné z jejich mohla způsobit nekompatibilitu s programy, které ji využívali. Linkování a propojování objektů má řadu striktních pravidel, aby se právě tomuto zabránilo. Například používání rozhraní, které se nesmí měnit, nebo nepoužívání sdílené paměti. Ale to není dostatečné, protože fungování uvnitř třídy může být stále změněno. Pro jednu aplikaci může být úprava knihovny odstranění bugu a pro druhou odstranění důležité funkčnosti. Před vydáním Windows 2000, byl v tomto Windows velice zranitelný, protože používal COM tabulka tříd byla sdílena mezi všemi uživateli a procesy. V COM objektu bylo pro každou DLL/EXE knihovnu vytvořeno pouze jedno specifické COM ID. Pokud nějaký program potřeboval vytvořit instanci dané třídy nebo knihovny, tak si jí vzala z centralizovaného úložiště. Naopak když se nainstaloval nový program, tak se zrušila stará verze a nainstalovala se verze s novým programem. Důsledkem toho bylo že instalací nového programu přestal fungovat ten starý.

DLL podupávání[editovat | editovat zdroj]

Problém DLL podupávání (anglicky DLL stomping) nastal, když nový program přehrál jinému programu starou funkční DLL knihovnu novou knihovnou, se kterou starý program nedokázal fungovat. Častým příkladem je ctl3d.dll a ctl3dv2.dll knihovnu pro Windows 3.1. Microsoftem vytvořené knihovny mohli vydavatelé třetích stran používat ve svých aplikacích, ale radši ke každé verzi přidali vlastní knihovnu u které souhlasila verze. Dupání DLL se objevilo z důvodů:

  • Microsoft distribuoval runtime DLL knihovny jako systémové komponenty (původně v C:\WINDOWS a C:\WINDOWS\SYSTEM). Tím ušetřil místo v paměti, proto knihovny byly sdílené. To mělo smysl u strojů, které měly malou paměť.
  • Instalátory aplikaci jsou typicky spuštěny v privilegovaném kontextu, který má přístup k instalaci DLL knihoven do systémových adresářů a má také přístup do registrů, kde může nové DLL knihovny registrovat jako COM objekty. Špatně napsaný instalátor může i snížit verzi systémové DLL knihovny a nic ho v tom nezastaví. Ve Windows Vista a vyšších toho může dělat už jenom instalátor, který je označen jako důvěryhodný nebo si vyžádá administrátorské heslo.
  • Aplikacím ve Windows bylo povoleno, aby v rámci svých instalací stahovaly aktualizace operačního systému. Pokud tedy nějaká aplikace potřebovala knihovnu začlenila si jí k sobě už při instalaci.
  • Před vydáním Windows Installeru existovaly pouze komerční programy, které instalátor zastupovaly a spousta lidí si začala psát vlastní instalátory. Bohužel ne všichni znali pravidla, jakými by se instalátory měly řídit. Tím se do operačního systému dostávaly různé verze DLL knihoven.
  • Některá vývojová prostředí automaticky nepřidávaly verzi knihovny ke svým kompilovaným knihovnám a spousta vývojářů na to taky zapomínala. Tím se opět dostaly do systému knihovny, které neodpovídaly ve verzi, které softwary potřebovaly.
  • Občas operační systém odstranil nebo změnil DLL knihovnu starší nebo zastaralou knihovnou. Například systém Windows 2000 nahrál ovladač černobílé tiskárny do ovladače barevné knihovny, pokud byla barevná tiskárna nainstalována první.

Nesprávná COM registrace[editovat | editovat zdroj]

V COM objektech a další částech Microsoft Windows je důležité, aby si všechny aplikace mohly registrovat svoje komponenty. Registry byly určeny pro to, aby řekly, která DLL se má ve výsledku použít. Pokud ovšem byla v registrech zapsána jiná DLL (jiná verze), tak program dostal knihovnu, která pro něj byla nefunkční. Toto se stalo, pokud jedna aplikace při instalaci přepsala jinému programu verzi knihovny, která měla sice stejné jméno, ale jinou verzi.

Sdílené paměťové moduly[editovat | editovat zdroj]

Všechny 16bitové verze Windows pro DOS načítají jen jednu instanci každé DLL knihovny. Všechny aplikace odkazují na stejnou kopii v operační paměti dokud ji žádná aplikace nepoužívá a teprve poté je DLL z paměti uvolněna. V řadě Windows NT (32bitové i 64bitové) dochází ke sdílení knihoven mezi procesy pouze v případě, že různé spustitelné soubory načítají DLL modul ze stejného adresáře a souboru. Sdílí se pouze výkonný kód, nikoliv však zásobník. Sdílení kódu mezi procesy je zajištěno mechanismem mapováním paměti (anglicky memory mapping), takže i když je požadovaná DLL knihovna umístěná v adresáři, kde je očekáváno její umístění, jako například v systémovém adresáři nebo v adresáři aplikace, sdílení se nepoužije když jiná aplikace začala používat nekompatibilní verzi z jiného adresáře. Tento problém se může projevovat jako chyba 16bitové aplikace, ke které dochází pouze tehdy, když se aplikace spustily ve specifickém pořadí.

Nedostatek provozuschopnosti[editovat | editovat zdroj]

V přímém rozporu s problémem DLL podupávání: Pokud aktualizace DLL nemá vliv na všechny aplikace, které ji používají, tak se DLL knihovny stávají těžší na správu, což znamená k odstranění problémů, které se vyskytují v současných verzích DLL (bezpečnostní opravy jsou zvláště přesvědčivý a bolestivý případ). Místo použití pouze nejnovější verze DLL, musí implementace v ideálním případě opravit problémy a otestovat jejich kompatibilitu na každé vydané verzi DLL.

Příčiny[editovat | editovat zdroj]

Nekompatibilitu DLL způsobuje:

  • Nedostatek operační paměti v kombinaci s neoddělením paměti procesů v 16bitových verzích Windows.
  • Nepřítomnost vynuceného standardního verzování, tj. pojmenování a systémových umístění schémat pro DLL.
  • Není vyžadována jednotná metoda pro instalaci a odstraňování softwaru (správce balíčků).
  • Centralizovaná autoritativní podpora pro binární rozhraní řízení a záruk DLL aplikace, dovolující vydání nekompatibilním DLL knihovnám se stejným názvem souboru a interním číslem verze.
  • Příliš zjednodušené nástroje pro správu, které brání identifikaci změněných problematických DLL uživateli a administrátory.
  • Vývojářské obcházení zpětné kompatibility funkcí ve sdílených modulech.
  • Microsoft vydává aktualizace běhového prostředí operačního systému mimo standardní aktualizace.
  • Neschopnost dřívějších verzí systému Windows spustit bok po boku konfliktní verze stejné knihovny.
  • Spolehnutí se na aktuální adresář nebo proměnnou prostředí %PATH%, kde oba parametry se mění v čase a systém od systému, k najití závislé DLL knihovny (namísto načtení jim explicitně nakonfigurovaného adresáře).
  • Developeři znovu používají ClassID z ukázkové aplikace pro COM rozhraní svých aplikací, spíše než aby vytvořili svoje vlastní nové GUID.

DLL peklo byl velmi častý jev na systémech před vydáním Windows NT. Hlavní příčinou je, že 16bitové operační systémy neměly omezovat procesy k jejich vlastnímu paměťovému prostoru, a tím jim nedovolit nahrání vlastní verze sdílených modulů, které jsou s ním kompatibilní. U aplikačního instalátoru se očekává, že bude kvalitní a bude ověřovat informace o verzi DLL knihovny před přepsáním existující systémové DLL knihovny. Standardní nástroje ke zjednodušení nasazení aplikací (které vždy zahrnují dodání vlastní potřebné DLL knihovny na operačním systému) byly poskytnuty společností Microsoft a dalšími dodavateli softwaru. Microsoft dokonce vyžaduje po dodavatelích aplikace použití standardního instalátoru a verifikaci jejich programu, aby správně fungoval, než mu bude povoleno použití loga Microsoftu.

Použití malwarem[editovat | editovat zdroj]

Nejednoznačnost s níž knihovny, které nejsou plně kvalifikované, mohou být vloženy do operačního systému Windows je v posledních letech zneužívána malwarem k otevření nových cest zranitelnosti, které ovlivňují aplikace od mnoha různých dodavatelů software, stejně jako systém Windows.

Řešení[editovat | editovat zdroj]

Různé druhy DLL pekla byly v průběhu let vyřešeny nebo zmírněny.

Statické linkování[editovat | editovat zdroj]

Jedním z nejjednodušších řešení DLL pekla v aplikaci je k ní připojit všechny statické knihovny. Toto je běžné v Microsoft C/C++ aplikacích, kde místo toho, abychom se museli starat o to, které verze MFC42.DLL jsou nainstalovány, aplikace je sestavena tak, aby se propojila se statickými knihovnami. To eliminuje DLL úplně, a je přijatelné pro samostatné aplikace, které používají pouze knihovny, které nabízejí statické možnosti, jako je například Microsoft Foundation Class Library. Hlavní účel DLL (sdílení knihoven v paměti mezi za účelem snížení zatížení paměti) je obětován, ale zjednodušuje další vývoj softwaru a komplikované nasazení bezpečnostních oprav nebo novějších verzí softwaru.

Ochrana souborů systému Windows[editovat | editovat zdroj]

Problém přepsání DLL byl poněkud snížen s příchodem Ochrany souborů systému Windows (Windows File Protection, WFP), která byla zavedena v systému Windows 2000. WFP zabrání neautorizovaným aplikacím přepsání systémové knihovny DLL, pokud nepoužívají specifické rozhraní Windows API, které toto umožňují. Stále ale existuje riziko, že aktualizace od společnosti Microsoft budou neslučitelné s existujícími aplikacemi, ale toto riziko je obvykle sníženo v současných verzích systému Windows pomocí Side-by-side assembly (SFC).

Aplikace třetích stran nemohou měnit soubory OS, pokud neobsahují balík legitimních aktualizací systému Windows přímo v jejich instalaci, nebo v případě, že tuto službu zakázala ochrana souborů systému Windows během instalace. Od Windows Vista aplikace třetích stran nemohou převzít vlastnictví systémových souborů a udělit si k nim přístup. Nástroj SFC může kdykoliv tyto změny vrátit.

Spuštění konfliktních knihoven DLL[editovat | editovat zdroj]

Řešení spočívá v tom, mít obě odlišné kopie stejné DLL knihovny pro každou aplikaci, obě na disku i v paměti.

Snadné manuální řešení konfliktů bylo umístění různých verzí problémových DLL knihoven do složek aplikací, než do společné složky celého systému. Toto funguje obecně tak dlouho, dokud aplikace je 32bitová nebo 64bitová a pokud DLL nepoužívá sdílenou paměť. V případě 16bitových aplikací nelze spustit na 16bitové platformě dvě aplikace současně nebo na 16bitovém virtuálním stroji pod 32bitovým operačním systémem. Před Windows 98 SE/Windows 2000 tomuto zabraňovalo Object Linking and Embedding (OLE), protože starší verze systému Windows měla jediný registr COM objektů pro všechny aplikace.

Systémy Windows 98 SE/Windows 2000 představily řešení s názvem Side-by-side assembly (SFC), které načte samostatné kopie DLL pro každou aplikaci, která je vyžaduje (a tím umožňuje aplikacím, které vyžadují konfliktní DLL, se spustit současně). Tento přístup eliminuje konflikty tím, že aplikaci umožní načíst požadovanou verzi modulu do svého adresního prostoru, při zachování primárního přínosu sdílení DLL mezi aplikacemi (tj. snížení využití paměti) pomocí metody mapování paměti a sdílení společného kódu mezi různými procesy, které nadále používají stejný modul. Avšak u DLL knihoven využívajících sdílená data mezi více procesy tento přístup nemusí fungovat. Jeden negativní vedlejší efekt jsou osamocené instance DLL knihovny, které nemusí být aktualizovány během automatizovaných aktualizací.

Přenosné aplikace[editovat | editovat zdroj]

V závislosti na architektuře aplikace a běhového prostředí může být přenosná aplikace efektivní způsob, jak snížit některé problémy s DLL, protože každý program obsahuje svazky svých vlastních soukromých kopií všech DLL knihoven, které potřebuje.

Virtualizace aplikací může také umožnit běh aplikace v „bublině“, která zabraňuje instalaci DLL knihoven přímo do souborů operačního systému.

Reference[editovat | editovat zdroj]

V tomto článku byl použit překlad textu z článku DLL Hell na anglické Wikipedii.