Hlavné menuUser loginSearch |
Reply to comment
Friday, 07.05.2010 19:36
V několika minulých dnech jsem se intenzivně zabýval zjišťováním, jakže to funguje ochrana jednoho nejmenovaného bezpečnostního produktu. Tato činnost často obnáší použití disassembleru a debuggeru a tento případ nebyl výjimkou. Během práce jsem si všiml přítomnosti zvláštní instrukce REP RET. Kdybych ji neviděl na vlastní oči, pokládal bych ji za neplatnou. Ale protože ji zřejmě procesor "sežere", udělal jsem malé pátrání, abych se dozvěděl, co tato instrukce provádí. RozkladZáhadná instrukce se skládá ze dvou částí. Pokud se na ně podíváme odděleně, nic nás nepřekvapí. Jak REP, tak RET dávají smysl. Pravda, prefix REP musí být následován nějakou instrukcí, ale jak uvidíme v následujícím odstavci, RET by mezi takové patřit rozhodně neměla. Příznak REP říká procesoru, aby následující instrukci prováděl pořád dokola a při každé obrátce snížil hodnotu v registru ECX (CX na 16-bitové platformě, RCX na 64-bitové) o jedničku. Cyklus skončí, jakmile hodnota registru dosáhne nuly. Proto se tento příznak využívá například při kopírování bloku paměti, práci s řetězci či jiných cyklických operacích. Instrukci RET se také jinak říká návrat z podprogramu. Procesor vybere z vrcholu zásobníku slovo (v bajtech odpovídá velikosti adresy) a zapíše jej do registru EIP (IP na 16-bitové platformě, RIP na 64-bitové). Protože tento registr vždy obsahuje adresu instrukce, která se má začít vykonávat, dojde ke skoku na adresu, jež se nacházela na vrcholu zásobníku. Existuje též varianta, která po načtení hodnoty do xIP odstraní z vrcholu zásobníku dalších n bajtů. Nazývá se RET n. SémantikaUž tedy víme, k čemu slouží příznak REP a instrukce RET, použijeme-li je zvlášť. Ale jakou má sémantiku instrukce, která vznikne jejich spojením (REP RET)? Má vybírat slova ze zásobníku, dokud nebude xCX obsahovat nulu a na adresu v posledním odebraném skočit? Nebo snížit registr o jedničku, vybrat slovo ze zásobníku, použít jej jako adresu pro skok a dál v opakování nepokračovat, protože skok změnil adresu aktuální instrukce? Ani jedna odpověď není správná. Dnešní procesory jsou velmi složité a pro zvýšení rychlosti využívají vyrovnávacích pamětí (L1, L2, L3 cache a další) či techniky zpracovávání více instrukcí najednou zvané pipelining či superskalární pipelining. Procesor nenačítá instrukce přesně tak, jak mu velí změny hodnoty v registru xIP, ale snaží se předem odhadnout, kudy program poběží a tyto instrukce si načíst (a případně předzpracovat) dříve, než ve skutečnosti potřebuje (prefetching). Moderní procesory též zpracovávají více instrukcí najednou - zatímco se jedna dekóduje, druhá může zapisovat do registru a třetí číst z paměti. Aby mohl úspěšně načítat instrukce "dopředu", procesor musí nějakým způsobem uhodnout, kudy se tok programu bude ubírat. Problém zde mohou způsobovat například podmíněné skoky - v době jejich "přednačtení" nemusí být známo, jestli je podmínka skoku splněna, nebo ne. V takovém případě se některé procesory pokusí další tok programu odhadnout a načíst a předzpracovat instrukce z příslušné adresy. Pokud se odhad ukáže jako nesprávný, předzpracované instrukce jsou zahozeny a pocesor se vrátí do stavu před provedením podmíněného skoku (či jinou instrukcí, která vyžaduje hádání). Jak se podle mého zdroje píše v manuálech AMD, implementace dopředného načítání instrukcí se dostane do potíží, nachází-li se těsně po instrukci podmíněného skoku instrukce návratu z procedury. Procesor přestane přednačítávat další instrukce, dokud se nevykoná RET, nebo se tok programu nepřesměruje do jiných míst. Má-li však taková instrukce před sebou prefix REP, k "záseku" nedochází, a tedy výkon procesoru není ztracen. Na závěr ještě uvedu zdrojovou URL a příslušnou citaci:
http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm.x86/2006-03/msg00041.html Reply |
LinksIRC kanál: #secit Štatistika fóraNové témy na fóre |
Recent comments
1 week 6 days ago
2 weeks 22 hours ago
2 weeks 1 day ago
2 weeks 1 day ago
3 weeks 2 days ago
16 weeks 1 day ago
29 weeks 4 days ago
29 weeks 6 days ago
30 weeks 4 days ago
30 weeks 4 days ago