De fleste operativsystem idag kjører med 32-bits addressering, noe som betyr at prosessoren kan adressere opp til 4gb virtuellt minne. Dette betyr ikke nødvendigvis at de kan adressere 4gb fysisk minne men la oss idag se på hvordan en 32 bits virituell addresse er bygd opp og hvordan disse igjen blir oversatt til en fysisk adresse.
En 32-bits addresse er delt inn i 3 hoveddeler de 10 første bitene benyttes til noe som kalles Page Directory Index som brukes til å finne den rette sidevekslings tabellen som inneholder PTE'en som tilhører den virituelle addressen. PTE står for Page Table Entry som er den strukturen som inneholder den fysiske addressen som den virituelle er mappet til.
Deretter består de neste 10 bitene av addressen av en struktur som kalles Page Table Index som har en peker til selve PTE'en i den aktuelle sidevekslingstabellen.
Tilslutt har man altså 12 gjenstående bit'er som er da avsatt til Byte Index som peker til den aktuelle addressen innenfor den fysiske siden.
Måten Windows leter frem til den fysiske adressen er slik at først letes prosessens Page Directory frem. Noe som skjer hvergang prosessoren gjør et context switch, og lagres typisk i et spesielt prosessor-register. (CR3 på X86) Deretter vil pekeren i Page Directory Index (10 første biter av addressen) vise til hvor den kan finne Page Directory Entry (PDE) som da igjen peker til det aktuelle sidevekslingstabellen. PDE er da en struktur som inneholder et såkalt Page Frame Number (PFN) som skal samsvare med det i sidevekslingstabellen.
Videre brukes da pekeren i Page Table Index (Neste 10 biter) som viser til lokaksjonen til den aktuelle PTE oppføringen. Deretter vil PTE brukes for å finne den fysiske addressen. Hvis PTE'en er gyldig vil den inneholde PFN'en til siden i det fysiske minnet som refererer til den virituelle addressen.
Hvis PTE'en peker til en gyldig side vil da Byte Index (Siste 12 biter) brukes for å finne ut hvor i den aktuelle siden dataen som skal hentes er.
For å forstå litt bedre hvordan denne prosessen fungerer kan det være greit å gå gjennom trinnene manuelt med en kjerne-debugger.
Vi tar da først utgangspunkt i prosessen msnmsgr.exe:
0: kd> !process
PROCESS 89f61270 SessionId: 0 Cid: 0d78 Peb: 7ffdb000 ParentCid: 03e4
DirBase: 0a960460 ObjectTable: e3fbe628 HandleCount: 866.
Image: msnmsgr.exe
Vi ser at Dirbase peker mot den fysiske addressen til Page Directoryen, som vi vet skal operativsystemet installere CR3 registeret med denne addressen slik at prosessoren vet hvor den skal finne Page Directory, la oss dumpe ut CR3 registeret for å sjekke at dette stemmer:
0: kd> r cr3
cr3=0a960460
La oss da ta utgangspunkt i den virtuelle addressen til et Hendeles-objekt i msnmsgr som har addresse 89809a30.
Konvert til bit blir det til 1000100110 0000001001 101000110000 og som vi vet skal de 10 første bitene er Page Directory Index som peker til den spesifikke PDE som har addressen til den spesifikke sidevekslingstabellen.
Page Directoryen ligger da altså på 0a960460 og vi har en Page Directory Index på 226 noe som igjen betyr at PDE ligger på fysisk addresse 0a960686
Vi kan da videre kalkulere oss frem til riktig PTE ved denne formelen:
Sidevekslingstabellbase (0XC0000000 på standard x86 systemer uten PAE)
+ Page Directory Index*størrelsen på en side(4kb på et x86 system)
+ Page Table Index*størrelsen på en PTE (4bytes på et x86 system)
= PTE
La oss kalkulere oss frem til addressen til PTE med denne formelen.
0XC0000000
+ 0X0044C000 (0X226*0X1000*2)
+ 0X00000048 (0X9*4*2)
= 0XC044C048
Som du ser har jeg i tillegg multiplisert resultatene med to, dette er fordi systemet har 2 prosessorer.
Vi kan sjekke om vi har funnet korrekt PTE ved å bruke !pte utvidelesen med en virtuell adresse:
0: kd> !pte 89809a10
VA 89809a10
PDE at 00000000C0602260 PTE at 00000000C044C048
contains 0000000009687963 contains 0000000008A51963
pfn 9687 -G-DA--KWEV pfn 8a51 -G-DA--KWEV
Vi kan videre dumpe ut innholdet av PTE'en: (Fremdeles 4 byte)
0: kd> dd 0C044C048 l1
c044c048 08a51963
PTEen inneholder to strukturer-de første 20 bitene er PFN mens de resterende 12 er avsatt til status flagg. For å finne den fysiske siden i minnet multipliserer vi PFN med størrelsen av en side (fremdeles 4kb) noe som gir oss adressen 08A51000. Dette er da bare basen på siden den fysiske siden. For å finne den eksakte adressen til hvor dataen ligger lagret bruker vi bare Byte indexen i den virtuelle adressen og adderer den med basen på den fysiske siden, noe som da gjør at vi ender opp med den fysiske adressen 08A51A30. La oss dumpe ut dataen som ligger her:
0: kd> !dc 8A51A30
# 8a51a30 aa044a01 00000000 8a288120 8a288120
# 8a51a40 0a060006 20646156 00003750 0000375f
# 8a51a50 89c27188 8979cbc0 8979c590 07100001
# 8a51a60 8a06dcc0 e1b97438 fffffffc 40000000
# 8a51a70 00020006 20646156 8a1169d0 89b30a18
# 8a51a80 0a060002 20646156 00000130 00000132
# 8a51a90 8a2cdc50 00000000 00000000 01400000
# 8a51aa0 8a126c58 e10b5d98 e10b5da8 41000000
La oss sammenligne dette med dataen i den virtuelle adressen:
0: kd> dc 89809a30
89809a30 aa044a01 00000000 8a288120 8a288120
89809a40 0a060006 20646156 00003750 0000375f
89809a50 89c27188 8979cbc0 8979c590 07100001
89809a60 8a06dcc0 e1b97438 fffffffc 40000000
89809a70 00020006 20646156 8a1169d0 89b30a18
89809a80 0a060002 20646156 00000130 00000132
89809a90 8a2cdc50 00000000 00000000 01400000
89809aa0 8a126c58 e10b5d98 e10b5da8 41000000
Vi ser da at dataen er identisk, vi kan med andre ord konkludere med at vi har lykkes i å konvertere en virtuell adresse til en fysisk adresse i minnet. Håper dette var nyttig for å forstå hvordan Windows konverterer minne!
Abonner på:
Legg inn kommentarer (Atom)
Ingen kommentarer:
Legg inn en kommentar