;антивирус против стелс вируса onehalf
;set date 2-22-95 11:38:52a

_path		equ	81h
XOR_BYTE	equ	05ah
analis_byte	equ	10
size_header	equ	01ah

cseg		segment
		assume	cs:cseg,ds:cseg
		org	100h

start:
; раскодировать
		mov	dx,offset copyright
		call	write_string
		mov	dx,offset gandvik
		call	write_color
		mov	dx,offset my_name
		call	write_string
		cli
		mov	sp,offset _stack
		sti
		mov	dx, offset int_23
		mov	ax,2523h
		int	21h
		mov	dx, offset int_24
		mov	ax,2524h
		int	21h
		cld
		mov	ah,19h		;определить текущий диск
		int	21h
		mov	di,_path
		xor	cx,cx
		mov	cl,ds:[80h]	;длина строки параметров
		jcxz	met_begin2
		mov	si,di
		xchg	bx,ax		;запомнить текущий диск
cycle0:
		lodsb
		cmp	al,"/"
		jnz	met_a1
		mov	al,byte ptr ds:[si]
		and	al,11011111b
		cmp	al,"F"
		jnz	met_a1
		mov	byte ptr cs:[ met_f ],1
		jmp	met_a3
met_a1:
		cmp	al,"G"
		jnz	met_a3
		mov	byte ptr cs:[ met_g ],1
met_a3:
		loop	cycle0
met_a2:
		mov	cl,ds:[80h]	;длина строки параметров
		mov	si,di
cycle1:
		lodsb
		cmp	al,"/"
		jz	met_begin0
		cmp	al,"A"
		jae	met_begin1
		loop	cycle1
met_begin0:
		xchg	ax,bx
		jmp	met_begin2
met_begin1:
;проверим допустимость назначенного диска
		and	al,00011111b
		dec	ax
		mov	dl,al
		mov	ah,0eh
		int	21h
		mov	ah,19h
		int	21h
		cmp	al,dl
		jnz	met_begin0	;не допустимо
		xchg	dx,bx
		mov	ah,0eh		;восстановить текущий диск
		int	21h
		xchg	ax,bx		;выбранный диск для проверки
met_begin2:
;в al - диск поиска
		add	al,"A"
		mov	ah,":"
		stosw
		xor	al,al
		mov	cl,77
		rep	stosb
		mov	al,"$"
		stosb
		xor	bx,bx
		mov	ah,3
		int	10h
		mov	word ptr cs:[ pos_curs ],cx
		mov	ah,1
		or	ch,00100000b
		int	10h			;сделать курсор невидимым
;начать поиск в памяти
		xor	dx,dx
		mov	es,dx
met_s0:
		mov	si,offset int_21
		lodsb
met_s1:
		mov	si,offset int_21+1
		mov	di,dx
		mov	cx,0ffffh
		sub	cx,di
		jcxz	met_s2
		repnz	scasb
		jnz	met_s2
		mov	dx,di
		mov	cx,offset sm_21 - offset int_21 - 1
		rep	cmpsb
		jnz	met_s1
; проверка, а не кусок ли этой программы ?
		mov	cx,offset sm_13 - offset sm_21
		rep	cmpsb
		jz	met_s1
;найден - нейтрализовать в памяти
		cli
		mov	di,dx
		sub	di,4
		add	di,word ptr ds:[ sm_21 ]
		mov	si,offset new_21
		mov	cx,3
		rep	movsb
		mov	di,dx
		sub	di,4
		push	di
		add	di,word ptr ds:[ sm_13 ]
		mov	si,offset new_13
		mov	cx,3
		rep	cmpsb
		pop	di
		jz	met_s29
		cmp	byte ptr ds:[ met_f ],0
		jnz	met_s26
		add	di,word ptr ds:[ sm_13n ]
		mov	si,offset new_13n
		jmp	met_s27
met_s29:
		mov	byte ptr ds:[ met_local ],1
		
met_s26:
		add	di,word ptr ds:[ sm_13 ]
		mov	si,offset new_13
met_s27:
		mov	cx,3
		rep	movsb
		sti
		inc	bx
		jmp	met_s1
met_s2:
;не найден пока - установить следующий сегмент поиска
		xor	dx,dx		;продолжить поиск с нулевого смещения
		mov	ax,es
		add	ax,1000h
		mov	es,ax
		cmp	ax,0f000h	;1M - 64K проверено ?
		jb	met_s0		;нет
		mov	dx,offset no_find
		cmp	byte ptr ds:[ met_local ],0
		jnz	met_s3
		or	bx,bx
		jz	met_s3
		mov	dx,offset local_tive
		cmp	byte ptr ds:[ met_f ],0
		jz	met_s3
		mov	dx,offset delete
met_s3:
		call	write_string

;**********************************************************************
;проверка и восстановление BOOT - сектора
;**********************************************************************
		mov	ax,0440eh
		mov	bl,3		; check drive C:
		int	21h
		jnc	met_s24
		jmp	met_s14
