Statistics

Members: 1927
News: 293
Web Links: 1
Visitors: 3933358

Who's Online

Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home arrow About/Disclaimer
Writing Boot Sectors To Disk
User Rating: / 1
PoorBest 
Written by Jan Verhoeven   


In my previous article I showed how to make a private non-bootable bootsector for 1.44 Mb floppy disks. Unfortunately, there was no way yet to write that non-bootsector to a floppy disk....

Enter this code. It is the accompanying bootsector writer for floppy disks. It assumes that your A: drive is the 1.44 Mb floppy disk drive and I dare say that this will be true in the majority of cases.

The assembler used

As usual, I have written this code in A86 format. Until now, not many aspects of the A86 extensions have been used, but, believe me, in future articles this will be done.

A86 is particularly useful for people that make syntax errors. It will insert the errormessages into the sourcefile so that you can easily find them back. In the next assembler run the error messages are removed again.

To fully use this aspect of A86 programming, I made a small batchfile that will let me choose between several options while writing the code. Below you can see the file. After an error, I choose to go back into the editor. When there are no errors, I might decided to do a trial run. Or to quit to DOS.

This is all done by means of the WACHT command which waits for a keypress. It returns (in errorlevel) the indexed position in the command tail table of th key which was pressed.

Rapid assembly prototyping.


For easy processing and running sourcefiles I use a small batchfile, which looks like:

----------- Run.Bat --------------------------------------- Start --------- @echo off
if "%1" == "" goto leave

:start

ed %1.a86
a86 %1.a86 %2 %3 %4 %5 %6

:menu

Echo *
Echo Options:
Echo *Escape = stop
Echo * L = LIST
echo * ;-() = back to the editor
echo * space = test-run of %1.com
echo *Period = debugger-run with %1.com/sym

wacht  .\=-[]';-()/":?><{}|+_LCE

if errorlevel 27 goto start
if errorlevel 26 goto screen
if errorlevel 25 goto list
if errorlevel 4 goto start
if errorlevel 3 goto debugger
if errorlevel 2 goto execute
if errorlevel 1 exit
goto menu

:execute
%1
if errorlevel 9 echo Errorlevel = 9+
if errorlevel 8 echo Errorlevel = 8
if errorlevel 7 echo Errorlevel = 7
if errorlevel 6 echo Errorlevel = 6
if errorlevel 5 echo Errorlevel = 5
if errorlevel 4 echo Errorlevel = 4
if errorlevel 3 echo Errorlevel = 3
if errorlevel 2 echo Errorlevel = 2
if errorlevel 1 echo Errorlevel = 1
goto menu

:debugger
vgamode 3
d86 %1
goto menu

:list
list
goto menu

:screen
vgamode 3
goto menu

:leave
echo No file specified
----------- Run.Bat ---------------------------------------- End ----------

This BAT file relies heavily on my computer system. For one, I use DR-DOS 6 which means that I can use the EXIT word to get out of a Batchfile.

Also, I switch videomodes back to Mode 3 with "Vgamode 3" and you will have to use another command for that, like "Mode co80" or using the utillity that came with your videocard.

The program "List" is Vernon Buerg's file lister which I use to track down errors in all kinds of files.

How to write a sector to disk.


Globally there are three methods. The first would be to program the floppy disk controller, but that is just downright difficult. A second approach would be to use INT 026, the way DOS does things.

I chose for the BIOS method. For non-partitioned diskstructures this is the easiest way. Just select track, head and side and write data to the sectors on that disk.

The bootsector is the very first sector on a disk. For a floppy disk this boils down to track 0, head 0 and sector 1 (sectors are counted from 1, not from 0!).

The code is very straightforward. What it does is:

  • reset disk drive controller
  • open the file to transfer to the bootsector
  • read file into internal buffer
  • close the file
  • repeat 5 times:
  • try to tranfer buffer to bootsector of drive A:
  • shut down and return to DOS.
  • if an error occurs, the user is informed about it.

That's all there's to it.

The Source.


Below is the sourcecode for this short utillity. I have commented just about any line I thought fit for it.

----------- Wrs.A86 --------------------------------------- Start --------- name wrs
title WRite Sector
page 80, 120

stdout   =  1                       ; the "standard" equates
lf       = 10
cr       = 13
DATA segment                      ; define the volatile data area
buffer   db    512 dup (?)          ; this is enough for one sector
EVEN                       ; make sure WORD starts at an even address
Handle   dw    ?                    ; handle number of file to write
; ----------------------
CODE segment                      ; start of the actualk code
; no ORG, so we start at offset 0100
jmp   main                 ; jump forward to entry point
db    'VeRsIoN=0.2', 0
db    'CoPyRiGhT=CopyLeft 1999, Jan Verhoeven, '
db    '{
 This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
 }', 0
