Jemny uvod do buffer overflow #1

18.01.2007 15:58 | blackhole_ventYl

Buffer overflow vulnerability - casto sa s nou mozno stretnut v changelogoch, alebo security advisories. Co to vlastne je a preco to vznika? Pre ludi znalych platformy x86, jej adresovacieho mechanizmu by sa mohlo zdat, ze je to priam jav nemozny. Opak je vsak pravdou. Tento clanok sa pokusi poskytnut jemny uvod do tejto vcelku lahko vytvoritelnej diery v mnohych programoch, ktora moze mat siahodlhe nasledky.

Nepojde o nijak prevratny clanok s nejakymi novymi a brutalnymi znalostami, bude skor zamerany na spojenie vsetkych elementov, ktore prispievaju k vzniku buffer overflow "efektu". Nebudem predpokladat ziadne vyznamne znalosti v oblasti bezpecnosti, iba trochu rozumu a znalost programovania v C. Znalost assemblera nebude na skodu. Ak bude zaujem, v moznom pokracovani nacrtnem aj to, ako sa proti takymto zalezitostiam branit. V tejto casti zhrniem vsetky podstatne faktory, ktore prispievaju k vzniku tejto zranitelnosti.

Prvym faktorom k vzniku buffer overflow je pouzitie vhodneho programovacieho jazyka. Co sa v tomto ohlade povazuje za vhodny jazyk? No v prvom rade musi dany jazyk byt dostatocne ignorantsky a v druhom rade musi byt dostatocne benevolentny pri kontrole chyb. Vcelku do tohto vzorca zapada jazyk C, resp. C++, ktore su navyse aj dobre rozsirene a vcelku slusne normalizovane. Prilisna benevolencia jazyka C vsak nie je sposobena tym, ze jeho navrhari nepouzili rozum, ale jeho urcenim. Pouziva sa na aplikacie, kde je hlavny vykon a efektivita a tam by overovanie kazdej blbosti, rozsahu, spravnosti kod vyrazne spomalilo a obmedzilo moznosti programatora, kedze niektore z vlastnosti (neoverovanie rozsahu poli) sa priamo vyuzivaju pri programovani. Doplnkom k tomuto faktoru je, ze programator casto nepredpoklada, ze by do funkcie mohol dostat viac dat, nez kolko si vyhradil v buffri, preto neosetri taketo pripady a pri kopirovani blokov dat kopiruje "kym este su data" a nie "kym este su data a v buffri je volne miesto". To sposobuje, ze vytvorit zranitelny program je velmi jednoduche.

Druhym faktorom je podpora platformy. Na domacich pocitacoch a vo sfere lowend serverov je asi najpouzivanejsou platformou platforma x86 a x86_64. Tato platforma uz cca od roku 1986 podporuje ochranu pamati a strankovanie - 2 zakladne faktory pre slusny memory managment. Organizacia pamate sa teda deli na 2 na sebe postavene vrstvy:

  • segmentacia - pamat je mozne rozdelit do lubovolne velkych blokov, ktore zacinaju na lubovolnom mieste v pamati. Je mozne zabezpecit, aby segmenty nesuce kod programu neboli citatelne, takisto je mozne zabezpecit, aby procesy nevedeli pristupovat do pamate inych procesov (to napriklad po windows 95 nebolo splnene, pri windows 95 a vyssich iba pre plne 32bitove programy), ani ju vobec nevideli (nevidiet znamena nevediet ju adresovat - pamat z pohladu ineho procesu neexistuje, a co nevidis, na to nemozes utocit). Na platforme x86 a od nej odvodenych je segmentacia povinna a neda sa vypnut (dodatok nizsie)
  • strankovanie - pamat je mozne rozdelit do blokov konstantnej velkosti (tzv. stranok) obvykle velkych 4kB. Proces prekladu strankovanej pamate zabezpeci preklad adresy ziskanej z prekladu segmentovanej pamate na fyzicku adresu v pamati. Vyhodou strankovania je, ze je nim mozne zabezpecit, aby 2 rozne procesy pouzivajuce 2 rozne segmenty pamate vyuzivali fyzicky tu istu pamat, cim sa jednoznacne pamat setri. Dalsim vyuzitim strankovania je lahsia podpora virtualnej pamate, nez pri segmentovani, nakolko sa lahsie pracuje s blokmi konstantnej velkosti, nez s blokmi variablinej velkosti. Strankovanie je na x86 platforme volitelne a standardne je vypnute, aj ked ho dnes pouzivaju snad vsetky operacne systemy bezne prevadzkovane.