met_s24:
		mov	dx,offset _boot
		call	write_string
		mov	ax,201h
		push	cs
		pop	es
		mov	bx, word ptr cs:[ address_dta ]
		add	bx,30h
		mov	cx,1
		mov	dx,80h
		int	13h
		jnc	met_b1
		mov	dx, offset error
		jmp	met_s11
met_b1:
		mov	dx,offset no_infection
		mov	si,offset boot_bin
		mov	di,bx
		mov	cx,offset int_21 - offset boot_bin
		rep	cmpsb
		jz	met_b7
		jmp	met_s11
met_b7:
		push	word ptr es:[ bx + 29h ]	; last cript cylinder
		pop	word ptr cs:[ data_29 ]
		mov	dx,offset infection
		cmp	byte ptr cs:[ met_f ],0
		jnz	met_b8
		jmp	met_s11
met_b8:
		mov	dx,80h
		mov	ah,8
		int	13h
		jnc	met_b2
		mov	dx, offset error
		jmp	met_s11
met_b2:
		and	cx,03fh

; save XOR_WORD 
		push	cx
		sub	cl,3
		mov	dx,80h
		mov	ax,202h
		int	13h
		pop	cx
		jnc	met_b3
		mov	dx, offset error
		jmp	met_s11
met_b3:
		push	word ptr cs:[ bx + 01d1h ]
		pop	word ptr cs:[ XOR_WORD ]
		push	word ptr cs:[ bx + 282h ]
		pop	word ptr cs:[ end_cylinder ]
		sub	cl,7
		mov	dx,80h
		mov	ax,201h
		int	13h
		jnc	met_b5
		mov	dx, offset error
		jmp	met_s11
met_b5:
		mov	dx,80h
		mov	cx,1
		mov	ax,301h
		int	13h
		jnc	met_b4
		mov	dx, offset error
		jmp	met_s11
met_b4:
		mov	dx,offset clear_boot
		call	write_string
		mov	dx,offset data_encript
		call	write_string
		call	encript
		
met_s11:
		call	write_string
met_s14:
		mov	dx,offset _enter
		call	write_string
		
;**********************************************************************
;процедура поиска exe,com-файлов по всем директориям
;**********************************************************************
		mov	bh,4eh	;начинаем поиск
		push	cs
		pop	es
;установить DTA для соответветствующего подуровня директории

met_s10:
		mov	dx,ds:[address_dta]
		mov	ah,1ah
		int	21h
;установить поиск всех файлов по маске *.*
		call	search
		push	di
		rep	stosb	;обнулить до конца строки
		pop	di
		dec	di
		mov	si,offset _mask				
		mov	cl,5
		rep	movsb
met_s12:
		mov	ah,bh
		mov	dx,_path
		mov	cx,00110000b
		int	21h
		jnc	met_s30
		jmp	met_s25
met_s30:
		mov	ah,0bh
		int	21h
		cmp	byte ptr cs:[ met_break ],1
		jz	met_s31
		or	al,al
		jz	not_esc
		mov	ah,07h			; Обработка ESC
		int	21h
		cmp	al,27
		jnz	not_esc
met_s31:
		mov	dx,offset user_break
		mov	byte ptr cs:[ data_color ],00001100b
		call	write_color
		mov	dx,offset _enter
		call	write_string
		jmp	quit
not_esc:
		mov	bh,4fh			;поиск будем продолжать
		mov	di,word ptr cs:[ address_dta ]
		test	byte ptr cs:[di+21],10h	;это директория ?
		jnz	met_s20			;да
		cmp	byte ptr cs:[ met_g ],1
		jz	met_c_com
		add	di,30			;смещение к имени
		mov	al,"."
		mov	cx,13			;длина имени
		repnz	scasb
		mov	si,offset _exe
		mov	cx,4
		push	di
		rep	cmpsb
		pop	di
		jz	met_c_exe

		mov	si,offset _com
		mov	cx,4
		push	di
		rep	cmpsb
		pop	di
		jnz	met_s12
met_c_com:
		call	check_com
		mov	bh,4fh
		jmp	met_s10

met_c_exe:
		call	check_exe
		mov	bh,4fh
		jmp	met_s10
met_s20:
		mov	si,word ptr cs:[ address_dta ]
		cmp	byte ptr ds:[si+30],"."	;корневая директория или сама
		jnz	met_s32
		jmp	met_s12
met_s32:
		mov	bh,4eh
		call	search
		sub	di,4
		add	word ptr cs:[ address_dta ],48
		add	si,30
		mov	cl,12
		rep	movsb
		jmp	met_s10
met_s25:
		cmp	al,12h
		jnz	quit
		cmp	word ptr cs:[ address_dta ],offset _stack
		jz	quit
		sub	word ptr cs:[ address_dta ], 30h
		call	search
		mov	al,"\"
		std
		mov	cl,25
		repnz	scasb
		repnz	scasb
met_s28:
		mov	byte ptr ds:[di+1],0
		cld
		mov	bh,04fh
		jmp	met_s10
