Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
BulgaraCeha slovacaCroataEnglezaEstonaFinlandezaFranceza
GermanaItalianaLetonaLituanianaMaghiaraOlandezaPoloneza
SarbaSlovenaSpaniolaSuedezaTurcaUcraineana

AdministracjaBajkiBotanikaBudynekChemiaEdukacjaElektronikaFinanse
FizycznyGeografiaGospodarkaGramatykaHistoriaKomputerówKsiążekKultura
LiteraturaMarketinguMatematykaMedycynaOdżywianiePolitykaPrawaPrzepisy kulinarne
PsychologiaRóżnychRozrywkaSportowychTechnikaZarządzanie

Przejmowanie przerwań i znajdowanie czystych wejść do systemu

komputerów



+ Font mai mare | - Font mai mic



DOCUMENTE SIMILARE

Przejmowanie przerwań i znajdowanie czystych wejść do systemu

6.1. Najczęściej przejmowane i wykorzystywane przerwania



Wirusy najczęściej wykorzystują i/lub przejmują następujące przerwania:

> 01h - Przerwanie trybu krokowego procesora, wywoływane wewnętrznie, gdy w rejestrze znaczników FLAGS jest ustawiony bit TF. Przerwanie Olh jest używane przez wirusy do poszukiwania w łańcuchu procedur obsługi przerwania jego ostatniego elementu, będącego przeważnie częścią DOS-a lub BIOS-a. W czasie wykonywania wyżej wymienionej operacji możliwe jest także przejęcie obsługi przerwania poprzez włączenie się w istniejący łańcuch obsługi przerwania, dzięki czemu nie trzeba modyfikować tablicy przerwań. Kontrola procedury obsługi tego przerwania pozwala wykryć uruchomiony debugger.

> 03h - Pułapka programowa (ang. breakpoint}, ze względu na 1-bajtową instrukcję (kod 0CCh) stosowana przez debuggery;

powyższa właściwość powoduje, iż instrukcję tę stosują bardzo krótkie wirusy do wywoływania pierwotnej procedury obsługi przejętego przez nie przerwania. Podobnie jak w przypadku przerwania numer 0lh, kontrolując INT 03h można wykryć włączony debugger.

> 08h - Przerwanie sprzętowe IRQ 0 - standardowo zgłaszane 18 razy na sekundę przez układ zegara 8253/8254 (częstotliwość generowania tego przerwania można zmienić programowo). Wewnątrz procedury jego obsługi znajduje się rozkaz wywołania przerwania 1Ch. Najczęściej używane jest ono do realizacji efektów specjalnych, rzadziej do autoweryfikacji wirusa.

> 09h - Przerwanie sprzętowe IRQ l, wywoływane po naciśnięciu lub puszczeniu klawisza na klawiaturze. Odczytany z portu 60h klawisz jest dekodowany przez funkcję (4F/15), a następnie umieszczany w buforze klawiatury, skąd dostępny jest później dla funkcji przerwania 16h. Podobnie Jak IRQ O, przerwanie 09h używane jest zwykle do efektów specjalnych i czasem do autoweryfikacji (na przykład kod wirusa jest sprawdzany przy każdym naciśnięciu lub puszczeniu klawisza).

> 10h - Przerwanie programowe BIOS obsługujące funkcje ekranu;

używane do efektów specjalnych lub w celu informowania innych kopii wirusa o obecności w pamięci.

> 12h - Przerwanie programowe BIOS zwracające po wywołaniu wielkość pamięci operacyjnej podaną w kilobajtach. Zwracana wartość jest odczytywana ze zmiennej systemowej BIOS, znajdującej się pod adresem 0000:0413. Przerwanie to wykorzystują głównie wirusy tablicy partycji i BOOT-sektorów, gdy zmniejszają ilość pamięci dostępnej dla systemu DOS. Aby tego dokonać, nie muszą jednak przejmować przerwania, a tylko zmodyfikować wyżej wymienioną zmienną BIOS. Czasem przerwanie 12h przejmowane jest w celu informowania innych kopii wirusa o obecności w systemie.

> 13h - Przerwanie programowe BIOS odpowiedzialne za obsługę dysków na poziomie sektorów. Obsługując dyskietki wywołuje przerwanie 40h. Jest ono używane najczęściej podczas infekcji

przez wirusy atakujące Główny Rekord Ładujący (MBR), BOOT-sektory i JAP. Jego przejęcie umożliwia zastosowanie techniki stealth dla sektorów, a także informowanie innych kopii wirusa o obecności w systemie.

> 14h - Przerwanie programowe BIOS odpowiedzialne za obsługę łączy szeregowych. Przechwytywane (choć rzadko) dla efektów specjalnych, polegających na przekłamywaniu odczytów7 i zapisów złącza.

> 15h - Przerwanie programowe BIOS odpowiedzialne za dodatkowe funkcje systemowe. Może być przejmowane dla efektów specjalnych, polegających na zmianie obsługi funkcji 4Fh. Powyższa funkcja jest wywoływana przez przerwanie sprzętowe IRQ l (09h) i odpowiada za dekodowanie klawiszy do postaci widzianej później przez przerwanie programowe int 16h. Godna uwagi jest także funkcja (9000/15), wywoływana przez procedurę obsługi przerwania sprzętowego IRQ 14 (76h), której przejęcie umożliwia zastosowanie techniki hardware-level stealth.

> 16h - Przerwanie programowe BIOS odpowiedzialne za obsługę klawiatury. Przejmowane najczęściej dla efektów specjalnych lub w celu informowania innych kopii wirusa o obecności w pamięci.

> 17h - Przerwanie programowe BIOS obsługujące drukarki. Przejmowane (choć rzadko) dla efektów specjalnych, polegających np. na fałszowaniu drukowanych znaków.

> 1Ch - Przerwanie wywoływane przez przerwanie sprzętowe IRQ 0 (08h), najczęściej przejmowane do celów efektów specjalnych (choć w tym wypadku lepiej przejąć obsługę przerwania IRQ 0).

> 21h - Przerwanie programowe DOS odpowiedzialne m.in. za obsługę dysków logicznych na poziomie plików, a także pamięci operacyjnej, czyli newralgicznych części systemu, stąd też jest ono najczęściej przejmowanym przez wirusy przerwaniem. Umożliwia infekcję plików przy ich otwieraniu, zamykaniu, czytaniu, zmianie nazwy, uruchamianiu itd. oraz pozwala na ukrywanie się w systemie. Ze względu na to, iż jest potrzebne wirusom do mnożenia się, nie wykorzystywane przez system numery funkcji często służą innym kopiom wirusa do sprawdzania jego

obecności w systemie (nie musi on już przejmować innego przerwania, gdyż wyżej wymieniona operacja wykonywana jest niejako przy okazji).

> 24h - Przerwanie programowe DOS obsługujące błędy krytyczne systemu. W wypadku wystąpienia błędu wywołuje ono standardowo tzw. dialog ARIF (skrót od ang. Abort Retry Ignore Fail), pozwalający użytkownikowi zadecydować, jaką podjąć operację. Przerwanie to wirusy przejmują na czas infekcji, aby w razie wystąpienia jakiegoś błędu wirus mógł sam zadecydować, jaką akcję chce podjąć. Nowa obsługa przerwania najczęściej zawiera dwie instrukcje nakazujące systemowi DOS sygnalizować błąd programowi wywołującemu (czyli wirusowi). Wyglądają one następująco:

