PROGRAMY REZYDENTNE Terminate and State Resident, TSR O co tu chodzi Podstawowe reguły Jak może program zostać rezydentnym Przechwytywanie przerwań Jak się samoznaleźć w pamięci Aktywacja TSR-u. Problemy z braku stabilności Korzystanie z pamięci Sytuacje konfliktowe Zakończenie Pytania
O co tu chodzi TSR z bliska Praca w tle Przechwytywanie przerwań Funkcje i zastosowanie: Draiwery sterowniki dla urządzeń wewnętrznych Monitory antywirusowe Warto zapamiętać: Na TSR-ach jest oparta duża część programów systemowych i aplikacyjnych konieczne jest przestrzeganie para reguł przy pisania TSR-ów Problematyka w tym wykładzie jest wspólna dla
Jak może program zostać rezydentnym Dla *.COM: INT 27H Wejście: DX adres początku części nierezydentnej; CS początek PSP Przykład: LEA DX,NO_RES INT 27H Dla *.EXE i *.COM: funkcja DOS-a 31H Wejście: АН 31Н, AL kod wyjścia, DX ilość paragrafów do załadowania Przykład: tsr1.asm
Przechwytywanie przerwań To już było... Ważne tu: korzystać z CALL albo JMP (dalekie) Pisać tak, aby To nie przeszkadzało innym programom, czyli pracować grzecznie w tle Przerwania 21h, 13h, 25h i 16h owszem da się je używać, jednak BARDZO ostrożnie! Używać PUSH/POP technikę na całego! Przed wywołaniem przerwania, wszystkie potrzebne rejestry mają zawierać to co zawierali one przed wejściu do Waszej procedury Przed wyjściem z Waszej procedury, te rejestry mają zawierać to co mieli przed wejściem do niej Przerwania sprzętowe 8 i 9 dbają o zachowanie rejestrów tam masz zadbać tylko o swojej ingerencji
Procedura obsługująca przerwania w TSR nr1 INT_N PPOC FAR ;chowamy rejestrów +rejestru znaczników PUSHF PUSH AX......;wykonujemy pracę ;i zwracamy zawartości rejestrów... PОР АХ POPF ;wołamy przerwania CALL DWORD PTR CS:OLD_INT_N ;chowamy rejestrów +rejestru znaczników PUSHF PUSH AX......;wykonujemy pracę ;i zwracamy zawartości rejestrów... PОР АХ POPF IRET INT_N ENDP
Procedura obsługująca przerwania w TSR nr2 INT_N PPOC FAR ;chowamy rejestrów +rejestru znaczników PUSHF PUSH AX......;wykonujemy pracę ;i zwracamy zawartości rejestrów... PОР АХ POPF ;wołamy przerwania JMP DWORD PTR CS:OLD_INT_N INT_N ENDP
Jak się samoznaleźć w pamięci CZYLI JAK ZDBAĆ ABY SIĘ 100 RAZY NIE ŁADOWAĆ = NIE ZAJMOWAĆ WIĘCEJ MIEJSCA NIŻ JEST POTRZEBNE Zewnętrzny markier Wewnętrzny markier (metoda funkcji pomocniczej ) Metoda skanowania bloków pamięci
Zewnętrzny markier W programie umieszczamy markier ze zwyczaj słowo, tuż przed wektorem przerwania Najprostszy sposób (+) Jeżeli inny program wykorzysta ten sam wektor, to już się program nie samoznależe (-)
;FRAGMENT CZĘŚCI INSTALACYJNEJ SPRAWDZA OBECNOŚĆ MARKIERA... MOV AX, 3508H INT 21H CMP WORD PTR ES:[BX-2],MARKIER JNE LADUJ... przykład ;FRAGMENT CZĘŚCI REZYDENTNEJ JEŻELI PROGRAM JUŻ ZAŁADOWANY, TO TA CZĘŚĆ JEST JUŻ W PAMIĘCI... MARKIER DW 12ABH INT_8 PROC FAR... INIT_8 ENDP...
Wewnętrzny markier (metoda funkcji pomocniczej ) Wykorzystać można jakąś nieistniejącą funkcję przerwania jakiegoś, np.. 21h, lub 16h itd.. No więc my ją nadpisujemy, a ona zwracać ma wartość (a la MARKIER) w danym rejestrze, np. AX (klasycznie :) I jak się funkcja TA wywoła (jasne że program nasz ma to zrobić część instalacyjna, oczywiście) sprawdzamy, wartość, przez niej zwracana, czyli nasz MARKIER Metoda jest o wielu bardzo stabilna, jednak czasami mogą się funkcje pokryć... (-)
Przykład ;FRAGMENT CZĘŚCI REZYDENTNEJ JEŻELI PROGRAM JUŻ ZAŁADOWANY, TO TA CZĘŚĆ JEST JUŻ W PAMIĘCI... INT16 PROC СМР АН,20Н JNZ CONT MOV АХ,789АН IRET CONT: JMP DWORD PTR CS:OLD16 INT16 ENDP... ;FRAGMENT CZĘŚCI INSTALACYJNEJ SPRAWDZA OBECNOŚĆ MARKIERA... MOV АН,20Н INT 16H CMP АХ,789АН JZ YES...
Metoda skanowania bloków pamięci Blok pamięci, nagłówek bloku,... Skanowane są wszystkie bloki szukamy naszego TSR-a Jest to najbardziej bezpieczną i wiarygodną metodę samolokalizacji się w pamięci. Jest nieco bardziej skomplikowana
Przykładowa procedura SCAN PROC PUSH BX PUSH DS PUSH DX PUSH SI ; w SI ładujemy segment aktualnego programu (nie rezydentnemu) MOV SI, CS ; znajdujemy pierwszy blok MOV AH, 52H INT 21H MOV ES, ES:[BX-2] ; ładujemy w ES segment MCB MOV AX, 1 LOO: CMP WORD PTR ES:[1], 0 ; JZ CONT5 PUSH ES POP BX INC BX ;czy ten segment? CMP SI,BX JZ CONT5 MOV DS,BX ; sprawdzamy nasz ZNACZNIK MOV BX, CS: ZNACZNIK CMP WORD PTR DS:[103H],BX ; tu offset zależy od naszego programu JZ _END CONT5: ; czy ten blok nie jest ostatni? CMP BYTE PTR ES:[0],'M ; - to nie ostatni blok JZ CONT4 ; (Z ostatni blok) XOR AX, AX JMP SHORT _END CONT4: ; znajdujemy adres nagłówka następnego bloku MOV DX, ES:[3] ; rozmiar bloku MOV BX,ES ADD BX, DX INC BX MOV ES, BX JMP LOO _END: MOV BX, ES INC BX MOV ES, BX POP SI POP DX POP DS POP BX RET SCAN ENDP
Aktywacja TSR-a. Problemy z braku stabilności Sprawdzanie klawisza/kombinacja klawiszów A z INT 21H?! Flag DOS-u (f 34H) To działa! Aby tylko odczekać na wyzerowania się znacznika! A jak uderzymy na funkcja oczekiwanie na klawisz!!!! A można przechwycić int 21h Więc jak mamy czekać na klawisz można sprawdzić bufor klawiatury i tylko wtedy pozwalać na pobierania, jak TAM coś będzie! Bufora można sprawdzić poprzez INT 16H, np.
???przykład INT21 РРОС FAR STI CMP АН,0АН JZ A1Z JMP SHORT A2Z A1Z: PUSH CX PUSH AX A3Z: MOV CX,OFFFFH A4Z: MOV AH,1 LOOP A4Z INT 16H JZ A3Z POР AX POP CX A2Z: MOV CS:FLAG_21,1 PUSHF CALL CWORD PTR CS: [OFF_21] MOV CS:FLAG_21,0 IRET INT21 ENDP
Korzystanie z pamięci /Jak zarezerwowania pamięć tak aby innym nie przeszkadzać/ Podstawowy sposób: Wewnątrz programu Zarezerwować sobie pod czas ładowania Wykorzystywanie pamięci wewnętrznej Dane na dysk Wybrać sobie obszar (oby tylko nie systemowy ;) Przy aktywacja TSR zastępujemy ten obszar własnymi danymi Dezaktywacja zwracamy stara zawartość!!! Wykorzystywanie dodatkową i rozszerzoną pamięć
Sytuacje konfliktowe Przy odinstalowania programu warto dobrze zadbać o wektorach przerwań! Funkcje 49h i 4Ah Sprawdzić czy do naszego programu nie wskazują wektory! Uważać na Stos!!! Problem ładowania się w trakcie pracy innego TSR-a! (korekcje w przerwania klawiatury!) Dbać o reżym ekranu czy pasuję do naszego TSR-a Praca z plikami przechwycić ewentualnie PSP przerwanego programu, żeby nie było kolizji..(f50h) Problemy z f59h (zamieszania w odczytu kodu błędu...)... Problem niestabilności MS DOS-a (system. stos: f5dh, al=6)
Jeszcze raz o tym samym.. PSP Punkt wejścia podczas ładowania programu Punkt wejścia podczas aktywizacji programu Main PROC JMP INIT Dane rezydentne Entry:...rozkazy rezydentne Main ENDP INIT PROC...Rozkazy...inicjalizacyjne MOV AH, 31H INT 21H INIT ENDP END Main Rezydentna część programu Część programu, odrzucana po instalacji