; ----------------------
filename db    'BootLoad.bin', 0        ; name of file to send to disk

Mess001 db 'Cannot open file BootLoad.bin. '

db 'Operation aborted.', cr, lf Len001 = $ - Mess001

Mess002 db 'Something went wrong while writing to disk.', cr, lf Len002 = $ - Mess002

Mess003 db 'The floppy disk subsytem reported an error. '

db 'Trying once more.', cr, lf Len003 = $ - Mess003

Mess004 db cr, lf, 'Bootsector written. '

         db            'Thank you for using this software.'
db    cr, lf, 'This program is GNU GPL free software and you use '
db            'it at your won risk.'
db    cr, lf, 'Please study the GNU '
db            'General Public License for more details.', cr, lf

Len004 = $ - Mess004
; ----------------------
Error1: mov dx, offset mess001 ; process "cannot open file"

         mov   cx, len001
mov   bx, stdout
mov   ah, 040
int   021                  ; print via DOS
mov   ax, 04C01            ; exit with errorcode = 1
int   021

; ----------------------
Error2: mov dx, offset mess002 ; process "disk error"

         mov   cx, len002
mov   bx, stdout
mov   ah, 040
int   021                  ; via DOS
mov   ax, 04C02            ; exit with errorcode = 2
int   021
; ----------------------
Error2a: push  ax, bx, cx, dx       ; process "Disk not ready"
mov   dx, offset mess003   ; point to message
mov   cx, len003           ; this many bytes
mov   bx, stdout           ; to the console
mov   ah, 040              ; do a write
int   021                  ; via DOS
pop   dx, cx, bx, ax       ; restore state of machine
ret                        ; and return to caller
; ----------------------
main:    mov   dl, 0                ; choose drive A:
mov   ah, 0                ; select funtion 0 ...
int   013                  ; ... reset diskdrives
mov   dx, offset filename  ; point to name of file
mov   ax, 03D00            ; to open
int   021                  ; via DOS
jc    Error1               ; if error, take action
mov   [Handle], ax         ; no error, => ax = handle
mov   dx, offset buffer    ; setup pointer, ...
mov   cx, 512              ; ... byte count, ...
mov   bx, ax               ; ... and handle
mov   ah, 03F              ; to read data from file
int   021                  ; via DOS
mov   bx, [Handle]
mov   ah, 03E
int   021                  ; close this file
mov   cx, 5                ; prepare for a five times LOOP
L0:      push  cx
mov   bx, offset buffer
mov   es, ds               ; es:bx = buffer to read from
mov   dx, 0000             ; drive A:, head 0
mov   cx, 0001             ; Track 0, Sector 1
mov   ax, 0301             ; Write sectors, 1 sector
int   013                  ; via BIOS
jnc   >L1                  ; if no error, jump forward
pop   cx                   ; Houston, we have an error!
call  error2a              ; inform the user
loop  L0                   ; and try again
jc    error2               ; after five times still no go....
L1:      mov   dx, offset Mess004   ; Signal that we're successful
mov   cx, Len004
mov   bx, stdout           ; to the console
mov   ah, 040
int   021                  ; via DOS (so it can be redirected)
mov   ax, 04C00            ; mention that there were no errors
int   021                  ; and return to DOS

----------- Wrs.A86 ---------------------------------------- End ----------

Have fun experimenting with bootsectors. But take care that this will NOT work on a hard disk.

Hard disk structure.


A hard disk uses another layout for it's structure. The very first sector of a HDD is the MBR (Master BootRecord). It is the only sensible sector in the first track of a normal HDD. The rest is just empty.

Each partition starts at a cylinder boundary, so the first one starts at cylinder 1 (track 1, side 0, sector 1). The very first sector of a bootable partition is the bootsector.

The MBR contains the partition table, indicating where partitions start and end and whether they are bootable or not. Plus some code to interpret that table and to find the bootsector that was selected.

If you write a floppy disk bootsector to the very first sector of a HDD, you wipe out the MBR and hence make inaccesable all data on that disk. The data will still be there, but the system will not be able anymore to find or use it.

So please take care that this software is NOT used for drive (DL=) 080.

{ This e-mail address is being protected from spam bots, you need JavaScript enabled to view it }