Korzystanie z resload_Protect#?
Teoria
Istnieje wiele sytuacji, w których może być bardzo użyteczne zdobycie
informacji kiedy zainstalowany program próbuje dostać się do specyficznych
obszarów pamięci.
Przy pomocy funkcji resload_Protect#?
jest możliwa chrona pewnych obszarów pamięci przed zapisem i/lub odczytem.
Ochrona oznacza tyle, że każdy dostęp do takiego chronionego obszaru wygeneruje
wyjątek błędu dostępu, który zostanie wyświetlony w stosownym komunikacie.
Jeżeli zadeklarujemy obszar pamięci jako chroniony, wykorzystanie funkcji
resload_Protect#? spowoduje, że
WHDLoad zmodyfikuje opisującą stronę pamięci w drzewo tłumaczeń MMU.
Od teraz każda próba dostępu procesora do chronionej strony pamięci wygeneruje
wyjątek błędu dostępu. WHDLoad i jego wewnętrzne procedury zweryfikują powód
wystąpienia wyjątku. Jeżeli powodem był dostęp do chronionej
strony pamięci, lecz dostęp nie odpowiada chronionemu
obszarowi, dostęp zostanie zaemulowany i program będzie wykonywany dalej.
W przeciwnym wypadku WHDLoad powróci do systemu ze stosownym komunikatem.
Jeżeli dostęp był dostępem do strumienia instrukcji (procesor próbuje
załadować kod), zawsze nastąpi emulacja. Innymi słowy funkcja
resload_Protect#? oddziałuje tylko
na odczyt i zapis danych. W rzeczywistości każdy dostęp do chronionej strony
pamięci (rozmiar strony pamięci obecnie wynosi $1000) utworzy błąd dostępu,
nawet wtedy, gdy chroniony obszar ma rozmiar 1 bajta.
Przykład
Jeżeli instalujesz grę przy pomocy pakietu WHDLoad, musisz załatać oryginalny
kod wczytujący gry w taki sposób, aby skorzystał on z WHDLoada do wczytywania danych.
Niektóre gry sprawdzają sumy kontrolne pewnych obszarów kodu, aby wykryć,
czy oryginalny kod był modyfikowany. Czasami jest je ciężko znaleźć.
Wykorzystując funkcję resload_Protect#?
nie ma nic prostszego. Należy tylko chronić bajty, które się zmieniało w kodzie
gry. Od teraz każda procedura, która próbuje sprawdzić sumę kontrolną i odczytuje
Twój zmodyfikowany kod, wygeneruje błąd dostępu, a Ty już będziesz wiedział,
gdzie ona się znajduje.
Ograniczenia
Nie wolno chronić stron pamięci, na których znajdują się punkty SSP. Jeżeli tak
zrobisz, nastąpi "wyjątek", którego efektem będzie "podwójny błąd szyny", gdyż
procesor nie będzie w stanie zapisać ramki stosu wyjątku.
Po "podwójnym błędzie szyny" należy wykonać reset. WHDload
sprawdza, czy występują konflikty pomiędzy chronionymi obszarami, a SSP,
i w takim przypadku przerywa działanie, lecz to nie pomoże, jeśli SSP
zostanie zmieniony później.
- 68020 + 68851
- ten sprzęt nie jest obecnie obsługiwany
- 68030
- Transfery trzybajtowe nie są obsługiwane i wygenerują błąd dostępu. Takie
transfery mają miejce przypadku, gdy występuje dostęp do długiego słowa na nieparzystym adresie
granicy strony pamięci (np. "
tst.l ($fff)
" gdzie strona jest na $1000 i jest chroniona).
- Blokowane transfery powodowane przez
tas
, cas
lub cas2
nie są obsługiwane
i wygenerują błąd dostępu. Nie jest to dużym problemem, gdyż blokowane transfery
nie występują na Amidze.
- 68040
- Ten sprzęt nie jest obecnie obsługiwany.
- 68060
- Dostępy do nieuporządkowanych strumieni danych nie są obsługiwane
i wygenerują błąd dostępu. Nieuporządkowany dostęp jest to dostęp, który
rozciąga się między dwoma stronami pamięci (z czego co najmniej jedna
z nich jest chroniona). Dla przykładu "
tst.l ($ffe)
"
oddziałuje na stronę $0..$fff i stronę $1000..$1fff. Takie ograniczenie jest
prawdziwym problemem i spowoduje, że wykorzystanie funkcji
resload_Protect stanie się czasami bezużyteczne. Może w przyszłości
spróbuję dodać obsługę tego, lecz będzie to bardzo trudne.
- Dostępy do nieuporządkowanych strumieni instrukcji nie są obsługiwane
i wygenerują Access Fault jeżeli obie strony pamięci są chronione. Zazwyczaj
taka sytuacja jest unikana, ale zdarzają się takie przypadki.
- Blokowane transfery powodowane przez
tas
lub cas
nie są obsługiwane
i spowodują Access Fault. Nie jest to duży problem, gdyż blokowane
transfery w żaden sposób nie są obsługiwane przez amigowy sprzęt
- Instrukcje znajdujące się na chronionej stronie pamięci (i z tej też racji będą emulowane)
i próbujące zapewnić sobie dostęp do rejestru statusu z poziomu nadzorcy
będą wykonane nieprawidłowo. Takie instrukcje zawsze rozpoznają śledzone bity
jako bity z przypisaną wartością 1 i priorytetem maski przerwań jako 7. Jakiekolwiek
zmiany z poziomu nadzorcy pozostaną bez efektu (niezmienione).
- Instrukcja
movem
może próbować dostępu do chronionego
obszaru bez wygenerowania błędu dostępu. Jest to możliwe ponieważ tylko pierwsza
próba dostępu (słowo lub długie słowo) jest sprawdzane pod kątem pasowania do chronionego obszaru.
- Instrukcja
move16
i operacje podwójnej precyzji (FPU) nie są obsługiwane
i wygenerują błąd dostępu.
- Instrukcja "
move (mem),(mem)
" z zachodzącym na siebie adresem źródłowym
i docelowym generuje błąd dostępu z powodu nieuporządkowania. Dla przykładu
"move.l ($ffc),($ffe)
", gdzie strona $1000..$1fff jest
chroniona, pamięć przed wykonaniem zawiera ($ffc)=$11112222, ($1000)=$33334444, a po
wykonaniu $1000 zawiera $11114444 a nie $22224444