quit:
		mov	cx,80
		mov	al," "
		mov	di,_path
		mov	dx,di
		rep	stosb
		mov	al,"$"
		stosb
		call	write_string
		xor	bx,bx
		mov	cx,pos_curs
		mov	ah,1
		int	10h
		mov	ah,4ch
		int	21h

;*****************************************************************
;   Проверка заражения файла
;   cf = 1	- заражен
;*****************************************************************
check_time:
		push	dx
		push	bx
		mov	bx, word ptr cs:[ address_dta ]
		add	bx,016h		; offset time
		mov	ax,es:[ bx + 2]
		xor	dx,dx
		div	word ptr cs:[ data_a6 ]
		mov	ax,word ptr es:[ bx ]
		and	al,00011111b
		cmp	al,dl
		stc
		jz	met_ct1
		mov	ax,word ptr es:[ bx ]
		and	ax,0ffe0h
		or	al,dl
		cmp	byte ptr cs:[ met_g ],0
		clc
		jz	met_ct1
		stc
met_ct1:
		stc			; проверять независимо от времени
		pop	bx
		pop	dx
		ret


search:
		mov	di,_path
		xor	al,al
		mov	cx,79
		repnz	scasb
		ret

write_string:
		push	si
		push	bx
		xor	bx,bx
		mov	si,dx
cycle_ws1:
		lodsb
		cmp	al,"$"
		jz	met_ws1
		mov	ah,0eh
		int	10h
		jmp	cycle_ws1
met_ws1:		
		pop	bx	
		pop	si
		ret
write_color:
		push	si
		push	bx
		push	cx
		push	dx
		xor	bx,bx
		mov	si,dx
		mov	ah,3
		int	10h
cycle_wc1:
		lodsb
		cmp	al,"$"
		jz	met_wc1
		cmp	al,0ah
		jz	met_wc2
		cmp	al,0dh
		jz	met_wc2
		mov	cx,1
		mov	bl,byte ptr cs:[ data_color ]
		mov	ah,09h
		int	10h
		inc	dx
		mov	ah,02h
		int	10h
		jmp	cycle_wc1
met_wc2:
		mov	ah,0eh
		int	10h
		jmp	cycle_wc1
met_wc1:
		mov	byte ptr cs:[ data_color ],00001010b
		pop	dx
		pop	cx
		pop	bx	
		pop	si
		ret

check_com:
;контроль и замена com-файла
		mov	word ptr cs:[ old_jmp ],0
		call	search
		sub	di,4
		sub	cl,4
		mov	si,word ptr cs:[ address_dta ]
		add	si,30
cycle_cc14:
		lodsb
		stosb
		or	al,al
		jnz	cycle_cc14

;проверка com-файла
		mov	dx,_path
		call	write_string
		mov	ah,3
		push	bx
		xor	bx,bx
		int	10h
		call	search
		sub	cl,79
		neg	cl
		mov	dl,cl
		mov	ah,2
		int	10h
		pop	bx
		call	check_time
		jc	met_cc31		; заражен
		jmp	met_cc40
met_cc31:
		mov	dx,_path
		mov	ax,3d00h
		int	21h
		jnc	met_cc2
		mov	dx, offset error
		jmp	met_cc1
met_cc2:
		mov	word ptr cs:[ handle ],ax
		mov	bx,ax
		mov	cx, size_header
		mov	dx, offset buf_header
		mov	ah,3fh
		int	21h
		jnc	met_cc3
		mov	dx, offset error
		jmp	met_cc100
met_cc3:
		cmp	ax,cx
		jz	met_cc4
		mov	dx, offset error
		jmp	met_cc100
met_cc4:
; ПРОВЕРКА НА exe - ФАЙЛ 
		mov	si,dx
		lodsw
		cmp	ax,"MZ"
		jz	met_cc17
		cmp	ax,"ZM"
		jnz	met_cc20
met_cc17:
		jmp	met_ce17	;ПЕРЕХОД В exe - ФУНКЦИЮ

; проверяю, является ли первая команда jmp и загружаю следующую команду
;ПЕРЕХОД ИЗ exe - ФУНКЦИИ
met_cc20:
		mov	si,dx
		lodsb
		cmp	al,0e9h		;jmp
		jz	met_cc6
		cmp	al,0ebh		;jmp near
		jz	met_cc5
		jmp	met_cc100
met_cc5:
		lodsw
		cbw
		add	ax,2
		jmp	met_cc7
met_cc6:
		lodsw
		add	ax,3
met_cc7:
		mov	word ptr cs:[ old_jmp ],ax
		mov	dx,ax
		xor	cx,cx
		mov	word ptr cs:[ begin_pos ],cx
		mov	word ptr cs:[ begin_pos + 2 ],cx
		mov	ax,4200h
		int	21h

		mov	cx,analis_byte
		mov	dx,word ptr cs:[ address_dta ]
		add	dx,30h
		mov	ah,3fh
		int	21h
		jnc	met_cc8
		mov	dx, offset error
		jmp	met_cc100