Kazdy proces sa obvykle sklada z troch casti:

  1. kod procesu - obsahuje vykonatelny kod programu, zodpoveda mu kodovy segment, ktory nie je zapisovatelny a casto ani citatelny. Pri pokuse o zapis do tohto segmentu vyvola procesor chybu ochrany pamate a program bude operacnym systemom s najvacsou pravdepodobnostou zostreleny.
  2. data procesu - obsahuje data programu, skladaju sa zo statickych dat (ktore su zname uz v case zostavovania programu - obvykle retazce, konstantny a podobne) a miesta pre dynamicke data (vstupy uzivatela, nacitane data a dalsie). Zodpoveda im datovy segment, ktory moze byt volitelne zapisovatelny, ale citatelny je vzdy. Vykonavanie programu sa neda preniest do datoveho segmentu. Pri pokuse o vykonanie niecoho v datovom segmente procesor vyhlasi vynimku ochrany a operacny system proces zostreli.
  3. zasobnik - je oblastou, do ktorej pristupuju dve specialne instrukcie procesora PUSH a POP. Jedna sa o LIFO (last-in first-out) strukturu, teda zo zasobnika je mozne vybrat len to, co je navrchu, nove data mozno taktiez polozit len na vrch zasobnika. Vyhodou je to, ze ak sa dodzi poradie a mnozstvo dat pri vkladani a vyberani (pri vyberani je poradie presne opacne), netreba si pamatat adresu ukladanych dat, su vzdy na vrchole zasobnika. Zasobniku zodpoveda stack segment. Tento segment musi byt zapisovatelny, v opacnom pripade pri pokuse o pouzitie segmentu vyvola procesor vynimku a operacny system proces zostreli.

Programy pracuju s adresami v tvare Segment:Offset (tomu sa hovori logicka adresa), ta sa segmentaciou meni na linearnu adresu v tvare Offset [od zaciatku linearnej pamate] a tato linearna adresa sa strankovanim meni na fyzicku adresu pamati v tvare Offset [od zaciatku skutocnej pamate procesora]. Pri strankovani ale nie je zakazane premapovat 2 oblasti linearnej pamate na tu istu oblast fyzickej pamate.

Do zasobnika sa najcastejsie ukladaju navratove adresy podprogramov (ked volate podprogram, obvykle sa chcete vratit a pokracovat v behu programu tam, odkial ste podprogram zavolali, tak si adresu nasledujucej instrukcie hodite na vrch zasobnika (hodi ju tam procesor) a idete vykonavat podprogram). Je to preto, lebo pri navrate z podprogramu je velmi jednoduche urcit, kde v pamati sa navratova adresa nachadza - je na vrchole zasobnika. Ak sa tam nenachadza, tak bud programator vo vnutri programu pouzil nesparovanu PUSH / POP operaciu, alebo je program blbo napisany - jednoducho padne, pretoze sa zo zasobnika ako navratova adresa vytiahne nejaka somarina a program skonci s chybou neplatna instrukcia, alebo chyba segmentacie - jednoducho zacne v lepsom pripade vykonavat nieco, co nie je kod, v horsom pripade zacne citat pamat, ktora neexistuje. Zasobniku sa tolko venujem preto, lebo je pre vykonanie buffer overflow klucovy. Ako som napisal vyssie, ak PUSH a POP nie su sparovane, pri navrate z podprogramu sa precita namiesto navratovej adresy podprogramu (adresa instrukcie, ktora by sa mala vykonavat) nejaka somarina, ktora moze byt ina navratova adresa podprogramu o uroven vyssie, alebo docasne ulozene data na zasobniku z predoslej funkcie.

