[ Pobierz całość w formacie PDF ]
0018 TSS32 C000D7A4 00002069 0 P B
0020 Data16 C0F39000 00000FFF 0 P RW
0028 Code32 00000000 FFFFFFFF 0 P RE
0030 Data32 00000000 FFFFFFFF 0 P RW
003B Code16 C0F84800 000007FF 3 P RE
0043 Data16 00000400 000002FF 3 P RW
0048 Code16 0000AE00 0000FFFF 0 P RE
0050 Data16 0000AE00 0000FFFF 0 P RW
0058 Reserved 00000000 0000FFFF 0 NP
0060 Reserved 00000000 0000FFFF 0 NP
0068 TSS32 C001BF5C 00000068 0 P
0070 Data32 00000000 FFFFFFFF 0 P RW
0078 Data16 C000F80E 00000003 0 P RW
0083 Data16 00000000 FFFFFFFF 3 P RO
008B Data32 80001000 00000FFF 3 P RW
0093 Code32 C002F3A9 FFFFFFFF 3 P RE ED
009B Code32 C002F3A9 000000FF 3 P RE
00A3 Data32 00000000 FFFFFFFF 3 P RW
00A8 Code32 C01834BC 00001000 0 P RE
00B0 Code32 C01834AD 00001000 0 P RE
00BB Data16 00000522 00000100 3 P RW
00CB Data32 80003000 00000FFF 3 P RW
00D0 LDT 80004000 00005FFF 0 P
00DB Data32 80014000 00000FFF 3 P RW
00E3 Data32 80015000 00000FFF 3 P RW
00EB Data32 80016000 00000FFF 3 P RW
...
026B CallG32 0028:004026FC 3 P
Widać w niej, że w systemach rodziny Windows 32-bitowy kod jest pod selektorem 28, a dane pod
selektorem 30. Kiedy widzimy adres typu 0028:0041F36B to wiemy, że 0028h jest tak zdefiniowanym
selektorem do tablicy deskryptorów a 0041F36B jest adresem efektywnym. Odczytując odpowiednia pozycję
z GDT (selektor 28) widzimy, że adres ten pokazuje na segment kodu (Code32), atrybuty to potwierdzają, są
ustawione na RE read i execute.
Struktura rejestru segmentowego:
15 3 2 1 0
SELEKTOR TI RPL
SELEKTOR jest indeksem deskryptora (13-bitów daje 8192 możliwych deskryptorów)
TI Table index - określa z jakiej tablicy odczytywać deskryptory
0 Globalna tablica deskryptorów
1 - Lokalna tablica deskryptorów
RPL Request Privilege Level, określa poziom uprzywilejowania selektoru. Pole 2-bitowe, co pozwala
numerować 4 poziomy uprzywilejowania (ring0,1,2,3)
40
Opis elementów globalnej tablicy deskryptorów wskazywanej przez rejestr GDTR:
Struktura deskryptora segmentu kodu (Code):
31 16 15 0
A D
adres rozmiar adres
G D 0 S 1 C R A
V P P
bazowy 31:24 segmentu 19:16 bazowy 23:16
L L
adres rozmiar
bazowy 15:0 segmentu 15:0
Opis bitów:
G granularity:
0 rozmiar segmentu w bajtach (max 1MB)
1 rozmiar segmentu w 4kB stronach (max 4GB)
D default
0 tryb chroniony 16-bitowy
1 tryb chroniony 32-bitowy
S system:
0 slektor systemowy
1 selektor segmentu kodu lub danych
AVL- available, definiowany prze użytkownika, nie wykorzystywany i nie modyfikowany przez CPU
C conforming, bezpośredni dostęp do segmentu z niższego poziomu użytkownika
0 zablokowany
1 - możliwy
R readable
0 segment może być tylko wykonywalny (E)
1 segment może być wykonywalny i odczytywany (RE)
A accessed
1 nastąpiło odwołanie do danych (kodu) z danego segmentu. Bit ten służy do monitorowania
wykorzystywania danego segmentu
P present
0 segment musi zostać załadowany z zewnętrznej pamięci (np.HDD) przez system pamięci
wirtualnej
1 segment znajduje się w pamięci RAM
DPL descriptor privilege level, dwa bity określające poziom uprzywilejowania deskryptora i związanego
z nim segmentu
Dla aktualnie wykonywanego segmentu kodu bity te określają CPL (current privilege level) bieżący
poziom upzywilejowania.
Bezpośredni dostęp do segmentu kodu jest możliwy wtedy i tylko wtedy gdy:
- CPL = DPL
- CPL > DPL (dostęp z poziomu mniej uprzywilejowanego) jeżeli segment kodu do którego
następuje odwołanie jest zgondy.
Struktura deskryptora segmentu danych (Data)
31 16 15 0
A D
adres rozmiar adres
G B 0 S 0 E W A
V P P
bazowy 31:24 segmentu 19:16 bazowy 23:16
L L
adres rozmiar
bazowy 15:0 segmentu 15:0
41
Opis niektórych bitów:
B big, dla odwołań stosu przyjmuje się:
0 rejestr SP 16-bitowy
1 rejestr ESP 32-bitowy (max rozmiar stosu 4GB)
E expand down:
0 standardowy rozszerzalny w górę segment danych
1 segment rozszerzalny w dół (używane dla segmentów stosu)
W - write enable
0 segment danych udostępniony tylko do odczytu
1 segment danych może być odzczytywany i zapisywany (RW)
Dostęp do segmentu danych jest możliwy wtedy i tylko wtedy gdy:
- DPL danego segmentu danych e" CPL
Struktura furtki wywołania (CallG)
Ich zadaniem jest transferowanie kodu programu pomiędzy różnymi poziomami uprzywilejowania. Są
wykorzystywane przez instrukcje CALL i JMP do wywołania fragmentu kodu znajdującego się w innym
segmencie.
31 16 15 5 4 0
D
przesunięcie liczba
0 1 1 0 0 0 0 0
P P
31:16 param.
L
seletkor przesunięcie
segmentu 15:0
Funkcja wywołania spełnia następujące funkcje:
- określa adres wywoływanej procedury (sgment:przesunięcie)
- definiuje wymagany poziom uprzywilejowania aby uzyskać dostęp do procedury
- określa liczbę parametrów przesyłanych do procedury (pole 5-bitowe zatem możliwych
paramterów jest 32 typu DWORD)
Dostęp do furtki wywołania jest możliwy wtedy i tylko wtedy gdy:
- DPL furtki e" CPL
Dostęp do segmentu kodu poprzez furtkę wywołania jest możliwy wtedy i tylko wtedy gdy:
- CPL e" DPL segmentu kodu
Przekazywanie sterowania przez furtkę wywołania:
wskaznik furtki wywołania (call gate)
SELEKTOR OFFSET
nie używany przez procesor
tablica deskryptorów
offset DPL param
Deskryptor wywołania
furtki
selektor offset
baza DPL baza
deskryptor segmentu
kodu
baza
+
adres startu procedury
42
[ Pobierz całość w formacie PDF ]