Typowa procedura obs│ugi przerwania int 24h u┐ywana podczas infekcji

MOV AL,3 ; sygnalizuj b│╣d programowi (czyli wirusowi)

IRET ; powr≤t 2 obs│ugi przerwania

> 25h - Przerwanie programowe DOS odpowiedzialne za odczyt sektorów z dysków logicznych, czasem używane do ukrywania się w systemie, ale głównie do łatwego odczytywania BOOT-se-ktorów.

> 26h - Przerwanie programowe DOS odpowiedzialne za zapis sektorów na dyskach logicznych. Najczęściej używane jest do infekcji BOOT-sektorów. Zwykle wykorzystuj ą je konie trojańskie do destrukcji.

> 27h - Przerwanie programowe DOS. Umożliwia zakończenie programu z pozostawieniem kodu w pamięci. Używają go niektóre, zwłaszcza stare, programy TSR, nowsze korzystają z funkcji (31/21). Wykorzystując działanie tego przerwania lub funkcji (31/21) można napisać prostego wirusa rezydentnego.

> 28h - Przerwanie programowe DOS pozwalające na wykonywanie pewnych operacji w tle, co jest wykorzystywane m. in. przez program PRINT. Może być użyteczne do infekowania plików, gdy DOS nie jest zajęty żadnym zadaniem, tak jak robi to np. wirus DOS-IDLE.

> 2Fh - Przerwanie multipleksowane systemu. Ze względu na różnorodność wykonywanych funkcji umożliwia m. in. znajdowanie oryginalnej procedury przerwania 13h (13h/2F), informowanie innych kopii wirusa o obecności w systemie oraz infekcję plików przy ich zamykaniu. To ostatnie możliwe jest dzięki zastosowaniu funkcji (1216/1220/2F), operujących na systemowych tablicach SFT (ang. System File Table), w których zawarte są wszystkie parametry wskazywanego przez uchwyt pliku.

> 30h/31h - W tablicy przerwań, w miejscu, gdzie powinny być adresy obsługi tych przerwań znajduje się rozkaz dalekiego skoku do DOS w postaci 0EA 00 00 SS SS, gdzie OO OO to ofset, a SS SS to segment (po starcie systemu jest to segment kodu systemu DOS, ale może być podmieniony przez program antywirusowy). Adres wskazywany przez rozkaz skoku może być wykorzystywany do wywoływania funkcji DOS według przestarzałej konwencji CP/M, a także do zlokalizowania w segmencie kodu DOS adresu obsługi przerwania 21h, co umożliwia bezpieczne, omijające większość monitorów antywirusowych, wywoływanie funkcji DOS (metodę tę stosuje m.in. wirus DIR-2).

> 40h - Przerwanie programowe BIOS, które obsługuje dyski elastyczne. W większości BIOS-ów adres tego przerwania jest oryginalnym adresem przerwania 13h podczas inicjacji systemu. Podczas startu systemu BIOS przekierowywuje przerwanie 13h na 40h, o ile wykryje dysk twardy. Rzadko przejmowane; umożliwia dostęp do dyskietek z pominięciem przerwania 13h.

> 76h - Przerwanie sprzętowe IRQ 14, generowane przez sterownik dysku twardego przy wszelkich operacjach dyskowych. Obsługa przerwania polega na wykonaniu odczytu z portu 1F7h (rejestr stanu IDE) i wywołaniu funkcji (9000/15). Przejęcie jego lub funkcji (9000/15) umożliwia zastosowanie techniki hardware-level stealth do ukrywania się w systemie.

Jak widać, jest to znakomita większość wszystkich wykorzystywanych przez programy przerwań. Czasem, w celu zminimalizowania rozmiarów, wirus przejmuje dodatkowo jakieś nie używane przez system przerwanie (najczęściej powyżej numeru 60h), aby przy jego pomocy wywoływać pierwotny program obsługi jakiegoś przejętego przez siebie przerwania. Korzysta z tego, że maszynowy rozkaz wy-

wołania przerwania (INT ??) zawiera tylko 2 bajty (o kodach OCDh/??, gdzie ?? to numer przerwania), gdy tymczasem rozkaz wywołania pierwotnego programu obsługi za pomocą rozkazu wywołania procedury zajmowałby od 3 (wywołanie pośredniej, bliskiej procedury) do 6 bajtów (wywołanie dalekiej, bezpośredniej procedury). Przejęcie jakiegoś przerwania programowego może być także wykorzystywane do sprawdzania, czy wirus został już wcześniej zainstalowany w pamięci, co pozwala mu uniknąć powtórnej, niepotrzebnej instalacji. Sekwencja wykrywająca, czy wirus jest już zainstalowany, ma najczęściej postać:

MOV AX.HASśO ; najczΩ£ciej w AX podaje siΩ jak╣£ nie typow╣ funkcjΩ

INT xx ; xx - numer przerwania (najczΩ£ciej 21h)

CMP REJ,ODPOWIEDÅ ; czy wirus ju┐ zainstalowany (rej - najczΩ£ciej AX)

JE Ju┐Zainstalowany ; skok, gdy zainstalowany wirus zwr≤ci│ odpowiedƒ

; zainstaluj siΩ

Ju┐Zainstalowany: ; powr≤µ do nosiciela

Wiedza o najczęściej przejmowanych przerwaniach pozwala często na ręczne przejście przez łańcuch obsługi przerwania przy użyciu de-buggera i sprawdzenie po drodze, czy nie ma gdzieś kodu budzącego podejrzenia, prawdopodobnie należącego do wirusa. Przy takim sprawdzaniu należy pamiętać o kilku niebezpieczeństwach związanych z używaniem debuggera w systemie kontrolowanym przez wirusa. Wirus może kontrolować funkcję (4B01/21), służącą debugge-rom do ładowania programów. Jeżeli jest ona wywoływana, wirus może się deinstalować z pamięci lub podjąć jakieś inne działanie, maskujące lub destrukcyjne. Podobne niebezpieczeństwo grozi ciekawskiemu użytkownikowi ze strony niektórych, najczęściej destrukcyjnych wirusów, kontrolujących stan przerwania INT 01h i INT 03h, a te, jak wiadomo, używane są najczęściej przez programy uruchomieniowe. Zwykle po wykryciu, iż adres procedury obsługi któregoś z tych przerwań nie wskazuje na rozkaz IRET (czyli na pustą procedurę obsługi przerwania), wirus bądź blokuje komputer, bądź brutalnie niszczy dane na dysku twardym. Jeszcze inne niebezpieczeństwo

może grozić użytkownikowi ze strony wirusów, które potrafią sprawdzać poprawność swego kodu. Procedura autoweryfikacji może być wywoływana przez każde z niewinnych przerwań programowych, używanych powszechnie w oprogramowaniu (np.: 10h, 16h) lub też może być podczepiona pod któreś z przerwań sprzętowych. W przypadku wykrycia jakichś zmian (np, zły wynik obliczanej na bieżąco sumy korekcyjnej) wirus może natychmiast podjąć niemile dla użytkownika działanie odwetowe.