Uvazujme vsak, ze sa nam podari prepisat navratovu hodnotu v zasobniku tak, aby to bolo pre nas uzitocne (napriklad aby sa zacal vykonavat program na inom mieste, nez chceme). Tomtu aktu brani hned niekolko veci. V prvom rade program len tak sam od seba nepojde prepisovat zasobnik, pretoze to robit nepotrebuje a ani velmi nevie (pokial v kode programu nieco take nie je, tak to nie je v jeho silach), ak potrebuje pouzije instrukcie push a pop, nebude donho priamo sahat a jednak je dost tazke ho k tomu donutit. Aby sme ho k tomu nainstruovali, potrebovali by sme prepisat kod v kodovom segmente, ktory vsak nie je zapisovatelny, na zapis do kodoveho segmentu vsak potrebujeme prava kernelu (ked ich mame, je nam nanic utocit na obycajny program). Je to proste zacarovany kruh. Vsetky tieto obmedzenia platia, pokial predpokladame, ze kodovy, datovy a segment zasobnika sa v pamati neprekryvaju.

Uz v dokumentacii k procesoru Intel 80386 (rok 1986) sa pisalo, ze ak ma 386tka simulovat procesory, kde neexistuje segmentacia (napriklad procesory Motorola MC68000), segmentaciu sice nie je mozne vypnut, ale je mozne nastavit ju tak, aby sa procesor tvaril, ze ju nepouziva. Robi sa to tak, ze kodovemu, datovemu aj zasobnikovemu segmentu sa nastavi adresa ich zaciatku na adresu 0 (pociatok pamate) a velkost segmentu na 4GB (maximalna mozna velkost pri 32bitovych procesoroch). Tym sa efektivne odstavia vsetky mechanizmy kontrolujuce segmentaciu a nemoze dojst k vyvolaniu chyby na urovni segmentov. Tomuto pamatovemu modelu sa hovori flat memory model (kazdy program ma pristup k celej pamati procesora).

Prave flat memory model otvoril cestu k existencii buffer overflowu v spojeni s chovanim sa kodu napisaneho v jazyku C.

Flat memory model sa pouziva v zrejme valnej casti dnesnych operacnych systemov. Mohlo by sa na prvy pohlad zdat, ze nie je prilis bezpecny, lebo kazdy proces vidi celu pamat procesora, ale nie je tomu tak. Vdaka strankovaniu je mozne pamat virtualizovat a kazdemu procesu pridelit jeho vlastnu virtualnu pamat. Vyhodou oproti modelu segmetovanej pamate je v tom, ze kazdy program zacina na linearnej adrese 0 a nemusi brat v ohlad segmentove casti adries. Druhou nespornou vyhodou je, ze ak sa zavedie segmentacia aj strankovanie, vysledny memory managment je velmi komplikovany a je jednoduchsie starat sa o managment na urovni stranok, nez o managment na urovni segmentov (ako bolo spomenute vyssie, lahsie sa prideluju a uvolnuju bloky pamate pevnej velkosti, ako dynamickej velkosti a navyse stranky sa daju pridelovat za letu, ale to je uz ina rozpravka).

To je prvy z faktorov platformy. Vo vacsine operacnych systemov sa teda kod, data a zasobnik prekryvaju.

Druhym faktorom platformy je chovanie Cckovskych (ale zrejme aj inych reentranciu podporujucich programovacich jazykov) programov. Premenne sa totizto rozdeluju na globalne a lokalne. Lokalne premenne platia len v ramci jedneho volania funkcie, globalne premenne su pristupne v celom programe. Jazyk C vsak nezistuje, kolko krat po sebe (vnorene) sa funkcia zavola a ci nevola sama seba. V skutocnosti toto zrejme ani v rozumnej miere overovat nejde. Preto nemozu byt lokalne premenne funkcie ulozene na pevnom mieste v pamati (pri druhom volani funkcie, ak este predosle volanie neskoncilo, by sa data prepisali a program by zrejme padol).