met_cc8:
		cmp	ax,cx
		jz	met_cc9
		mov	dx, offset error
		jmp	met_cc100
met_cc9:
		mov	si,offset test_code
		mov	word ptr cs:[ address ], si
		mov	word ptr cs:[ num_comm ],0		
met_cc16:
		mov	si,word ptr cs:[ address ]
		cmp	si,offset address
		jb	met_cc15
		jmp	met_cc101
met_cc15:
		call	search_byte
		mov	word ptr cs:[ address ], si
		jz	met_cc32
		jmp	met_cc100
met_cc32:
		mov	si,di
		inc	word ptr cs:[ num_comm ]
		cmp	word ptr cs:[ num_comm ], 4
		jnz	met_cc45
		lodsw
		dec	cx
		dec	cx
		mov	word ptr cs:[ xxxx ],ax
		jmp	cycle_cc1

met_cc45:
		cmp	word ptr cs:[ num_comm ], 5
		jnz	met_cc47
		lodsw
		dec	cx
		dec	cx
		mov	word ptr cs:[ yyyy ],ax
		jmp	cycle_cc1

met_cc47:
		cmp	word ptr cs:[ num_comm ], 7
		jnz	met_cc49
		dec	si
		lodsb
		cmp	al, 81h		; add xx, yy   7fh < yy < 0ffffh
		jz	met_cc52
		lodsw
		jmp	met_cc50
met_cc52:
		inc	si
		lodsw
		dec	cx
met_cc50:
		dec	cx
		dec	cx
		mov	word ptr cs:[ zzzz ],ax
		jmp	cycle_cc1

met_cc49:
		cmp	word ptr cs:[ num_comm ], 9
		jnz	met_cc65
		inc	si
		lodsw
		sub	cx,3
		mov	word ptr cs:[ kkkk ],ax
		jmp	cycle_cc1

met_cc65:
		cmp	word ptr cs:[ num_comm ], 10
		jnz	cycle_cc1
		inc	cx
		jmp	met_cc10

cycle_cc1:
		lodsb
		cmp	al,0e9h		;jmp
		jz	met_cc11
		cmp	al,0ebh		;jmp near
		jz	met_cc10
		loop	cycle_cc1
		xor	ax,ax
		jmp	met_cc12
met_cc10:
		lodsb
		cbw
		add	ax,2
		jmp	met_cc12
met_cc11:
		lodsw
		add	ax,3
met_cc12:
		sub	cx,analis_byte
		neg	cx
		add	ax,cx
		add	ax,word ptr cs:[ old_jmp ]
		cmp	word ptr cs:[ num_comm ], 6
		jnz	met_cc68
		push	word ptr cs:[ old_jmp ]
		pop	word ptr cs:[ old_jmp_xor ]
met_cc68:
		cmp	word ptr cs:[ num_comm ], 10
		jnz	met_cc60
		cmp	word ptr cs:[ old_jmp_xor ],ax
		jz	met_cc60
		jmp	met_cc100
		
met_cc60:
		mov	word ptr cs:[ old_jmp ],ax
		xchg	dx,ax
		xor	cx,cx
		mov	ax,4200h
		int	21h

		mov	cx,analis_byte
		mov	dx,word ptr cs:[ address_dta ]
		add	dx,30h
		mov	ah,3fh
		int	21h
		jnc	met_cc13
		mov	dx, offset error
		jmp	met_cc100
met_cc13:
		cmp	ax,cx
		jz	met_cc14
		mov	dx, offset error
		jmp	met_cc100
met_cc14:
		jmp	met_cc16
met_cc100:
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3eh
		int	21h
		jmp	met_cc40
met_cc101:
; лечение программы 
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3eh
		int	21h
		mov	byte ptr cs:[ data_color ],00001100b
		mov	dx,offset infection
		cmp	byte ptr cs:[ met_f ],0
		jz	met_cc1
		mov	byte ptr cs:[ metka_ext ],1
		call	encript_virus
		jnc	met_cc19
		mov	dx, offset infection
		jmp	met_cc1
met_cc19:
		mov	dx,offset revive
met_cc1:
		call	write_color
met_cc40:
		mov	dx,offset _begin_pos
		call	write_string
		call	search
		std
		mov	al,"\"
		mov	cl,15
		repnz	scasb
		mov	byte ptr ds:[di+1],0
		cld
		ret

check_exe:
;контроль и замена exe-файла
		mov	word ptr cs:[ old_jmp ],0
		call	search
		sub	di,4
		sub	cl,4
		mov	si,ds:[ address_dta ]
		add	si,30
cycle_ce14:
		lodsb
		stosb
		or	al,al
		jnz	cycle_ce14

;проверка exe-файла
		mov	dx,_path
		call	write_string
		mov	ah,3
		push	bx
		xor	bx,bx
		int	10h
		call	search
		sub	cl,79
		neg	cl
		mov	dl,cl
		mov	ah,2
		int	10h
		pop	bx
		call	check_time
		jc	met_ce31		; заражен
		jmp	met_ce40
