Relokace
Relokace je v informatice metoda, pomocí níž může být strojový kód umístěn na jiné místo v paměti, než pro které byl překladačem vytvořen. Adaptaci strojového kódu provádí program nazývaný locator (umisťovač), který podle údajů uvedených v relokační tabulce opraví ve strojovém kódu absolutní adresy skoků a odkazů na data.[1]
Původ
Starší procesory nepodporovaly mechanismus virtuální paměti, pomocí kterého je možné vytvořit pro běžící proces virtuální adresní prostor, který začíná od adresy 0 (nula). Program tak musel být umístěn v paměti od místa, kde začínal volný prostor. Začátek volného prostoru byl však různý podle aktuálních okolností. Proto bylo nutné vytvářet programy tak, aby je bylo možné přizpůsobit libovolnému umístění v paměti.
V systémech DOS (též MS-DOS z roku 1981) byla na začátku paměti rezervovaná oblast, za kterou následovalo jádro systému. Volná oblast pro programy začínala na různých adresách podle toho, jaké ovladače byly při startu systému zavedeny nebo podle použité verze systému. Procesor Intel 8088 použitý v IBM PC a kompatibilních počítačích podporoval pouze omezenou segmentaci (max. velikost segmentu je 64 kiB), virtuální paměť nepodporoval. Programy v souborech s příponou .COM
, jejichž velikost byla omezena maximální velikostí segmentu na 64 kiB relokovány být nemusely. Programy EXE obsahují relokační tabulky a zavaděč podle ní automaticky provádí relokaci.[1]
V operačním systému OS/360 s MFT bylo již v roce v roce 1967 možné spustit omezený počet programů současně (tzv. multitasking). Byly pro ně vyhrazeny pevné úseky paměti, do kterých byl kód relokován.[1]
Relokační tabulka
Relokační tabulka obsahuje seznam absolutních adres ve strojovém kódu, které je nutné modifikovat. Adresy v kódu jsou obvykle upraveny tak, aby kód byl funkční při umístění od adresy 0 (nula). Při umístění kódu na jinou adresu (například 100, tzv. bázová adresa) je nutné ke všem adresám uvedeným v relokační tabulce přičíst bázovou adresu.[1]
Pozičně nezávislý kód
Pozičně nezávislý kód (PIC) může být umístěn na libovolnou adresu a přesto si zachovává svoji funkčnost. Využívá strojové instrukce, které používají relativní adresy, jejichž cílová adresa je vztažena k aktuální adrese (uložena v registru čítač instrukcí, PC, IP) nebo jsou využívány bázové adresy, které je možné na začátku vhodným způsobem inicializovat na aktuální pozici kódu v paměti.
Knihovny
Knihovny jsou obvykle přeloženy tak, že jsou přímo bez úprav funkční na jisté adrese. V omezeném adresním prostoru architektury IA-32 (32bitové procesory i386 a novější) se však často stane, že loader při umisťování do paměti narazí na kolizi, která vede k relokaci dynamické knihovny a tím drobnému zpoždění při spuštění programu a zároveň k nemožnosti sdílení původní kopie knihovny, která je již v paměti umístěna (relokace způsobí, že se kód liší). Proto je výhodnější, aby byly bázové adresy knihoven pečlivě voleny. V Microsoft Windows určuje toto rozmístění sama firma Microsoft, která jej provádí s ohledem na své vlastní programy, které tak mohou startovat rychleji. V unixovém systému Linux je k dispozici speciální nástroj prelink, který může po každé aktualizaci systému vypočítat ideální rozmístění všech knihoven systému a obratem ji aplikovat (knihovny „předrelokovat“). V systému Mac OS X je tato činnost nazývána prebinding.
Vznik binárky
Překladač vytváří strojový kód, který je vytvořen pro běh na určité adrese. Překladač programovacího jazyka C vytváří nejprve objektový kód (anglicky object code), který je pozičně nezávislý, protože obsahuje symbolické reference, které je možné přizpůsobit zvolenému umístění v paměti. Spojení více objektových kódů a tím vytvoření spustitelného souboru zajišťuje linker, jehož úkolem je vyřešit (vyčíslit) všechny symbolické adresy, což je typicky prováděna ve dvou krocích:
- kód každého objektu má různé sekce jako kód segmentu, data segmentu, .bss apod. Ke kombinaci všech těchto objektů do jediného spustitelného souboru, linker připojí všechny sekce podobných typů do jedné sekce téhož typu. Linker poté přiděluje běhové adresy každé sekci a každému symbolu. V tomto bodě má kód (funkce) i data (globální proměnné) unikátní běhové adresy.
- každá sekce odkazuje na jeden nebo více symbolů, které by měly být modifikovány tak, aby mohly ukazovat na správné adresy.
Výsledný kód se obvykle vytváří tak, aby byl funkční při umístění od adresy 0 (nula). Zároveň je vytvořena relokační tabulka, která umožňuje relokaci výsledného kódu na alternativní adresu. Relokační tabulka se připojuje do výsledného spustitelného souboru.
Náhodné umístění v paměti
Možnost relokace se využívá ke zvýšení odolnosti systému proti útokům pomocí přepsání části paměti (např. přetečení na zásobníku). Při této metodě ochrany je strojový kód umístěn na náhodně zvolenou adresu. Na 32bitovém systému jsou možnosti náhodného umístění silně omezeny, zatímco 64bitové systémy ji mohou využít efektivněji.[2] Útočník pak předem neví ani přibližné umístění kódu v paměti, což útok činí obtížnějším. Zabezpečení používají systémy Windows Vista a novější pod názvem Address space layout randomization (ASLR). V Linuxu existuje podobná možnost implementovaná pod názvem Exec Shield.[3][4]
Reference
- KOLÁŘ, Petr. Operační systémy [online]. Liberec: 2005-02-01 [cit. 2008-08-30]. S. 40, 41. Dostupné online.
- Ollie Whitehouse. An Analysis of Address Space Layout Randomization on Windows Vista [PDF]. February 2007 [cit. 2010-05-19]. Dostupné v archivu pořízeném dne 2011-06-07.
- VAN DE VEN, Arjan. New Security Enhancements in Red Hat Enterprise Linux v.3, update 3 [PDF]. 2004-08 [cit. 2007-10-18]. (Red Hat, Inc.). Dostupné v archivu pořízeném z originálu dne 2005-05-12.
- COBBERT. Address space randomization in 2.6. LWN.net [online]. 2005-02-02 [cit. 2010-05-20]. Dostupné online.