Vhodnym miestom pre ulozenie tychto dat sa preto stava zasobnik. Do zasobnika ako takeho sa sice priamo nezapisuje, ale adresa niecoho v zasobniku je taka ista, ako adresa toho isteho v datovom segmente (a je taka ista, ako adresa niecoho v kodovom segmente). Programy preto vyuzivaju tzv. stack frames. Pri vstupe do podprogramu si tento vyhradi tolko miesta, kolko potrebuje na ulozenie lokalnych premennych a do tohto miesta potom cez datovy segment zapisuje. Vyhodou je, ze moze do zasobnika sucasne zapisovat cez datovy segment do lokalnych premennych a nadalej vyuzivat instrukcie push a pop (ktore operuju mimo tychto dat a z ich pohladu su to len data zasobnika a spravne napisany program sa k nim nedostane).

Poslednym faktorom platformy je chovanie sa zasobnika. So zasobnikom sa operuje vyhradne pomocou operacii PUSH a POP (ak opomenieme jeho inicializaciu). operacia PUSH do zasobnika vlozi udaj pevnej velkosti (obvykle 16, 32 alebo 64 bitov) a posunie vrchol zasobnika o tuto velkost hore. Pri tom sa neuchovava informacia o velkosti, ani adrese objektu, ktory tam bol ulozeny. To ani netreba, totizto data sa daju vytiahnut len z vrcholu zasobnika (netreba adresu, vrchol zasobnika je urceny systemovym registrom) a predpoklada sa, ze velkost objektu bude kod, ktory ho vybera, poznat. Zasobnik je vsak mierne postaveny na hlavu, totizto u zasobnika je dno (adresa 1. vlozeneho udaju) na vyssej adrese, ako vrchol (adresa posledneho vlozeneho udaju) zasobnika. Zasobnik "rastie" k nizsim adresam, to znamena, ze ak do zasobnika vkladame data, vrchol zasobnika smeruje k nule. Toto chovanie sa v minulosti vyuzivalo najma k zistovaniu pretecenia zasobnika. Nastavit velkost zasobnika, ktory rastie hore, by si vyziadalo zaviest register najvacsej povolenej adresy v zasobniku a vzdy ho overovat. To by skomplikovalo procesor, program a na lacnych platformach, ako 8051 a 8080 sa nenosilo. Preto sa zvolil opacny pristup. Pri starte programu sa nastavi vrchol zasobnika na nejaku adresu (vzhladom k tomu, ze v zasobniku nic nie je, je vrchol sucasne aj dnom zasobnika), pridavanim dat do zasobnika bude adresa vrcholu stupat a ked dosiahne 0, zasobnik je zaplneny a program padne (nic dalsie sa donho uz nezmesti). Nevyhodou bolo, ze nebolo ako zistovat podtecenie zasobnika (tahanie dat z prazdneho zasobnika), ale to zas nebol tak casty jav, ktory navyse vznikal len nespravne napisanym programom, zatial co pretecenia mohlo vzniknut aj nespravne nastavenym operacnym systemom.

Toto chovanie sa zachovalo, aj ked pri flat memory modeli sa nepouziva detekcia pretecenia zasobnika tymto sposobom, ale nejako inak (netusim, ako).

Opacny rast zasobnika sposobi, ze ak zapisujeme do oblasti zasobnika nieco, co je vacsie, nez miesto pre to vyhradene a pretecie nam to cez buffer, prepise nam to veci, ktore boli v zasobniku skor, ako bol vyhradeny stack frame. Je to sposobene tym, ze hoci je buffer v oblasti zasobnika, ta stale rastie smerom k vyssim adresam. Tam sa nachadza aj navratova hodnota z funkcie, kedze stack frame si tvori funkcia a navratovy kod zapisuje do zasobnika procesor pred spustenim funkcie.