met_ce31:
		mov	dx,_path
		mov	ax,3d00h
		int	21h
		jnc	met_ce2
		mov	dx, offset error
		jmp	met_ce1
met_ce2:
		mov	word ptr cs:[ handle ],ax
		mov	bx,ax
		mov	cx, size_header
		mov	dx, offset buf_header
		mov	ah,3fh
		int	21h
		jnc	met_ce3
		mov	dx, offset error
		jmp	met_ce100
met_ce3:
		cmp	ax,cx
		jz	met_ce4
		mov	dx, offset error
		jmp	met_ce100
met_ce4:
; нахожу первую загружаемую команду
		mov	si,dx
		lodsw
		cmp	ax,"MZ"
		jz	met_ce17
		cmp	ax,"ZM"
		jz	met_ce17
		jmp	met_cc20	; переход в com - функцию
		
;ПЕРЕХОД ИЗ com - ФУНКЦИИ
met_ce17:
		mov	si,dx
		add	si,08h		; long header
		lodsw
		mov	cx,10h

		push	dx
		mul	cx
		mov	word ptr cs:[ begin_pos ],ax
		mov	word ptr cs:[ begin_pos + 2 ],dx
		pop	dx

		mov	si,dx
		add	si,14h		; long cs:ip
		lodsw
		mov	word ptr cs:[ old_jmp ],ax
		lodsw
		mov	cx,10h
		mul	cx
		add	word ptr cs:[ begin_pos ],ax
		adc	word ptr cs:[ begin_pos + 2 ],dx
		and	word ptr cs:[ begin_pos + 2 ],0000fh
		mov	dx,word ptr cs:[ begin_pos ]
		mov	cx,word ptr cs:[ begin_pos + 2 ]
		mov	ax,4200h
		int	21h
		mov	ax,word ptr cs:[ old_jmp ]
		cwd		;переход назад
		mov	cx,dx
		mov	dx,ax
		mov	ax,4201h
		int	21h

		mov	cx,analis_byte
		mov	dx,word ptr cs:[ address_dta ]
		add	dx,30h
		mov	ah,3fh
		int	21h
		jnc	met_ce18
		mov	dx, offset error
		jmp	met_ce100
met_ce18:
		cmp	ax,cx
		jz	met_ce9
		mov	dx, offset error
		jmp	met_ce100
met_ce9:
		mov	si,offset test_code		
		mov	word ptr cs:[ address ], si
		mov	word ptr cs:[ num_comm ],0		
met_ce16:
		mov	si,word ptr cs:[ address ]
		cmp	si,offset address
		jb	met_ce15
		jmp	met_ce101
met_ce15:
		call	search_byte
		mov	word ptr cs:[ address ], si
		jz	met_ce32
		jmp	met_ce100
met_ce32:
		mov	si,di
		inc	word ptr cs:[ num_comm ]
		cmp	word ptr cs:[ num_comm ], 4
		jnz	met_ce45
		lodsw
		dec	cx
		dec	cx
		mov	word ptr cs:[ xxxx ],ax
		jmp	cycle_ce1

met_ce45:
		cmp	word ptr cs:[ num_comm ], 5
		jnz	met_ce47
		lodsw
		dec	cx
		dec	cx
		mov	word ptr cs:[ yyyy ],ax
		jmp	cycle_ce1

met_ce47:
		cmp	word ptr cs:[ num_comm ], 7
		jnz	met_ce49
		dec	si
		lodsb
		cmp	al, 81h		; add xx, yy   7fh < yy < 0ffffh
		jz	met_ce52
		lodsw
		jmp	met_ce50
met_ce52:
		inc	si
		lodsw
		dec	cx
met_ce50:
		dec	cx
		dec	cx
		mov	word ptr cs:[ zzzz ],ax
		jmp	cycle_ce1

met_ce49:
		cmp	word ptr cs:[ num_comm ], 9
		jnz	met_ce5
		inc	si
		lodsw
		sub	cx,3
		mov	word ptr cs:[ kkkk ],ax
		jmp	cycle_ce1

met_ce5:
		cmp	word ptr cs:[ num_comm ], 10
		jnz	cycle_ce1
		inc	cx
		jmp	met_ce10

cycle_ce1:
		lodsb
		cmp	al,0e9h		;jmp
		jz	met_ce11
		cmp	al,0ebh		;jmp near
		jz	met_ce10
		loop	cycle_ce1
		xor	ax,ax
		jmp	met_ce12
met_ce10:
		lodsb
		cbw
		add	ax,2
		jmp	met_ce12
met_ce11:
		lodsw
		add	ax,3
met_ce12:
		sub	cx,analis_byte
		neg	cx
		add	ax,cx
		add	ax,word ptr cs:[ old_jmp ]
		cmp	word ptr cs:[ num_comm ], 6
		jnz	met_ce8
		push	word ptr cs:[ old_jmp ]
		pop	word ptr cs:[ old_jmp_xor ]