Na koniec warto jeszcze wspomnieć, iż zamiast przerwań niektóre wirusy rezydentne przejmują obsługę sterowników urządzeń blokowych, zajmujących się operacjami na urządzeniach masowych, takich jak dysk twardy czy dyskietka, w sposób analogiczny do programów umieszczanych w plikach SYS. Pozwala im to monitorować odwołania do dysków logicznych, zainstalowanych w systemie na poziomie pośrednim między systemem DOS i BIOS (jest to potrzebne np. przy infekcji polegającej na podmianie pierwszej JAP pliku). Tak przejęte odwołanie do systemu będzie dość trudne do wykrycia poprzez ręczne analizowanie kodu jakiegoś przerwania krok po kroku.

6.2. Wykorzystanie funkcji DOS

Najprościej przejąć obsługę przerwania używając dwóch przeznaczonych do tego celu funkcji DOS, tzn. (25/35/21) za pomocą poniższej sekwencji w asemblerze:

; Przejmowanie przerwa± za pomoce DOS-a

MOV AL, NUMER ; podaj w AL numer przerwania

MOV AH, 35h ; w AH numer funkcji, weƒ adres starej procedury

; obs│ugi przerwania

INT 21h ; wywo│aj funkcjΩ DOS po wywo│aniu funkcji

MOV [StarySEG],ES ; w ES:BX pobrany adres poprzedniej procedury

MOV [StaryOFS],BX ; obs│ugi, kt≤ry najczΩ£ciej zapamiΩtuje siΩ

MOV AH, 25h ; w AH numer funkcji, ustaw now╣ procedurΩ obs│ugi

; przerwania

MOV AL,NUMER ; w AL numer przerwania

MOV DS, SEG Nowa ; DS:DX zawiera adres do nowej procedury

MOV DX, OFFSET Nowa ; obs│ugi przerwania

INT 21h ; wywo│aj funkcjΩ DOS

Powyższy sposób przejmowania przerwań, zalecany przez twórców systemu DOS, ze względu na możliwość monitorowania funkcji (25/35/21) przez program antywirusowy, stosują najczęściej prymitywne wirusy. Bardziej wyrafinowane, używają metod trochę innych, omówionych poniżej.

6.3. Bezpośrednie zmiany w tablicy wektorów przerwań

Bezpieczniejszym (ze względu na programy antywirusowe) sposobem na przejęcie przerwania jest bezpośrednia manipulacja w tablicy wektorów przerwań, przy użyciu poniższej sekwencji w asemblerze, wykonującej w przybliżeniu to samo, co sekwencja z poprzedniego punktu:

: Przejmowanie przerwa± bezpo£rednio w tablicy przerwa±

MOV BL, NUMER ; w BL numer zmienianego przerwania

XOR BH,BH ; BX=BL

SHL BX,l ; pomn≤┐ je przez 4 (2 razy przesu± w lewo)

SHL BX,l ; jeszcze raz przesu± w lewo

XOR AX,AX ; zeruj rejestr AX

MOV DS,AX ; i z jego pomoc╣ zeruj rejestr segmentu DS

; DS:BX wskazuje na pozycjΩ w tablicy przerwa±,

; gdzie zapisany jest adres obs│ugi przerwania

LDS DX,DS:[BX] ; pobierz segment i offset przerwania (do

; zapamiΩtania)

MOV [StarySEG],DS ; zachowaj segment

MOV [StaryOFS],DX ; zachowaj offset

MOV DS,AX ; ponownie DS=0

CLI ; bezpiecznie zmieniaµ adres obs│ugi przerwania

; przy wy│╣czonych przerwaniach