Ak sa na situaciu pozrieme teraz, vidime, ze mame program, ktory "zapisuje do zasobnika", cize ak ho prinutime prepisat navratovu adresu, moze program skocit na lubovolne miesto, kam my chceme. Mame teda moznost prinutit program k tomu, aby zmenil svoj obvykly tok, to je nam vsak nanic, ak mu nemozeme prikazat robit nieco, co normalne nerobi, preto musime do programu pred samotnym prepisom navratovej adresy tento kod dostat a potom sa donho "vratit".

Pri tomto injektovani kodu do programu je hlavnym pomocnikom fakt, ze jazyk C si bezne nestrazi rozsahy poli a adresa dat v datovom segmente je rovnaka ako adresa tych istych dat v zasobniku a je rovnaka ako adresa tych istych dat v kodovom segmente. To dava moznost pouzit data ako obsah zasobnika, alebo vykonatelny kod.

Kedze sa mi tu ta teoria mierne (neplanovane) rozflakla, na tomto mieste to ustrihnem. Dalsia cast sa bude venovat praktickejsej ukazke toho, ako nevinne taky buffer overflow moze vzniknut, co vsetko sa nim da dosiahnut a nejake doplnkove informacie. Bude sa mihat takymi obskurnostami, ako vykonavanie dat, prepis kodu, skok na zasobnik, ktore su v tazkom rozpore s tym, co bolo povedane vyssie, ale ukaze sa, ze co je teoreticky nemozne, je v skutocnosti relativne lahko vykonatelne.

    • re: 18.01.2007 | 16:47
      disorder   Návštevník

      > aj ked pri flat memory modeli sa nepouziva detekcia pretecenia zasobnika tymto sposobom, ale nejako inak (netusim, ako).

      AFAIK sa stack nerozsiruje podla potreby a preto sa to zisti jednoducho pomocou exception (nesie info o pouzitom segmentovom registri), ked sa pokusas zapisovat do neexistujucej stranky...

      ---
      Windows NT was supposed to hit Unix hard. It did - like a bug hitting a windshield.

      • to je mozne... ak sa pokusi 18.01.2007 | 17:00
        Avatar blackhole_ventYl   Používateľ

        to je mozne... ak sa pokusi proces pristupit k stranke, ktora je pod stropom zasobnika, bude proces zostreleny, lebo ak potial naalokoval data, tak ich naalokoval prilis vela a ak potial naalokoval zasobnik, tiez toho uz ma dost... k tomu by prispel aj fakt, ze program, ktory prehuli zasobnik, zleti so segmentation fault chybou...

        neskumal som, ale je to vcelku pravdepodobny scenar...

        ---
        Cuchat s nadchou, to je ako sniffovat bez promiscu.

        --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
    • si to tlacim prave,taze 18.01.2007 | 18:16
      zero0x   Návštevník

      si to tlacim prave,taze dufam ze to bude stat za to :)

      inac pekne dlhy clanok, take daco sa hodi - jemny uvod

    • real vs. secured 18.01.2007 | 22:46
      srigi   Návštevník
      Pises, ze mame dva druhy memory modelu: segment a page, jo? Ale potom pises, ze segment nie je mozne vypnut, co sa mi nezda. Mal by si trocha pokecat o realnom a chranenom mode i386. A prave to sa mi zda, ze v chranenom rezime mame memory model 0 - 4GB, linearne, cize page model. Fakt sa segment model neda vypnut, sak to je prezitok z 20 storocia.
      • Inak super clanok, len to 18.01.2007 | 22:47
        srigi   Návštevník
        Inak super clanok, len to real vs. chraneny mi chyba na UVOD.
        • no ano, ono to tam tak 18.01.2007 | 23:03
          Avatar blackhole_ventYl   Používateľ

          no ano, ono to tam tak trochu chyba, ale jaksi toto nie je clanok o tom, ako pracuje pamatovy subsystem i386-compatible, ale o buffer overflow vulnerability a tieto informacie boli tak trocha podstatne dolezite k plnemu pochopeniu vzniku tohto javu :)

          ---
          Cuchat s nadchou, to je ako sniffovat bez promiscu.

          --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
      • segmentacia a paging 18.01.2007 | 23:01
        Avatar blackhole_ventYl   Používateľ

        ako vsetci vieme, i686 a cele x86_64 je spatne plne kompatibilne s i386, takze budem citovat casti Intel 386 Programming reference manualu:

        5.3.1 "Flat" Architecture

        When the 80386 is used to execute software designed for architectures that don't have segments, it may be expedient to effectively "turn off" the segmentation features of the 80386. The 80386 does not have a mode that disables segmentation, but the same effect can be achieved by initially loading the segment registers with selectors for descriptors that encompass the entire 32-bit linear address space. Once loaded, the segment registers don't need to be changed. The 32-bit offsets used by 80386 instructions are adequate to address the entire linear-address space.

        Je to v podstate presne to, co som pisal... segmenty sa nastavia tak, aby BASE segmentu bolo 0, limit bol 2^32 -1 a tym padom je segmentacia efektivne odstavena a operacny system uz riesi iba paging. To ale stale znamena, ze kazdy proces ma svoju privatnu LocalDescriptorTable a ze existuje Interrupt Descriptor Table a kvoli task gates v nom obsiahnutym musi existovat aj Global Descriptor table s niekolkymi deskriptormi pre prechod do PL0 na uroven kernelu (ale to sa deje najskor jedine vnutri kernelu, ked takuto privilegovanu operaciu treba robit, lebo prepnutie kontektu procesu cez task gate je casovo dost narocna operacia).

        Segmentacia existuje v i386 asi jedine kvoli spatnej kompatibilite s 8086, kde nebolo mozne delenie pamati riesit inac, nez segmentaciou, pretoze ten procesor nemal ziadne deskriptorove registre, ani mapovaci subsystem, tak to vyriesili salamunsky... (Segment<<4)+Offset.

        ---
        Cuchat s nadchou, to je ako sniffovat bez promiscu.

        --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
        • otazka 18.01.2007 | 23:20
          srigi   Návštevník
          Zjednodusene, prepnutie do chraneneho rezimu na i386 = nastavenie flat memory modelu + nejaky workaround?
          • segment 18.01.2007 | 23:25
            srigi   Návštevník
            A jasne segmentovanie je z dovodu, ze 8086 bola nepravy 16b procesor, mala 16b datovu zbernicu ale iba 8b adresnu. Tak to tusim bolo. Uz si neviem presne spomenut, ale k adresovaniu 1MB je potrebne 20 bitov a tam bol prave ten workaround.
            • ani nie :))))) 8086 mala 19.01.2007 | 13:15
              Avatar blackhole_ventYl   Používateľ

              ani nie :))))) 8086 mala 16bitovu datovu a 20bitovu adresnu zbernicu :)))))

              ak by mal procesor 8bitovu adresnu zbernicu, tak by to mal dost nadraka... 8bitovu adresnu zbernicu mal tusim jedine intel 4004, co bol 4bitovy procesor... schopny adresovat 256 bytov pamati...

              a nebol to workaround k tomu adresovaniu, ale skor k tomu, aby bolo mozne vytvorit jednoduchy procesor. vacsina komplexnych procesorov tej doby podporovala ochranu pamate a paging, co ale pri 360 kB RAM (ktorymi disponovali prve pecka) znamenalo alokovat velke page directories, page tables, descriptor tables, interrupt descriptor tables a potobne ptakoviny, ktore by efektivne tych okolo 100 kB zabrali a navyse by skomplikovali operacne systemy na nich beziace... preto to vyriesili takto jednoducho.

              ---
              Cuchat s nadchou, to je ako sniffovat bez promiscu.

              --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
          • ehm... 19.01.2007 | 13:06
            Avatar blackhole_ventYl   Používateľ

            nie... v realnom aj chranenom mode _VZDY_ plne funguje segmentacia, tu odstavit nemozes. Segmentacia je by default, mozes si akurat ako doplnkovy navolit flat memory model. Budem to teraz popisovat krok za krokom pre prechod z realneho rezimu do chraneneho, bez pouzitia LDT a IDT:

            1. nastavis si GDT s minimalne troma deskriptormi (jeden pre kod /CODE_DESCRIPTOR/, jeden pre data /DATA_DESCRIPTOR/ a jeden pre zasobnik /STACK_DESCRIPTOR/) vsetky budu mat base = 0 a limit = 4GB.

            2. zapnes protected mod (to akurat znamena, ze procesor v pripade potreby zacne pouzivat GDT, LDT, IDT a ochranu pamate, toto samotne este nenacita deskriptory z GDT)

            3. urobis daleky skok na CODE_DESCRIPTOR:FLAT_ENTRY. Skok musi byt daleky, aby sa do CS registra nacital deskriptor kodoveho segmentu a nesmie to byt volanie funkcie, lebo return by sa pokusal o navrat cez adresu realneho rezimu.

            4. do registra DS loadnes DATA_DESCRIPTOR.

            5. do registra SS loadnes STACK_DESCRIPTOR a v dalsom kroku nastavis SP tak, aby ukazovalo na dno zasobnika (nejake velke cislo).

            6. program ma momentalne k dispozicii FLAT memory model.

            segmentacia stale funguje, ale vdaka tomu, ze sa segmenty prekryvaju a pokryvaju celu pamat, nemoze vzniknut ziadna chyba zalozena na segmentacii (segmentation violation, segmentation fault, segment not present a dalsie).

            pri datovych operaciach sa defaultne v chranenom rezime pracuje v ramci segmentu DS, ak nie je povedane prefixom inak, stack sa defaultne pri instrukciach POP a PUSH riesi v ramci SS segmentu a kod sa vykonava jedine v CS segmente. Tzn. ze pri takto nastavenych deskriptoroch sa z i386 stava platforma, ktora akokeby segmentaciu nemala, ale _ONA TAM STALE JE_.

            ---
            Cuchat s nadchou, to je ako sniffovat bez promiscu.

            --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
        • re: 19.01.2007 | 15:58
          disorder   Návštevník

          > To ale stale znamena, ze kazdy proces ma svoju privatnu LocalDescriptorTable

          je nejaky dovod aby mal kazdy proces vlastnu LDT? nikdy som nepocul o tom, ze by LDT bola pre nieco povinna...

          ---
          Windows NT was supposed to hit Unix hard. It did - like a bug hitting a windshield.

          • vlastne nemusis pouzit LDT, 19.01.2007 | 16:49
            Avatar blackhole_ventYl   Používateľ

            vlastne nemusis pouzit LDT, ak mas privatny page directory, pretoze ti stacia GDT descriptory... ale podla povodneho zamyslania intelu mali LDT umoznit oddelenie jednotlivych procesov, pretoze jeden proces nemoze inemu vidiet do segmentov, ktore su v inej LDT.

            zalezi od implementacie...

            ---
            Cuchat s nadchou, to je ako sniffovat bez promiscu.

            --- Cuchat s nadchou, to je ako sniffovat bez promiscu.
            • > ak mas privatny page 19.01.2007 | 17:51
              disorder   Návštevník

              > ak mas privatny page directory, pretoze ti stacia GDT descriptory...

              presne

              ---
              Windows NT was supposed to hit Unix hard. It did - like a bug hitting a windshield.

    • ....:-)... 20.01.2007 | 19:35
      WLXok   Návštevník

      Celkom v pohode clanocek na to ze som akurat pred skuskou z Assemblerov tak si to aspon zopakujem a uz sa tesim na pokracovanie dufam ze bude co najskor...:-)