Programming - The Boot Sector
Programming - The Boot Sector
A Message Board Shells The Team Online Chat Links Translations Books
http://blacksun.box.sk
http://awc.rejects.net
_____________________________
______________________I Topic: I_____________________
\ I I /
\ HTML by: I The Boot Sector I Written by: /
> I I <
/ Martin L. I_____________________________I Ralph \
/___________________________> <_________________________\
TOC
1. Introduction
❍ What you need
2. Basic hard drive/BIOS shit
3. Making a Boot Sector
4. Making a program to write a boot sector
5. Other
1. Introduction
Well usually I give you a specific purpose at this point, but in this case I can't. I was just in the mood to write
something on boot sectors so I did it. And maybe (hopefully) someone out there can make use of this info. This
thing will most likely became part of a larger tutorial, maybe something on assembly or on OS design. After having
consumed this text file you should know enough to design and create your own boot sector, maybe for a virus, or
an OS, or...?
Why am I using 2 different programs? Well I have always used NASM to make simple programs as it's good at
creating efficient memory copies. I always use TASM to make programs a bit more complex. In the end however it
comes down to the answer "why not??". However, it shouldn't be hard at all to make the TASM program in NASM
(or the other way around), just change a few things here and there. If enough people come bitch to me, I'll rewrite
all the code for NASM/TASM.
As you should know, CD = INT. INT 19h attempts to read in the Boot Sector of the 1st floppy disk. If it fails it does
the same thing on the 1st hard drive. If that fails it returns an error message. A valid boot sector must have its last
two bytes set to AA55h. Assuming a valid boot sector is found, the code is loaded into memory at location
0000:7C00 and interrupt 19h jumps there to start executing the code. Since a boot sector has to fit into one sector
(512 bytes) it can't really do much, usually it does a search for another file on another sector, then executes it. Our
boot sector won't do that. For now it is enough that it displays a message and reboots when you press a key. Since
DOS is not loaded yet, we have to use BIOS interupts to do all this. First we display a messages using interupt
10h. Next we wait for the user to press a key using interrupt 16h, and finally we make a FAR jump to FFFF:0000
which we restart the computer. So lets code this bitch:
MOV AX,0x0003
INT 0x10
to get into video mode. The registers have to be set up like this:
AH Function number (00h, video)
AL Video Mode (03, 80x25x16)
Next we print the message using:
MOV AX,0x1301
MOV BX,0x0007
MOV CX,0x23
MOV BP,MSG
ADD BP,0x7C00
INT 0x10
AH Function number (13h: print string)
AL Write Mode (01h: string is characters only, attribute in BL, cursor moved)
BH Video Page number (00h)
BL Attributes of characters (07h)
CX Length of string, excluding any attributes (23h = 35 characters)
ES:BP must point to the string, since a boot sector starts at 07C00, we add that to BP after we loaded it. You
BP could also set the entry point of the program to 07C00, or change the data segment register to point to
07C00, but since it's just one instruction, this is fine for now.
Now we wait for the key to be pressed:
MOV AH,0x00
INT 0x16
Registers:
AH - 00, Read keyboard buffer, wait till full if not already.
The buffer will be empty since the computer didn't get time to put anything into it yet. Finally we reboot the
computer by simply jumping to 0000:FFFF:
DB 0xEA
DW 0x0000
DW 0xFFFF
This looks a bit wierd but it's actualy quite simple. When declaring "variables" in assembly, the assembler simply
puts the value into a memory location. Usually you use interrupts or something to point to them in order to use
and manipulate them, but we could also put code there. This is what we're doing here. If you get a Hex to
Mnemonix chart you will notice that EA is a Far Jump. So we put that into memory, followed by the location to
jump to.
TIMES 510-($-$$) DB 0
This could also be done in TASM with something like TIMES 510 DUP (0). Finally we have to add those two bytes to
the end so that the BIOS will know that this is a valid boot sector. This is done with the simple statement:
SIGNATURE DW 0xAA55
START:
MOV AX,0x0003
INT 0x10
PRINT_STRING:
MOV AX,0x1301
MOV BX,0x0007
MOV CX,0x23
MOV BP,MSG
ADD BP,0x7C00
INT 0x10
WAIT_FOR_KEY_PRESS:
MOV AH,0x00
INT 0x16
REBOOT:
DB 0xEA
DW 0x0000
DW 0xFFFF
MSG DB 'pR3sS 4nY k3y 2 k0n71nu3',13,10,'btw, ph33r',0
TIMES 510-($-$$) DB 0
SIGNATURE DW 0xAA55
Assemble with "nasm filename.asm". This will get you a file called "filename", no extension. It is a raw binary
image of the code. Get out a floppy and type "debug filename". Enter this at the prompt: w 100 0 0 1. You should
know what this does from my assembly tutorial, if not it simply means write whatever is in memory to location 100
on disk 0 (A:), starting from sector 0 to sector 1. Now try booting from this disk. You should get the message:
And when you press a key, the keyboard buffer gets filled so interupt 16h is finished and we move on to the restart
procedure. Obviously this was just a simply example, instead of printing a string, waiting for a key press and
restarting, you could've put anything in there, just as long as you don't use DOS interupts. One nice thing might be
to get into Protected Mode, or you could even do some graphics shit which might run faster than in DOS or
Windows since nothing is in memory except what you want to be there.
READFILE:
MOV AX,3D00h
MOV DX,OFFSET FILENAME
INT 21h
This will return the file handle in AX. If an error has occured, the carry flag will be set and the error code stored in
AH. In that case, branch:
JC ERROR
MOV BX,AX
MOV AH,3Fh
MOV CX,0200h
MOV DX,OFFSET SHIT
INT 21h
First we move the file handle from AX into BX, then set up the other registers as follows:
AH = 3Fh, Read file
CX = 200h, Amount of data to read. Since a boot sector will always be 512 bytes long we read in 200h bytes
(512d).
DX = Points to memory area to hold contents of file
Again, the carry flag will be set if an error occured, so branch:
JC ERROR
Now we're getting to the actual writing part. First we reset the floppy disk controller with the code:
WRITE_SECTOR:
MOV AH,0h
MOV DL,0
INT 13h
MOV AX,0301h
MOV CX,1
MOV DX,0
MOV BX,OFFSET SHIT
INT 13h
This is one of the more complicated interupts, and you have to know some shit about how hard drives are made
up.
AH = 03h, Write Sector
AL = 1, Number of sectors to write on same track and head
CH = 0, Track number to write
CL = 1, Sector number to start writing from
DH = 0, Head number to write
DL = 0, Drive number to write (0 = A, 1 = B, etc)
BX = Buffer to write sector(s) from
Again the carry flag is set if an error occurs, but I like to keep things interesting and used a different method to
check for an error. The error code is stored in AH, if AH is 0 there was no error. So to check for an error I can
simply XOR AH, AH and Jump if Not Zero.
XOR AH,AH
JNZ ERROR
INT 20h
ASSUME CS:MAIN,DS:MAIN,ES:MAIN,SS:MAIN
ORG 100h
START:
MOV AX,3D00h
MOV DX,OFFSET FILENAME
INT 21h
JC ERROR
MOV BX,AX
MOV AH,3Fh
MOV CX,0200h
MOV DX,OFFSET SHIT
INT 21h
JC ERROR
MOV AH,0h
MOV DL,0
INT 13h
MOV AH,03h
MOV AL,1
MOV CX,1
MOV DX,0
MOV BX,OFFSET SHIT
INT 13h
XOR AH,AH
JNZ ERROR
INT 20h
ERROR:
Now this thing is very very basic. There are many areas you could improve on. For example:
1. Make the filename a user inputed value. To do so, make FILENAME an array of 12 unitialized bytes (DOS
filenames can't be longer than that). Than load that array into SI and call interupt 16h, function 0h. Loop it
until enter is pressed, store the value in SI, incrementing SI each time.
2. Add more error messages, maybe even something that checks the error code and response with an
appropriate message
3. This program wont wait for the motor to start up, so make a loop that loops about 3 times, checking if the
disk drive is ready. If all tries fail, return an error saying that the disk is not in the drive or something. The
error code is returned in AH, so you can make a simple check and respond with the corrosponding error
message.
4. Display a (C) Microsoft message
5. Other
If you fuck up your computer as a result of this tutorial, don't blame me. All code has been tested and works great,
but I cannot be held responsible for anything that happens to you as a result of using this information.
You may freely distribute this text as long as you don't change anything. If there's something you think should be
changed, contact me first.
Please always get the newest version of this an other tutorials at http://awc.rejects.net as they usually contained
updated information, and addons.
Greetings to:
cozgedal, skin_dot, Linxor, jyc, rpc, moJoe, Lindex, aphex twin
EOF