MOV DS:[BXJ,OFFSET NOWA ; bezpo£rednie warto£ci wskazujΩ

; na adres nowej

MOV DS:[BX+2], SEG NOWE ; procedury obs│ugi przerwania

STI ; teraz mo┐na ju┐ w│╣czyµ przerwania

Oczywiście, w powyższej sekwencji można pominąć rejestr BX i podać offset w postaci absolutnej (np, jako 21h*4), jednak użycie rejestru umożliwia przejmowanie więcej niż jednego przerwania za pomocą tej samej procedury (należy zmieniać tylko wartość BL).

6.4. Włączanie się do istniejącego łańcucha obsługi przerwania i znajdowanie czystych wejść do systemu (ang. tunnelling

Dowolna modyfikacja w tablicy przerwań jest łatwa do wykrycia przez najprymitywniejszy nawet program antywirusowy, stąd też twórcy wirusów poszukiwali innej metody przejmowania przerwań, dzięki której nie trzeba modyfikować tablicy przerwań. Opracowano szereg metod polegających na włączaniu się do istniejącego łańcucha procedur obsługi przerwania, zwanych ogólnie tunelingiem.

Zainstalowany rezydentnie w pamięci wirus musi mieć możliwość wywoływania pierwotnej procedury przejętego przez siebie przerwania (np. podczas infekcji potrzebne są funkcje systemu obsługujące działania na plikach). Wywoływanie aktualnej (tzn. wskazywanej przez tablicę przerwań) procedury obsługującej dane przerwanie lub nawet tej, która została zapamiętana podczas instalacji wirusa w pamięci, grozi szybkim wykryciem przez monitor antywirusowy Najlepiej, gdy wywoływana przez wirusa procedura jest ostatnim elementem w łańcuchu procedur obsługi przerwania, czyli jest to po prostu oryginalna procedura zawarta w BIOS-ie lub DOS-ie.

6.4.1. Korzystanie ze stałych adresów w systemie (przerwania 21h i 2Fh)

Ta metoda tunelingu jest możliwa tylko w wersjach DOS powyżej 5.00. Służy ona do przechwytywania obsługi przerwania 21h i ewentualnie 2Fh (przy okazji znajdowany jest oryginalny adres procedury obsługi tego przerwania, ulokowanej w kodzie systemu DOS). Wykorzystuje ona fakt, iż system DOS posiada w swym pierwszym bloku MCB (oznaczonym jako systemowy) standardową sekwencję kodu (taką samą dla obu przerwań 2 h i 2Fh), która została przedstawiona poniżej.

Sekwencja kodu występująca w DOS od 5.0 wzwyż

DOS używa HMA

DOS nie używa HMA

Adres

Kod

Znaczenie

Kod

Znaczenie

SEG:OFS

NOP NOP

EB 03

JMP $+3

SEG:OFS+2

E8 xxxx

CALL [IP+xxxx]

E8 xxxx

CALL [IP+xxxx]

SEG:OFS+5

2E FF 2E yyyy

JMP FAR CS:[yyyy]

2E FF 2E

JMP FAR CS:[yyyy]

Dla przerwania 21h powyższa sekwencja kodu występuje pod adresem SEG:OFS, gdzie OFS jest równy 109Eh (w wersji DOS od 5.00 do 6,22) lub 0FB2h w wersjach powyżej 6.22 (np. DOS 7.0, występujący z systemem Windows 95).

W przypadku przerwania 2Fh OFS jest równy: 10C6h (dla DOS 5.00 - 6.22) i 0FDAh (dla wersji 7.00).

Wartość SEG jest wartością zwracaną przez funkcję 52h w rejestrze ES. Na podstawie powyższych danych łatwo odczytać adres pierwotnego adresu procedury int 21h, korzystając z następującej sekwencji:

MOV AH,30H ; funkcja - weƒ wersjΩ systemu

INT 21h ; wywo│aj funkcjΩ

XCHG AL,AH ; zabieg kosmetyczny - aby p≤ƒniejsze

; por≤wnanie by│o bardziej przejrzyste

MOV BX,109EH ; offset dla wersji 5.00 - 6.22

CMP AX,0500h ; czy wersja

JB NIEDZIAśA ; je£li tak, to tunneling nie dzia│a

CMP AX,0622h ; czy wersja wiΩksza od 6.22 ?

JB Wer5_6_22

MOV BX,OFB2h ; nowsze wersje DOS - inny offset

Wer5_6_22:

PUSH BX ; zachowaj offset na stosie

MOV AH,52h ; funkcja - podaj adres do LL

INT 21h ; wywo│aj funkcjΩ

POP BX ; teraz ES:BX wskazuje na sekwencjΩ z tabeli

CMP WORD PTR ES:[BX],9090h; czy jedna z sekwencji ?

JE JEST ; jest czΩ£µ sekwencji

CMP WORD PTR ES:[BX],03EBh ; czy druga z sekwencji ?

JNE NIEDZIAśA ; nie ma sekwencji - tuneling nie dzia│a

JEST:

CMP BYTE PTR ES:[BX+2],OE8h; czy druga czΩ£µ sekwencji ?

JNE NIEDZIAśA ; nie ma sekwencji - tuneling nie dzia│a

CMP WORD PTR ES:[BX+5],0FF2Eh ; czy trzecia czΩ£µ sekwencji ?

JNE NIEDZIAśA ; nie ma sekwencji - tuneling nie dzia│a

CMP BYTE PTR ES:[BX+7],02Eh ; czy czwarta czΩ£µ sekwencji ?

JNE NIEDZIAśA ; nie ma sekwencji - tunelling nie dzia│a

; znaleziona pe│na sekwencja

MOV BX,WORD PTR ES:[BX+8]

LES BX,DWORD PTR ES:[BX] ; ES:BX wskazuje na oryginalny adres int 21h

NIEDZIALA:

Dla przerwania 2Fh sekwencja będzia wyglądała bardzo podobnie, z jedyną zmianą w programie wartości 0FS z 109Eh na 10C6h i 0FB2h na 0FDAh.

6.4.2. Wykorzystanie trybu krokowego procesora (ang. tracing)

Do znalezienia oryginalnych wejść do procedur obsługi przerwań można wykorzystać tryb krokowy procesora. Po zainstalowaniu odpowiedniego monitora pod przerwaniem krokowym wykonuje się jakąś testową funkcję, której wynik jest już wcześniej znany (np. przez uprzednie wywołanie tej funkcji bez monitora przerwania krokowego). Na bazie tego możemy stwierdzić (będąc w procedurze obsługi przerwania krokowego), czy znajdujemy się w poszukiwanym, oryginalnym kodzie przerwania, poprzez testowanie zawartości odpowiedniego rejestru lub ich grupy.

Dla przerwania int 21h wygodnie śledzić np. funkcję 62h (weź aktualny adres PSP) lub funkcję 30h (weź numer wersji DOS), dla przerwania int 13h taką funkcją może być 08h (weź informację o parametrach dysku).

6.4.3. Tuneling rekursywny (ang. recursive tunneling)

Ze względu na możliwość blokowania trybu krokowego procesora do znalezienia oryginalnego adresu przerwania 21h można zastosować tzw. tuneling rekursywny. Polega on na tym, iż w otoczeniu aktualnej procedury obsługi przerwania (wskazywanej przez tablicę przerwań), poszukuje się kodów wywołań dalekich procedur lub skoków, dzięki którym zwykle przekazywane jest sterowanie do kolejnego elementu łańcucha obsługi przerwania. Najczęściej łańcuch taki składa się z następujących sekwencji:

Element_l

; pierwszy element │a±cucha

Skok_do_Elementu_2

; pamiΩµ wykorzystywana przez inne programy

Element_2 ; drugi element │a±cucha

Skok_do_Elementu_3

; pamiΩµ wykorzystywana przez inne programy

Element_N ; ostatni element │a±cucha - poszukiwana czΩ£µ systemu Powr≤t_Z_Elementu_N ; powr≤t poprzez rozkaz IRET lub

; RETF 2 do elementu poprzedniego lub bezpo£rednio

; do wywo│uj╣cego programu

Na przykład działanie procedury szukającej adresu przerwania 21h można sprowadzić do następującej sekwencji:

mov ah,52h ; pobierz do ES:BX adres struktury

int 21h ; LL (lista list)

mov bx,es

xor ax,ax ; ustaw adres DS:SI na adres

mov ds,ax ; przerwania 21h wskazywanego

mov si,21h*4 ; przez tablice przerwa±

xchg ax,di ; DI=licznik sprawdzanych bajtow=0

Adres 32:

Ids si,ds:[si] ; pobierz adres

or bx,bx ; czy koniec szukania ?

jz WSegmencieDOS ; TAK - powr≤t DS:SI-adres

mov ax,ds ; czy jest to segment DOS ?

cmp ax, bx ; /

jne NastepnyBajt ; TAK - znaleziony adres

xor bx,bx ; BX=0 oznacza koniec szukania

NastepnyBajt:

lodsw ; weƒ 2 bajty bΩd╣ce czΩ£ci╣ aktualnej procedury dec si ; sprawdzamy co bajt

cmp al,9Ah ; czy jest to CALL FAR PTR ?

je Adres32 ; TAK - weƒ kolejny adres

cmp al,0EAh ; czy jest to JMP FAR PTR ?

je Adres32 ; TAK - weƒ kolejny adres

cmp ax,0FF2Eh ; czy jest to JMP FAR CS:DWORD ?

jne NieJMP_DWORD

cmp byte ptr [si+l],al ; czy dalsz╣ czΩ£µ rozkazu JMP FAR CS:DWORD ?

jne NieJMP_DWORD

mov si,ds:[si+2] ; pobierz offset do danych dla skoku jmp short Adres32 ; TAK - weƒ kolejny adres

NieJMP_DWORD:

inc DI ; licznik sprawdzanych bajt≤w

and DI,4095 ; je┐eli sprawdzono ju┐ 4095 bajt≤w,

je Recursive21_Exit ; to ko±cz, bo tuneling nie dzia│a

jmp NastepnyBajt ; weƒ kolejny bajt

WSegmencieDOS:

; adres zosta│ znaleziony (jest w DS:SI)

RecursNieDzia│a:

; adres nie zosta│ znaleziony

6.4.4. Trik2F/13

Do znalezienia oryginalnego programu obsługi przerwania 13h (obsługa fizycznych dysków) w ROM-BIOS można zastosować funkcję (13/2F), która służy do ustawiania nowej procedury obsługi dysków. Po jej wywołaniu dodatkowo zwracana jest informacja o obecnej i pierwotnej (oryginalnej) procedurze obsługi tego przerwania [dokładniej: zwracane są wartości parametrów z poprzedniego wywołania funkcji (13/2F)]. Funkcję tę wykorzystuje IO.SYS przy starcie sy

stemu, aby przejąć kontrolę nad różnymi błędami pojawiającymi się przy dostępie do dysków. To, że potrzebuje ona parametrów wejściowych, można pominąć, gdyż jej dwukrotne wywołanie przywraca oryginalne ustawienia systemu. Poniższa sekwencja pokazuje, jak za pomocą opisanej funkcji znaleźć oryginalny (o ile nie jest on kontrolowany przez program antywirusowy) adres int 13h w ROM-BIOS-ie:

; Trik 2F/13

MOV AH,13h ; funkcja - ustaw obs│ugΩ dysk≤w DS:DX adres

; procedury obs│ugi (mo┐na pomin╣µ gdy┐ za

; chwilΩ i tak zostanie przywr≤cona w│a£ciwa

; procedura obs│ugi). ES:BX adres procedury, kt≤ra system

; bΩdzie ustawia│ jako procedurΩ obs│ugi przerwania nr 13h

; przy ewentualnym zawieszeniu systemu lub po wywo│aniu

; int 19h (tak┐e mo┐na pomin╣µ)

INT 2Fh ; wywo│aj funkcjΩ 13h

; po wywo│aniu ES:BX zwraca adres procedury, kt≤ra system

; ustawi jako int 13h w wy┐ej wymienionych wypadkach, czyli

; zwykle bΩdzie to oryginalna procedura obs│ugi przerwania

13h MOV SEG_13,ES ; trzeba zapamiΩtaµ adres oryginalnej procedury obs│ugi

MOV OFS_13,BX ; intl3h, znajduj╣cej siΩ w ES:BX

MOV AH,13h ; funkcja - ustaw obs│ugΩ dysk≤w DS:DX i ES:BX to warto£ci

; z poprzedniego wywo│ania funkcji (13/2F)

INT 2Fh ; wywo│aj funkcjΩ 13h

Poniższy program znajduje (o ile to możliwe) wejścia do przerwań 21h, 13h, 2Fh, z wykorzystaniem różnych technik tunelingowych-

;

Czesc ksiazki : 'Nowoczesne techniki wirusowe i antywirusowe' ;

;

TUNEL v1.0, Autor : Adam Blaszczyk 1997 ;

;

Program demonstruje uzycie kilku odmian tunelingu ;

do znalezienia oryginalnych adresow przerwan ;

- 13h (trik 2F/13, tryb krokowy) ;

- 21h (tablica stalych adresow, tryb krokowy, tuneling rekursywny) ;

- 2Fh (tablica stalych adresow) ;

;

; Kompilacja :  ;

TASM TUNEL.ASM ;

TLINK /t TUNEL.OBJ ;

;

NUL = 00h ;

LF = 0Ah ; - stale potrzebne do deklaracji

CR = 0Dh ; / lancuchow napisowych

ON = 001h ; stale potrzebne do obslugi

OFF = 002h ; / przerwania 1

PROG segment  ; segment kodu i danych

ORG 100h  ; program jest typu COM

Assume CS:PROG, DS:PROG, ES:PROG, SS:PROG

CodeStart: ; tu zaczyna sie program

lea si,TeCopyRight ; pokaz info o programie

Call Print ; /

Call GetOriginal13 ; pokaz oryginalny adres 13h

Call GetOriginal21 ; pokaz oryginalny adres 21h

Call GetOriginal2F ; pokaz oryginalny adres 21h

mov ax, 4C00h ; koncz program i powroc do DOSa

int 21h ; /

GetOriginal13 proc near ; procedura pobiera oryginalny adres

; Int 13h (na dwa sposoby) i wyswietla

; go

push si ; zachowaj zmieniany rejestr

lea si,TeGet13 ; pokaz info o przerwaniu 13h

Call Print ; /

Call Trik2F13 ; wez adres 13h

; metoda Trik 2F/13

Call ShowAddr ; pokaz adres 13h

Call Tracing13 ; wez adres 13h

; metoda tracingu

Call ShowAddr ; pokaz adres 13h

pop si ; przywroc zmieniany rejestr

ret ; powrot z procedury

GetOriginal13 endp

Trik2F13 proc near ; procedura pobiera oryginalny adres

; Int 13h wykorzystujac funkcje 13h

; przerwania 2Fh

; (wewnetrzna funkcja DOS)

push ds ;

push es ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push dx ; /

push si ; /

lea si,TeTrik2F13 ; pokaz info o metodzie

Call Print ; / Trik 2F/13h

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ah,13h ;

int 2Fh ;

;

mov cs:ShowSeg,es ; trik 2F/13

mov cs:ShowOFS,bx ; /

; /

mov ah,13h ; /

int 2Fh ; /

pop si ;

pop dx ;

pop bx ; przywroc zmieniane rejestry

pop ax ; /

pop es ; /

pop ds ; /

ret ; powrot z procedury

Trik2F13 endp

Tracing13 proc near ; procedura popbiera oryginalny

; adres Int 13h, wykorzystujac

; metode tracingu

push ds ;

push es ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push cx ; /

push dx ; /

push si ; /

mov ShowError, offset TeTracingFail

; ewentualny komunikat o bledzie

lea si,TeTracing13 ; wyswietl info o metodzie

Call Print ; /

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ah,8 ; pobierz info o twardym dysku

mov dl,80h ; i zachowaj na pozniej wartosci

int 13h ; / rejestrow CX i DX; beda one

mov MagicNum1,cx ; / potrzebne do sprawdzenia czy

mov MagicNum2,dx ; / tracer jest juz w dobrym kodzie

mov ax,3513h ; wez adres przerwania Int 13h,

int 21h ; zeby mozna je bylo przetrace'owac,

mov CallFarSeg,es ; / trzeba je emulowac poprzez

mov CallFarOfs,bx ; / pushf/call dword ptr Ofs:Seg

mov TraceMode,OFF ; flaga potrzebna tracerowi

mov ax,3501h ; pobierz adres obslugi

int 21h ; przerwania krokowego Int 1

mov of1,bx ;

mov se1,es ; i ustaw nowa procedure jego

; - obslugi, sprawdzajaca, czy

mov dx,offset Tracer_13 ; / funkcja zostala juz wykonana

mov ax,2501h ; / przez BIOS

int 21h ; /

pushf ; wlacz tryb krokowy

pop ax ; procesora

or ah,1 ;

push ax ; /

popf ; /

mov dl,80h ; parametr funkcji 08/int 13h = HD0

mov ah,08h ; numer funkcji BIOS

pushf ; czesc emulacji Int 13

mov TraceMode,ON ; wlacz flage tracera

Call dword ptr cs:IntAsFarCall

; emuluj int 13

mov TraceMode,OFF ; wylacz flage tracera

pushf ; wylacz tryb krokowy

pop ax ; procesora

and ah,0FEH ;

push ax ; /

popf ; /

lds dx,dword ptr cs:of1 ; przywroc stary adres przerwania

mov ax,2501h ; / krokowego Int 1

int 21h ; /

pop si ;

pop dx ;

pop cx ; przywroc zmieniane rejestry

pop bx ; /

pop ax ; /

pop es ; /

pop ds ; /

ret ; powrot z procedury

Tracing13 endp

Tracer_13 proc far

push bp ; zachowaj zmieniany rejestr

mov bp,sp ; BP wskazuje na stos

; [bp+00] BP

; [bp+02] IP

; [bp+04] CS

; [bp+06] FLAGS

push ax ; zachowaj zmieniany rejestr

cmp cs:TraceMode,ON ; czy wlaczony tracer ?

jne Tracer_13Exit ; jesli nie, to wyskocz z procedury

mov ax,[bp+04] ; AX=CS image

cmp ax,cs:ShowSeg ; czy segment kodu ten sam

je OldSeg13 ; tak=wyskocz procedury

; nie=zachowaj nowy adres seg:ofs

mov cs:ShowSeg,ax ; AX=CS image

mov ax,[bp+02] ; AX=IP image

mov cs:ShowOfs,ax

OldSeg13:

cmp cx,cs:MagicNum1 ;

jne Tracer_13Exit ; czy funkcja sie juz wykonala ?

cmp dx,cs:MagicNum2 ; / nie=wyskocz z procedury

jne Tracer_13Exit ; /

mov cs:TraceMode,OFF ; tak=wylacz tracer, bo adres

; znaleziony

Tracer_13Exit: ; koniec przerwania Int 1

pop ax ; przywroc zmieniany rejestr

or byte ptr [bp+7],1 ; [bp+06] FLAGS , ustaw

; bit TF dla nastepnego rozkazu

; wykonywanego po IRET

pop bp ; przywroc zmieniany rejestr

iret ; powrot z przerwania Int 1

Tracer_13 endp

GetOriginal21 proc near

push si ; zachowaj zmieniany rejestr

lea si,TeGet21 ; pokaz info o przerwaniu 21h

Call Print ; /

Call LookUpTable21 ; wez adres 21h

; tablica stalych adresow

Call ShowAddr ; pokaz adres 21h

Call Recursive21 ; wez adres 21h

; metoda tunelingu rekursywnego

Call ShowAddr ; pokaz adres 21h

Call Tracing21 ; wez adres 21h

; metoda tracingu (tryb krokowy)

Call ShowAddr ; pokaz adres 21h

pop si ; przywroc zmieniany rejeetr

ret ; powrot z procedury

GetOriginal21 endp

LookUpTable21 proc near

push es ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push si ; /

lea si,TeLookUpTable21 ; wyswietl info o metodzie

Call Print ; /

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ShowError, offset TeLookUpTableFailDOSVer

; ewentualny komunikat o bledzie

mov ah,30h ; wez wersje DOS

int 21h ; /

xchg al,ah ; ax=wersja DOS, ah=major,al=minor

mov bx,109Eh ; ofset dla DOS 5.0 - 6.22

cmp ax,0500h ; wersja musi byc wieksza od 5.00

jb LookUpTable21_Exit ; mniejsza=tuneling nie zadziala

cmp ax,0622h ; dla wersji wiekszej od 6.22

jbe DOSVerOk21 ; jest inny ofset

mov bx,0FB2h ; ofset dla DOS >6.22 (np. 7.0)

DOSVerOk21:  ; ofset ustawiony

push bx ; zachowaj go na stosie

mov ah,52h ; pobierz do ES:BX adres struktury

int 21h ; / LL (lista list)

pop bx ; przywroc ze stosu ofset do skoku

mov ShowError, offset TeLookUpTableFailBadOfs

; ewentualny komunikat o bledzie

; czy pod ES;BX jest sekwencja

; 90 lub EB NOP JMP $+3

; 90 lub 03 NOP /

; E8 xx xx CALL NEAR [IP+xxxx]

; 2E FF 2E yyyy JMP FAR CS:[yyyy] ?

cmp word ptr es:[bx],9090h

je FirstCodeOK21 ; skocz, gdy sa 2 NOPy

cmp word ptr es:[bx],03EBh

jne LookUpTable21_Exit ; skocz, gdy JMP $+3

FirstCodeOK21:

cmp byte ptr es:[bx+2],0E8h ;

jne LookUpTable21_Exit ; skocz, gdy nie ma CALL xxxx

cmp word ptr es:[bx+5],0FF2Eh

jne LookUpTable21_Exit ; skocz, gdy nie ma czesci rozkazu jmp far

cmp byte ptr es:[bx+7],02Eh ;

jne LookUpTable21_Exit ; skocz, gdy nie ma czesci rozkazu jmp far

mov bx,word ptr es:[bx+8] ; pobierz [yyyy]=adres oryginalnej procedury

les bx,dword ptr es:[bx] ; /

mov ShowSeg,es ; przepisz segment i offset

mov ShowOfs,bx ; potrzebne do wyswietlenia adresu

LookUpTable21_Exit: ; skacz tu, gdy jakis blad

pop si

pop bx ;

pop ax ; - przywroc zmieniane rejeetry

pop es ; /

ret ; powrot z procedury

LookUpTable21 endp

Recursive21 proc near

push es ;

push ds ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push si ; /

push di ; /

lea si,TeRecursive21 ; wyswietl info o metodzie

Call Print ; /

mov ShowError, offset TeRecursive21Fail

; ewentualny komunikat o bledzie

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ah,52h ; pobierz do ES:BX adres struktury

int 21h ; / LL (lista list)

mov bx,es

xor ax,ax ; ustaw adres DS:SI na adres

mov ds,ax ; przerwania 21h wskazywanego

mov si,21h*4 ; przez tablice przerwa±

xchg ax,di ; DI=licznik sprawdzanych bajtow=0

Adres32:

lds si,ds:[si] ; pobierz adres

or bx,bx ; czy koniec szukania ?

jz WSegmencieDOS ; TAK - powrot DS:SI=adres

mov ax,ds ; czy jest to segment DOS ?

cmp ax,bx ; /

jne NastepnyBajt ; TAK - znaleziony adres

xor bx,bx ; BX=0 oznacza koniec szukania

NastepnyBajt:

lodsw ; wez 2 bajty bedace czescia

; aktualnej procedury

dec si ; sprawdzamy co bajt

cmp al,9Ah ; czy jest to CALL FAR PTR ?

je Adres32 ; TAK - wez kolejny adres

cmp al,0EAh ; czy jest to JMP FAR PTR ?

je Adres32 ; TAK - wez kolejny adres

cmp ax,0FF2Eh ; czy jest to JMP FAR CS:DWORD ?

jne NieJMP_DWORD ;

cmp byte ptr [si+1],al ; czy dalsza czesc rozkazu JMP FAR CS:DWORD ?

jne NieJMP_DWORD ;

mov si,ds:[si+2] ; pobierz ofset do danych dla skoku

jmp short Adres32 ; TAK - wez kolejny adres

NieJMP_DWORD:

inc DI ; licznik sprawdzanych bajtow

and DI,4095 ; jezeli sprawdzono juz > 4095 bajtow,

je Recursive21_Exit ; to koncz, bo tuneling nie dziala

jmp NastepnyBajt ; wez kolejny bajt

WSegmencieDOS:

; adres zostal znaleziony (jest w DS:SI)

mov cs:ShowSeg,ds ; przepisz segment i offset

mov cs:ShowOfs,si ; potrzebne do wyswietlenia adresu

Recursive21_Exit: ; skacz tu, gdy jakis blad

pop di ;

pop si ;

pop bx ; przywroc zmieniane rejeetry

pop ax ; /

pop ds ; /

pop es ; /

ret ; powrot z procedury

Recursive21 endp

Tracing21 proc near ; procedura popbiera oryginalny

; adres Int 13h wykorzystujac

; metode tracingu

push ds ;

push es ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push cx ; /

push dx ; /

push si ; /

mov ShowError, offset TeTracingFail

; ewentualny komunikat o bledzie

lea si,TeTracing21 ; wyswietl info o metodzie

Call Print ; /

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ah,62h ; pobierz info o aktualnym PSP

int 21h ; i zachowaj na pozniej te wartosc

mov MagicNum1,bx ; / (rejestr BX) bedzie ona

; / potrzebna, zeby sprawdzic, czy

; / tracer jest juz w dobrym kodzie

mov ax,3521h

int 21h ; wez adres przerwania Int 21h,

mov CallFarSeg,es ; zeby mozna je bylo przetrace'ow

mov CallFarOfs,bx ; / trzeba je emulowac poprzez

; / pushf/call dword ptr Ofs:Seg

mov TraceMode,OFF ; flaga potrzebna dla tracera

mov ax,3501h ; pobierz adres obslugi

int 21h ; przerwania krokowego Int 1

mov of1,bx ;

mov se1,es ; i zmien je na nowa procedure

; - obslugi, sprawdzajaca czy

mov dx,offset Tracer_21 ; / funkcja zostala juz wykonana

mov ax,2501h ; / przez DOS

int 21h ; /

pushf ; wlacz tryb krokowy

pop ax ; procesora

or ah,1 ;

push ax ; /

popf ; /

mov ah,62h ; numer funkcji DOS

pushf ; czesc emulacji Int 21

mov TraceMode,ON ; wlacz flage tracera

Call dword ptr cs:IntAsFarCall ; emuluj int 21

mov TraceMode,OFF ; wylacz flage tracera

pushf ; wylacz tryb krokowy

pop ax ; procesora

and ah,0FEH ;

push ax ; /

popf ; /

; przywroc stary adres przerwania

lds dx,dword ptr cs:of1 ; / krokowego Int 1

mov ax,2501h ; /

int 21h

pop si ;

pop dx ;

pop cx ; przywroc zmieniane rejestry

pop bx ; /

pop ax ; /

pop es ; /

pop ds ; /

ret ; powrot z procedury

Tracing21 endp

Tracer_21 proc far

push bp ; zachowaj zmieniany rejestr

mov bp,sp ; BP wskazuje na stos

; [bp+00] BP

; [bp+02] IP

; [bp+04] CS

; [bp+06] FLAGS

push ax ; zachowaj zmieniany rejestr

cmp cs:TraceMode,ON ; czy wlaczony tracer ?

jne Tracer_21Exit ; jesli nie, to wyskocz z procedury

mov ax,[bp+04] ; AX=CS instrukcji

cmp ax,cs:ShowSeg ; czy segment kodu ten sam

je OldSeg21 ; tak=wyskocz procedury

mov cs:ShowSeg,ax ; nie=zachowaj nowy adres seg:ofs

mov ax,[bp+02] ; AX=CS instrukcji

mov cs:ShowOfs,ax ; AX=IP instrukcji

OldSeg21:

cmp bx,cs:MagicNum1 ;

jne Tracer_21Exit ; czy funkcja juz sie wykonala ?

; / nie=wyskocz z procedury

mov cs:TraceMode,OFF ; / tak=wylacz tracer, bo adres

; / znaleziony

Tracer_21Exit: ; koniec przerwania Int 1

pop ax ; przywroc zmieniany rejestr

or byte ptr [bp+7],1 ; [bp+06] FLAGS, ustaw

; bit TF dla nastepnego rozkazu

; wykonywanego po IRET

pop bp ; przywroc zmieniany rejestr

iret ; powrot z przerwania Int 1

Tracer_21 endp

GetOriginal2F proc near

push si ; zachowaj zmieniany rejestr

lea si,TeGet2F ; pokaz info o przerwaniu 2Fh

Call Print ; /

Call LookUpTable2F ; wez adres 2Fh

; tablica stalych adresow

Call ShowAddr ; pokaz adres 21h

pop si ; przywroc zmieniany rejestr

ret ; powrot z procedury

GetOriginal2F endp

LookUpTable2F proc near

push es ;

push ax ; zachowaj zmieniane rejestry

push bx ; /

push si ; /

lea si,TeLookUpTable2F ; wyswietl info o metodzie

Call Print ; /

xor ax,ax ; zeruj zmienne pomocnicze

mov ShowSeg,ax ; /

mov ShowOfs,ax ; /

mov ShowError, offset TeLookUpTableFailDOSVer

; ewentualny komunikat o bledzie

mov ah,30h ; wez wersje DOS

int 21h ; /

xchg al,ah ; ax=wersja DOS, ah=major,al=minor

mov bx,10C6h ; ofset dla DOS 5.0 - 6.22

cmp ax,0500h ; wersja musi byc wieksza od 5.00

jb LookUpTable2F_Exit ; mniejsza=tuneling nie zadziala

cmp ax,0622h ; dla wersji wiekszej od 6.22

jbe DOSVerOk2F ; jest inny ofset

mov bx,0FDAh ; ofset dla DOS >6.22 (np. 7.0)

DOSVerOk2F: ; ofset ustawiony

push bx ; zachowaj go na stosie

mov ah,52h ; pobierz do ES:BX adres struktury

int 21h ; / LL (lista list)

pop bx ; przywroc ze stosu ofset do skoku

mov ShowError, offset TeLookUpTableFailBadOfs

; ewentualny komunikat o bledzie

; czy pod ES;BX jest sekwencja

; 90 lub EB NOP JMP $+3

; 90 lub 03 NOP /

; E8 xx xx CALL NEAR [IP+xxxx]

; 2E FF 2E yyyy JMP FAR CS:[yyyy] ?

cmp word ptr es:[bx],9090h

je FirstCodeOK2F ; skocz, gdy sa 2-a NOPy

cmp word ptr es:[bx],03EBh

jne LookUpTable2F_Exit ; skocz, gdy JMP $+3

FirstCodeOK2F:

cmp byte ptr es:[bx+2],0E8h ;

jne LookUpTable2F_Exit ; skocz, gdy nie ma CALL xxxx

cmp word ptr es:[bx+5],0FF2Eh

jne LookUpTable2F_Exit ; skocz, gdy nie ma czesci rozkazu jmp far

cmp byte ptr es:[bx+7],02Eh ;

jne LookUpTable2F_Exit ; skocz, gdy nie ma czesci rozkazu jmp far

mov bx,word ptr es:[bx+8] ; pobierz [yyyy]=adres oryginalnej procedury

les bx,dword ptr es:[bx] ; /

mov ShowSeg,es ; przepisz segment i ofset

mov ShowOfs,bx ; potrzebne do wyswietlenia adresu

LookUpTable2F_Exit: ; skacz tu, gdy jakis blad

pop si

pop bx ;

pop ax ; - przywroc zmieniane rejestry

pop es ; /

ret ; powrot z procedury

LookUpTable2F endp

ShowAddr proc near ; wyswietl adres w postaci

; seg:ofs heksalnie na podstawie

; zawartosci zmiennych

; ShowSeg i ShowOfs

push ax ; zachowaj zmieniany rejestr

push si ; /

mov si,ShowError ; wez adres komunikatu o ewentualnym

; / bledzie

mov ax,ShowSeg ; czy seg i ofs sa wyzerowane,

or ax,ShowOfs ; tzn czy nie znaleziono adresu ?

jz ShowAddrError ; tak=nie znaleziono adresu

mov ax,ShowSeg ; wyswietl segment

Call PrintHexDW ; /

mov al,':' ; wyswietl dwukropek

Call PrintChar ; /

mov ax,ShowOfs ; wyswietl ofset

Call PrintHexDW ; /

lea si,TeCRLF ; wyswietl CR,LF,

ShowAddrError: ; - czyli przejdz do nastepnego wiersza

Call Print ; / lub komunikat o bledzie

pop si ;

pop ax ; / przywroc zmieniany rejestr

ret ; powrot z procedury

ShowAddr endp

PrintHexDW proc near ; procedura wyswietla heksalnie

; liczbe zawarta w AX

push ax ; zachowaj zmieniane rejestry

push bx ; /

lea bx,HexChars ; bx wskazuje na tablice konwersji

; liczb heksadecymalnych 0..F

Call PrintHex ; wyswietl liczbe w AX

pop bx ; przywroc zmieniane rejestry

pop ax ; /

ret ; powrot z procedury

PrintHexDW endp

PrintHex proc near

push ax ; zachowaj mlodsza czesc adresu

mov al,ah ; AL=starsza czesc adresu

Call PrintHexDB ; wyswietl starsza czesc adresu

pop ax ; przywroc mlodsza czesc adresu

PrintHexDB:  ; wyswietl czesc adresu z al

mov ah,al ; zachowaj na chwile te czesc

shr al,1 ; wyswietl starsza czesc bajtu

shr al,1 ; al przesuniete o 4 w prawo

shr al,1 ;

shr al,1 ; /

xlat byte ptr cs:[bx] ; / al=[bx+al]

Call PrintChar ; / wyswietl znak w AL

mov al,ah ; wyswietl mlodsza czesc bajtu

and al,15 ; al zamaskowane z 00001111b

xlat byte ptr cs:[bx] ; / al=[bx+al]

Call PrintChar ; / wyswietl znak w AL

ret ; powrot z procedury

PrintHex endp

Print proc near ; procedura wyswietla tekst ASCIIZ

; spod adresu CS:SI

push ax ; zachowaj zmieniane rejestry

push si ; /

GetNextChar:

lods byte ptr cs:[si] ; wez kolejny znak

or al,al ; czy znak jest zerem

jz PrintExit ; tak=koniec napisu; wyjdz z petli

Call PrintChar ; nie=wyswietl znak w AL

;

jmp short GetNextChar ; i wez nastepny znak

PrintExit:

pop si ; przywroc zmieniane rejestry

pop ax ; /

ret ; powrot z procedury

Print endp

PrintChar proc near ; procedura wyswietla znak w AL

push ax ; zachowaj zmieniany rejestr

mov ah,0Eh ; funkcja BIOS

int 10h ; wyswietl znak w AL

pop ax ; przywroc zmieniany rejestr

ret ; powrot z procedury

PrintChar endp

TeCopyRight:

db CR,LF,'TUNEL v1.0, Autor : Adam Blaszczyk 1997',NUL

TeGet13 db CR,LF,'Adres oryginalnej procedury 13h : '

db CR,LF,NUL

TeGet21 db CR,LF,'Adres oryginalnej procedury 21h : '

db CR,LF,NUL

TeGet2F db CR,LF,'Adres oryginalnej procedury 2Fh : '

TeCRLF db CR,LF,NUL

TeTrik2F13 db ' _ trik Int 2Fh/13h := ',NUL

TeTracing13 db ' _ tracing 13h := ',NUL

TeLookUpTable21 db ' _ tablica stalych adresow 21h := ',NUL

TeRecursive21 db ' _ tuneling rekursywny 21h := ',NUL

TeTracing21 db ' _ tracing 21h := ',NUL

TeLookUpTable2F db ' _ tablica stalych adresow 2Fh := ',NUL

TeLookUpTableFailBadOfs db 'Blad : Zla kombinacja kodu',CR,LF,NUL

TeLookUpTableFailDOSVer db 'Blad : Wersja DOS musi byc >5.0',CR,LF,NUL

TeTracingFail db 'Blad : Tracing nie dziala',CR,LF,NUL

TeRecursive21Fail db 'Blad : Tuneling rekursywny nie dziala',CR,LF,NUL

HexChars db '0123456789ABCDEF'

ShowSeg dw ? ; zmienne pomocnicze do zachowywania

ShowOfs dw ? ; znalezionego adresu

ShowError dw ? ; zmienna dla ewentualnych bledow

of1 dw ? ; zmienne potrzebne do zachowywania

se1 dw ? ; adresu Int 1

IntAsFarCall label dword ; adres dalekiej procedury sluzacej do

CallFarOfs dw ? ; emulacji instrukcji INT

CallFarSeg dw ?

TraceMode db ? ; flaga ON=wlaczony/OFF= wlaczony tracer

MagicNum1 dw ? ; zmienne pomocnicze do przechowywania

MagicNum2 dw ? ; wartosci potrzebnych do sprawdzenia czy

; jestesmy juz we wlasciwym kodzie DOS/BIOS

PROG ends ; koniec segmentu kodu i danych

end CodeStart ; koniec programu, pierwsza instrukcja

; pod etykieta CodeStart

6.5. Wykorzystanie trybu chronionego

Tryb chroniony nie jest zbyt często wykorzystywany przez wirusy, jednak kilka z nich używa go do przejmowania przerwań. Po zainstalowaniu (co wiąże się z przejściem do trybu chronionego) każde odwołanie do jakiegokolwiek przerwania będzie kierowane najpierw do wirusa, a dopiero ten przekaże je do oszukiwanego systemu poprzez chwilowe przejście (ang. redirection) do trybu rzeczywistego (lub trybu V86). Ponadto, aby utrudnić wykrycie wirusa w pamięci, można po instalacji przenieść jego kod do pamięci powyżej 1MB.

W przypadku systemu Windows do przejmowania przerwań można wykorzystać fakt, iż udostępnia on programom usługi specyfikacji DPMI (ang. DOS Protected Mode Interface).

Do przejmowania przerwań służą funkcje:

> 0200h - odczytanie wektora przerwań trybu rzeczywistego;

> 0201h - zapisanie wektora przerwań trybu rzeczywistego;

> 0202h - odczytanie adresu procedury obsługi wyjątku;

> 0203h - ustawienie adresu procedury obsługi wyjątku;

> 0204h - odczytanie wektora przerwań trybu wirtualnego;

> 0205h - zapisanie wektora przerwań trybu wirtualnego;

Powyższe funkcje są dostępne w trybie chronionym za pośrednictwem przerwania 31h. Przed ich użyciem należy sprawdzić, czy DPMI jest dostępne, za pomocą funkcji (1687/2F). Dokładniejsze informacje na temat specyfikacji DPMI oraz trybu chronionego zawarte są w pozycjach [l] i [6] ze spisu na końcu książki.

6.6. Włączanie się jako program obsługi urządzenia

Jednym z wirusów stosujących tę metodę jest wymieniany już wirus DIR-2. Zamienia on oryginalną procedurę obsługi dysków poprzez manipulację na strukturach DPB, co zostało dokładniej omówione przy okazji omawiania wirusów zarażających JAP



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 981
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved