home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / boot.asm < prev    next >
Assembly Source File  |  1991-04-01  |  14KB  |  248 lines

  1. ;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not
  2. ;self-reproducing, but it will be used as the foundation on which to build a
  3. ;virus into a boot sector.
  4.  
  5. ;This segment is where the first operating system file (IBMBIO.COM or IO.SYS)
  6. ;will be loaded and executed from. We don't know (or care) what is there, but
  7. ;we do need the address to jump to defined in a separate segment so we can
  8. ;execute a far jump to it.
  9. DOS_LOAD        SEGMENT AT 0070H
  10.                 ASSUME  CS:DOS_LOAD
  11.  
  12.                 ORG     0
  13.  
  14. LOAD:           DB      0               ;Start of the first operating system program
  15.  
  16. DOS_LOAD        ENDS
  17.  
  18.  
  19. MAIN            SEGMENT BYTE
  20.                 ASSUME  CS:MAIN,DS:MAIN,SS:NOTHING
  21.  
  22. ;This jump instruction is just here so we can compile this program as a COM
  23. ;file. It is never actually executed, and never becomes a part of the boot
  24. ;sector. Only the 512 bytes after the address 7C00 in this file become part of
  25. ;the boot sector.
  26.                 ORG     100H
  27.  
  28. START:          jmp     BOOTSEC
  29.  
  30. ;The following two definitions are BIOS RAM bytes which contain information
  31. ;about the number and type of disk drives in the computer. These are needed by
  32. ;the virus to decide on where to look to find drives to infect. They are not
  33. ;normally needed by an ordinary boot sector.
  34. ;
  35. ;               ORG     0410H
  36. ;
  37. ;SYSTEM_INFO:    DB      ?                       ;System info byte: Take bits 6 & 7 and add 1 to get number of
  38. ;                                                ;disk drives on this system (eg 01 = 2 drives)
  39. ;
  40. ;                ORG     0475H
  41. ;
  42. ;HD_COUNT:       DB      ?                       ;Number of hard drives in the system
  43. ;
  44. ;This area is reserved for loading the first sector of the root directory, when
  45. ;checking for the existence of system files and loading the first system file.
  46.  
  47.                 ORG     0500H
  48.  
  49. DISK_BUF:       DW      ?                       ;Start of the buffer
  50.  
  51. ;Here is the start of the boot sector code. This is the chunk we will take out
  52. ;of the compiled COM file and put it in the first sector on a 360K floppy disk.
  53. ;Note that this MUST be loaded onto a 360K floppy to work, because the
  54. ;parameters in the data area that follow are set up to work only with a 360K
  55. ;disk!
  56.  
  57.                 ORG     7C00H
  58.  
  59. BOOTSEC:        JMP     BOOT                    ;Jump to start of boot sector code
  60.  
  61.                 ORG     7C03H                   ;This is needed because the jump will get coded as 2 bytes
  62.  
  63. DOS_ID:         DB      'EZBOOT  '              ;Name of this boot sector (8 bytes)
  64. SEC_SIZE:       DW      200H                    ;Size of a sector, in bytes
  65. SECS_PER_CLUST: DB      02                      ;Number of sectors in a cluster
  66. FAT_START:      DW      1                       ;Starting sector for the first File Allocation Table (FAT)
  67. FAT_COUNT:      DB      2                       ;Number of FATs on this disk
  68. ROOT_ENTRIES:   DW      70H                     ;Number of root directory entries
  69. SEC_COUNT:      DW      2D0H                    ;Total number of sectors on this disk
  70. DISK_ID:        DB      0FDH                    ;Disk type code (This is 360KB)
  71. SECS_PER_FAT:   DW      2                       ;Number of sectors per FAT
  72. SECS_PER_TRK:   DW      9                       ;Sectors per track for this drive
  73. HEADS:          DW      2                       ;Number of heads (sides) on this drive
  74. HIDDEN_SECS:    DW      0                       ;Number of hidden sectors on the disk
  75.  
  76. DSKBASETBL:
  77.                 DB      0                       ;Specify byte 1: step rate time, head unload time
  78.                 DB      0                       ;Specify byte 2: Head load time, DMA mode
  79.                 DB      0                       ;Wait time until motor turned off, in clock ticks
  80.                 DB      0                       ;Bytes per sector (0=128, 1=256, 2=512, 3=1024)
  81.                 DB      12H                     ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies)
  82.                 DB      0                       ;Gap length between sectors for r/w operations, in bytes
  83.                 DB      0                       ;Data transfer length when sector length not specified
  84.                 DB      0                       ;Gap length between sectors for format operations, in bytes
  85.                 DB      0                       ;Value stored in newly formatted sectors
  86.                 DB      1                       ;Head settle time, in milliseconds (we set it small to speed operations)
  87.                 DB      0                       ;Motor startup time, in 1/8 seconds
  88.  
  89. HEAD:           DB      0                       ;Current head to read from (scratch area used by boot sector)
  90.  
  91. ;Here is the start of the boot sector code
  92.  
  93. BOOT:           CLI                                     ;interrupts off
  94.                 XOR     AX,AX                           ;prepare to set up segments
  95.                 MOV     ES,AX                           ;set ES=0
  96.                 MOV     SS,AX                           ;start stack at 0000:7C00
  97.                 MOV     SP,OFFSET BOOTSEC
  98.                 MOV     BX,1EH*4                        ;get address of disk
  99.                 LDS     SI,SS:[BX]                      ;param table in ds:si
  100.                 PUSH    DS
  101.                 PUSH    SI                              ;save that address
  102.                 PUSH    SS
  103.                 PUSH    BX                              ;and its address
  104.  
  105.                 MOV     DI,OFFSET DSKBASETBL            ;and update default
  106.                 MOV     CX,11                           ;values to the table stored here
  107.                 CLD                                     ;direction flag cleared
  108. DFLT1:          LODSB
  109.                 CMP     BYTE PTR ES:[DI],0              ;anything non-zero
  110.                 JNZ     SHORT DFLT2                     ;is not a default, so don't save it
  111.                 STOSB                                   ;else put default value in place
  112.                 JMP     SHORT DFLT3                     ;and go on to next
  113. DFLT2:          INC     DI
  114. DFLT3:          LOOP    DFLT1                           ;and loop until cx=0
  115.  
  116.                 MOV     AL,AH                           ;set ax=0
  117.                 MOV     DS,AX                           ;set ds=0 so we can set disk tbl
  118.                 MOV     WORD PTR [BX+2],AX              ;to @DSKBASETBL (ax=0 here)
  119.                 MOV     WORD PTR [BX],OFFSET DSKBASETBL ;ok, done
  120.                 STI                                     ;now turn interrupts on
  121.                 INT     13H                             ;and reset disk drive system
  122. ERROR1:         JC      ERROR1                          ;if an error, hang the machine
  123.  
  124. ;Here we look at the first file on the disk to see if it is the first MS-DOS or
  125. ;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively.
  126. LOOK_SYS:
  127.                 MOV     AL,BYTE PTR [FAT_COUNT]         ;get fats per disk
  128.                 XOR     AH,AH
  129.                 MUL     WORD PTR [SECS_PER_FAT]         ;multiply by sectors per fat
  130.                 ADD     AX,WORD PTR [HIDDEN_SECS]       ;add hidden sectors
  131.                 ADD     AX,WORD PTR [FAT_START]         ;add starting fat sector
  132.  
  133.                 PUSH    AX
  134.                 MOV     WORD PTR [DOS_ID],AX            ;root dir, save it
  135.  
  136.                 MOV     AX,20H                          ;dir entry size
  137.                 MUL     WORD PTR [ROOT_ENTRIES]         ;dir size in ax
  138.                 MOV     BX,WORD PTR [SEC_SIZE]          ;sector size
  139.                 ADD     AX,BX                           ;add one sector
  140.                 DEC     AX                              ;decrement by 1
  141.                 DIV     BX                              ;ax=# sectors in root dir
  142.                 ADD     WORD PTR [DOS_ID],AX            ;DOS_ID=start of data
  143.                 MOV     BX,OFFSET DISK_BUF              ;set up disk read buffer at 0000:0500
  144.                 POP     AX
  145.                 CALL    CONVERT                         ;and go convert sequential sector number to bios data
  146.                 MOV     AL,1                            ;prepare for a disk read for 1 sector
  147.                 CALL    READ_DISK                       ;go read it
  148.  
  149.                 MOV     DI,BX                           ;compare first file on disk with
  150.                 MOV     CX,11                           ;required file name
  151.                 MOV     SI,OFFSET SYSFILE_1             ;of first system file for PC DOS
  152.                 REPZ    CMPSB
  153.                 JZ      SYSTEM_THERE                    ;ok, found it, go load it
  154.  
  155.                 MOV     DI,BX                           ;compare first file with
  156.                 MOV     CX,11                           ;required file name
  157.                 MOV     SI,OFFSET SYSFILE_2             ;of first system file for MS DOS
  158.                 REPZ    CMPSB
  159. ERROR2:         JNZ     ERROR2                          ;not the same - an error, so hang the machine
  160.  
  161. ;Ok, system file is there, so load it
  162. SYSTEM_THERE:
  163.                 MOV     AX,WORD PTR [DISK_BUF+1CH]      ;get file size of IBMBIO.COM/IO.SYS
  164.                 XOR     DX,DX
  165.                 DIV     WORD PTR [SEC_SIZE]             ;and divide by sector size
  166.                 INC     AL                              ;ax=number of sectors to read
  167.                 MOV     BP,AX                           ;store that number in BP
  168.                 MOV     AX,WORD PTR [DOS_ID]            ;get sector number of start of data
  169.                 PUSH    AX
  170.                 MOV     BX,700H                         ;set disk read buffer to 0000:0700
  171. RD_BOOT1:       MOV     AX,WORD PTR [DOS_ID]            ;and get sector to read
  172.                 CALL    CONVERT                         ;convert to bios Trk/Cyl/Sec info
  173.                 MOV     AL,1                            ;read one sector
  174.                 CALL    READ_DISK                       ;go read the disk
  175.                 SUB     BP,1                            ;subtract 1 from number of sectors to read
  176.                 JZ      DO_BOOT                         ;and quit if we're done
  177.                 ADD     WORD PTR [DOS_ID],1             ;add sectors read to sector to read
  178.                 ADD     BX,WORD PTR [SEC_SIZE]          ;and update buffer address
  179.                 JMP     RD_BOOT1                        ;then go for another
  180.  
  181.  
  182. ;Ok, the first system file has been read in, now transfer control to it
  183. DO_BOOT:
  184.                 MOV     CH,BYTE PTR [DISK_ID]           ;Put drive type in ch
  185.                 MOV     DL,BYTE PTR [DRIVE]             ;Drive number in dl
  186.                 POP     BX
  187.                 JMP     FAR PTR LOAD                    ;and transfer control to the first system file
  188.  
  189.  
  190. ;Convert sequential sector number in ax to BIOS Track, Head, Sector information.
  191. ;Save track number in DX, sector number in CH,
  192. CONVERT:
  193.                 XOR     DX,DX
  194.                 DIV     WORD PTR [SECS_PER_TRK]         ;divide ax by sectors per track
  195.                 INC     DL                              ;dl=sector number to start read on, al=track/head count
  196.                 MOV     CH,DL                           ;save it here
  197.                 XOR     DX,DX
  198.                 DIV     WORD PTR [HEADS]                ;divide ax by head count
  199.                 MOV     BYTE PTR [HEAD],DL              ;dl=head number, save it
  200.                 MOV     DX,AX                           ;ax=track number, save it in dx
  201.                 RET
  202.  
  203.  
  204. ;Read the disk for the number of sectors in al, into the buffer es:bx, using
  205. ;the track number in DX, the head number at HEAD, and the sector
  206. ;number at CH.
  207. READ_DISK:
  208.                 MOV     AH,2                            ;read disk command
  209.                 MOV     CL,6                            ;shift possible upper 2 bits of track number to
  210.                 SHL     DH,CL                           ;the high bits in dh
  211.                 OR      DH,CH                           ;and put sector number in the low 6 bits
  212.                 MOV     CX,DX
  213.                 XCHG    CH,CL                           ;ch (0-5) = sector, cl, ch (6-7) = track
  214.                 MOV     DL,BYTE PTR [DRIVE]             ;get drive number from here
  215.                 MOV     DH,BYTE PTR [HEAD]              ;and head number from here
  216.                 INT     13H                             ;go read the disk
  217. ERROR3:         JC      ERROR3                          ;hang in case of an error
  218.                 RET
  219.  
  220. ;Move data that doesn't change from this boot sector to the one read in at
  221. ;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and
  222. ;the data area at the beginning of the boot sector.
  223. MOVE_DATA:
  224.                 MOV     SI,OFFSET DSKBASETBL            ;Move all of the boot sector code after the data area
  225.                 MOV     DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC)
  226.                 MOV     CX,OFFSET DRIVE - OFFSET DSKBASETBL
  227.                 REP     MOVSB
  228.                 MOV     SI,OFFSET BOOTSEC               ;Move the initial jump and the sector ID
  229.                 MOV     DI,OFFSET DISK_BUF
  230.                 MOV     CX,11
  231.                 REP     MOVSB
  232.                 RET
  233.  
  234.  
  235. SYSFILE_1:      DB      'IBMBIO  COM'                   ;PC DOS System file
  236. SYSFILE_2:      DB      'IO      SYS'                   ;MS DOS System file
  237.  
  238.                 ORG     7DFDH
  239.  
  240. DRIVE:          DB      0                               ;Drive number, used in disk reads, etc.
  241. BOOT_ID:        DW      0AA55H                          ;Boot sector ID word
  242.  
  243.  
  244. MAIN            ENDS
  245.  
  246.  
  247.                 END START
  248.