met_ce8:
		cmp	word ptr cs:[ num_comm ], 10
		jnz	met_ce60
		cmp	word ptr cs:[ old_jmp_xor ],ax
		jz	met_ce60
		jmp	met_ce100
		
met_ce60:
		mov	word ptr cs:[ old_jmp ],ax
		mov	dx,word ptr cs:[ begin_pos ]
		mov	cx,word ptr cs:[ begin_pos + 2 ]
		mov	ax,4200h
		int	21h

		mov	ax,word ptr cs:[ old_jmp ]
		cwd		;переход назад
		mov	cx,dx
		mov	dx,ax
		mov	ax,4201h
		int	21h

		mov	cx,analis_byte
		mov	dx,word ptr cs:[ address_dta ]
		add	dx,30h
		mov	ah,3fh
		int	21h
		jnc	met_ce13
		mov	dx, offset error
		jmp	met_ce100
met_ce13:
		cmp	ax,cx
		jz	met_ce14
		mov	dx, offset error
		jmp	met_ce100
met_ce14:
		jmp	met_ce16
met_ce100:
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3eh
		int	21h
		jmp	met_ce40
met_ce101:
; лечение программы 
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3eh
		int	21h
		mov	byte ptr cs:[ data_color ],00001100b
		mov	dx,offset infection
		cmp	byte ptr cs:[ met_f ],0
		jz	met_ce1
		mov	byte ptr cs:[ metka_ext ],0
		call	encript_virus
		jnc	met_ce19
		mov	dx, offset infection
		jmp	met_cc1
met_ce19:
		mov	dx,offset revive
met_ce1:
		call	write_color
met_ce40:
		mov	dx,offset _begin_pos
		call	write_string
		call	search
		std
		mov	al,"\"
		mov	cl,15
		repnz	scasb
		mov	byte ptr ds:[di+1],0
		cld
		ret

encript:
		mov	bx, word ptr cs:[ address_dta ]
		add	bx,30h
		mov	dl,80h
		mov	ah,8
		int	13h
		mov	al,cl
		and	al,03fh
		mov	byte ptr cs:[ max_heads ],dh
		mov	si, word ptr cs:[ end_cylinder ]
		dec	si
met_en3:
		cmp	si,word ptr cs:[ data_29 ]
		jc	met_en11
		mov	cl,1		; begin sector
		mov	dl,80h
		mov	dh,byte ptr cs:[ max_heads ]
		call	cyl_to_bios
met_en4:
		mov	ah,2
		push	ax
		int	13h
		pop	ax
		jnc	met_en1
		mov	dx, offset error
		jmp	met_en12
met_en1:
		call	buf_encript
		mov	ah,3
		push	ax
		int	13h
		pop	ax
		jnc	met_en2
		mov	dx, offset error
		jmp	met_en12
met_en2:
		or	dh,dh
		jz	met_en5
		dec	dh
		jmp	met_en4
met_en5:
		dec	si
		jmp	met_en3

met_en11:	
		mov	dx,offset clear_boot
met_en12:		
		ret

cyl_to_bios:
		push	ax
		mov	ax,si
		mov	ch,al
		push	cx
		mov	cl,4
		shl	ah,cl
		pop	cx
		mov	al,3fh
		and	dh,al
		and	cl,al
		not	al
		push	ax
		and	ah,al
		or	dh,ah
		pop	ax
		shl	ah,1
		shl	ah,1
		and	ah,al
		or	cl,ah
		pop	ax
		ret
bios_to_cyl:
		push	cx
		push	dx
		shr	cl,1
		shr	cl,1
		and	dh,0c0h
		or	dh,cl
		mov	cl,4
		shr	dh,cl
		mov	dl,ch
		xchg	si,dx
		pop	dx
		pop	cx
		ret

; al - max sectors
buf_encript:
		push	ax
		push	bx
		push	cx
		push	dx
		mov	dx,word ptr cs:[ XOR_WORD ]
met_be1:
		mov	cx,100h
cycle_be1:
		xor	word ptr es:[ bx ], dx
		inc	bx
		inc	bx
		loop	cycle_be1
		dec	al
		jnz	met_be1
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		ret

encript_virus:
		push	ds
		push	es
		mov	dx,_path
		mov	ax,4300h
		int	21h
		jnc	met_ev11
		mov	dx, offset infection
		jmp	met_ev19
met_ev11:
		mov	word ptr cs:[ file_attrib ], cx
		mov	dx,_path
		xor	cx,cx
		mov	ax,4300h
		int	21h
		jnc	met_ev12
		mov	dx, offset infection
		jmp	met_ev19
met_ev12:

		mov	dx,_path
		xor	cx,cx
		mov	ax,3d02h
		int	21h
		jnc	met_ev13
		mov	dx, offset infection
		jmp	met_ev19
met_ev13:

		mov	word ptr cs:[ handle ],ax
		mov	bx,ax
		mov	ax,5700h
		int	21h
		jnc	met_ev15
		mov	dx, offset infection
		jmp	met_ev19
met_ev15:
		mov	word ptr cs:[ file_time ],cx
		mov	word ptr cs:[ file_date ],dx
		mov	dx,word ptr cs:[ begin_pos ]
		mov	cx,word ptr cs:[ begin_pos + 2 ]
		mov	ax,4200h
		int	21h
		mov	ax,word ptr cs:[ address_dta ]
		add	ax,30h + 10h
		mov	cl,4
		shr	ax,cl	
		mov	cx,cs
		add	cx,ax
		mov	ds,cx
		xor	dx,dx
		mov	dh,byte ptr cs:[ metka_ext ]
		mov	cx,word ptr cs:[ kkkk ]
		sub	cx,dx
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3fh
		int	21h
		jnc	met_ev1
		mov	dx, offset infection
		jmp	met_ev19
met_ev1:
		cmp	ax,cx
		jz	met_ev2
		mov	dx, offset infection
		jmp	met_ev19
met_ev2:
		push	dx
		mov	bx, word ptr cs:[ xxxx ]
		mov	ax, word ptr cs:[ yyyy ]
		mov	dx, word ptr cs:[ zzzz ]  
		mov	cx, word ptr cs:[ kkkk ]
		sub	cx,bx
cycle_ev3:
		xor	word ptr ds:[ bx ],ax
		add	ax,dx
		inc	bx
		loop	cycle_ev3
		pop	dx
		
		push	ds
		pop	es
		
		mov	bx, word ptr cs:[ xxxx ]
		lea	si, word ptr ds:[ 0040h + bx ]
		add	bx,002ah
		mov	cx, analis_byte
cycle_ev4:
		mov	di, word ptr ds:[ bx ]
		push	cx
		mov	cx, analis_byte
		rep	movsb
		pop	cx
		inc	bx
		inc	bx
		loop	cycle_ev4
		add	bx,0ffd2h
		cmp	byte ptr cs:[ metka_ext ],1
		jnz	met_ev5
		mov	si,bx
		mov	di,100h
		mov	cx,3
		rep	movsb
		jmp	met_ev18
met_ev5:
; exe - file, change PSP		
		xor	dx,dx
		xor	cx,cx

		push	bx
		mov	bx, word ptr cs:[ handle ]
		mov	ax,4200h
		int	21h
		pop	dx

		mov	cx,size_header
		mov	ah,40h
		int	21h
		jnc	met_ev10
		mov	dx, offset infection
		jmp	met_ev19
met_ev10:
		cmp	ax,cx
		jz	met_ev18
		mov	dx, offset infection
		jmp	met_ev19
met_ev18:
		mov	dx,word ptr cs:[ begin_pos ]
		mov	cx,word ptr cs:[ begin_pos + 2 ]
		mov	bx, word ptr cs:[ handle ]
		mov	ax,4200h
		int	21h
		xor	dx,dx
		mov	dh,byte ptr cs:[ metka_ext ]
		mov	cx, word ptr cs:[ xxxx ]
		sub	cx,dx
		mov	ah,40h
		int	21h
		jnc	met_ev6
		mov	dx, offset infection
		jmp	met_ev19
met_ev6:
		cmp	ax,cx
		jz	met_ev7
		mov	dx, offset infection
		jmp	met_ev19
met_ev7:
		xor	cx,cx		; усечь файл
		mov	ah,40h
		int	21h
		jnc	met_ev8
		mov	dx, offset infection
		jmp	met_ev19
met_ev8:
		cmp	ax,cx
		jz	met_ev9
		mov	dx, offset infection
		jmp	met_ev19
met_ev9:
		mov	cx,word ptr cs:[ file_time ]
		mov	dx,word ptr cs:[ file_date ]
		mov	ax,5701h
		int	21h
		jnc	met_ev16
		mov	dx, offset infection
		jmp	met_ev19
met_ev16:
		mov	ah,3eh
		int	21h
		push	cs
		pop	ds
		mov	cx, word ptr cs:[ file_attrib ]
		mov	dx,_path
		mov	ax,4301h
		int	21h
		jnc	met_ev14
		mov	dx, offset infection
		jmp	met_ev14
met_ev19:
		mov	bx, word ptr cs:[ handle ]
		mov	ah,3eh
		int	21h
met_ev14:

		pop	es
		pop	ds
		ret

;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;			SUBROUTINE INT_23
;обработка CTRL + BREAK, вызываемая DOS
;заменяет int 23h
;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
int_23		proc	far
		mov	byte ptr cs:[ met_break ],1
		iret
int_23		endp

;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;			SUBROUTINE INT_24
;обработка критических ошибок, вызываемая DOS
;заменяет int 24h
;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
int_24		proc	far
		mov	al,0	;игнорировать ошибку
		stc
		retf 0002
int_24		endp


search_byte:
; dx - начало сканирования
		push	ax
		push	bx
		mov	cx,analis_byte
		mov	bx,si
		mov	si,dx		; в dx смещение к буферу
cycle_sb3:
		lodsb
		dec	cx
		xor	di,di
cycle_sb4:
		mov	ah, ds:[ bx + di ]
		inc	di
		or	ah,ah
		jz	met_sb2
		cmp	ah,al
		jnz	cycle_sb4
		add	di,bx
		xchg	si,di
cycle_sb6:
		lodsb
		or	al,al
		jnz	cycle_sb6	
		jmp	met_sb1				
met_sb2:
		inc	cx
		loop	cycle_sb3
		inc	ah		; set zf = 0
met_sb1:
		pop	bx
		pop	ax
		ret


address_dta	dw	offset _stack
pos_curs	dw	0a0dh
_mask		db	"\*.*",0
_exe		db	"EXE",0
_com		db	"COM",0
data_a6		dw	0001eh
data_29		dw	0		; last virus cylinder
max_heads	db	0		; max heads
XOR_WORD	dw	0
end_cylinder	dw	0
begin_pos	dd	0
file_attrib	dw	0
file_time	dw	0
file_date	dw	0
handle		dw	0
old_jmp		dw	0
old_jmp_xor	dw	0
xxxx		dw	0
yyyy		dw	0
zzzz		dw	0
kkkk		dw	0
num_comm	dw	0		; текущий проход
met_break	db	0		; if == 1 then press Ctrl - Break
metka_ext	db	0		; 0 - exe, 1 - com
buf_header	db	size_header dup( 0 )
test_code:
; step 1		
		db	050h		;push	ax
		db	0
; step 2
		db	016h		;push	ss
		db	00eh		;push	cs
		db	0
; step 3
		db	01fh		;pop	ds
		db	0
; step 4
		db	0bbh		;mov	bx,xxxx
		db	0bdh		;mov	bp,xxxx
		db	0beh		;mov	si,xxxx
		db	0bfh		;mov	di,xxxx
		db	0
; step 5
		db	0b8h		;mov	ax,yyyy
		db	0b9h		;mov	cx,yyyy
		db	0bah		;mov	dx,yyyy
		db	0bbh		;mov	bx,yyyy
		db	0bdh		;mov	bp,yyyy
		db	0beh		;mov	si,yyyy
		db	0bfh		;mov	di,yyyy
		db	0
; step 6
		db	031h		; xor [ xxxx ], yyyy
		db	0
; step 7	
		db	081h		; add ( step 5 ), zzzz
		db	083h		; add ( step 5 ), 0 < zzzz < 07Fh
		db	05h		; add (   ax   ), zzzz
		db	0
; step 8
		db	043h		;inc	bx
		db	045h		;inc	bp
		db	046h		;inc	si
		db	047h		;inc	di
		db	0
; step 9
		db	081h		; cmp ( step 4 ), kkkk
		db	0
; step 10
		db	075h		; jz ( step 6 )
		db	0

address		dw	0		;адрес разыскиваемой команды
boot_bin	db	033h,0dbh,0fah,0bch,000h,07ch,08eh,0d3h,0fbh,08eh
		db	0dbh,083h,02eh,013h,004h,004h,0b1h,006h,0cdh,012h
int_21		db	0fch,011h,074h,005h
		db	080h,0fch,012h,075h,02fh,0ebh,000h
sm_21		dw	0
new_21		db	0e9h,016h,001h
sm_13		dw	0e45h - 0c5dh		;смещение в теле вируса
new_13		db	0e9h,0ech,000h
sm_13n		dw	0e5ch - 0c5dh		; только модифицировать
new_13n		db	0ebh,066h,053h
met_f		db	0	; else = 1, delete files
met_g		db	0	; else = 1, all files
met_local	db	0	; else = 1, память уже была очишена
data_color	db	00001010b
_boot		db"Проверка BOOT сектора диска С: ...",36
data_encript	db"Производится расшифровка диска C: ...",36
user_break	db"Программа прервана пользователем.                                               ",36 
error		db" Ошибка чтения/записи",13,10,36
clear_boot	db" Восстановлен",13,10,36
no_infection	db" Не заражен",13,10,36
no_find:	db" Не обнаружен",13,10,36
local_tive:	db" Частично обезврежен",10,13,36
delete:		db" Удален",10,13,36
revive:		db" Вылечен",10,13,36
infection:	db" Заражен"
_enter		db	10
_begin_pos	db	13,36

copyright	db 10,13
		db'╔══════════════════════════════════╗',13,10
		db'║     Ревизор вируса ACCT-3544     ║    Пример: ANTIACCT [D:][/F/G]',13,10
		db'║          ANTIACCT R1.12          ║     D: - диск поиска',13,10
		db'║  $'
gandvik         db   'Гандвикбанк$'
my_name	        db              '  Афанасьев Валерий  ║    /F  - лечить зараженные файлы',13,10
		db'║    Copyright (C) 1995 VGAsoft    ║    /G  - проверять все файлы подряд',13,10
		db'╚══════════════════════════════════╝',13,10,13,10
		db'Поиск вируса в памяти ...$'
_stack:		
cseg		ends
		end	start