I am an electrical engineer who has recently discovered the need to modify the code in the MBR. Basically I need the ability to execute code on the HDD before, the OS starts up
Why does it go without saying that Windows doesn't allow direct access to the disk? The MSDN page for CreateFile() says this:
Direct access to the disk or to a volume is restricted. For more information, see "Changes to the file system and to the storage stack to restrict direct disk access and direct volume access in Windows Vista and in Windows Server 2008" in the Help and Support Knowledge Base at http://support.microsoft.com/kb/942448.
Windows Server 2003 and Windows XP/2000: Direct access to the disk or to a volume is not restricted in this manner.
KB942448 explains the restrictions, and they seem to allow a process with sufficient privileges to write to the MBR or to a partition boot sector.
Windows has an undocumented utility "debug" which allows to:1) load any sector (including mbr) of hdd to ram. 2)view that code as binary or assemby. 3) Assemble some code in ram.4) write that code to any sector (to mbr also). To start this utilty, type debug at command promt, hit enter. The prompt changes to "-" .then type "help". you get informstion abot how to use it,
I think your best way is with linux, it has nasm
for compiling, dd
for cluster copying (which means MBR as well), and even a boot loader menu (lilo
for example) if you don't want to mess with your actual partitions.
I had to make my own boot sequence last year. Basically, I had this:
LILO boot menu:
-> WindowsXP
-> linux
I wanted to do something seperately on an MBR, without affecting the actual install, so I created a new (small) partition and added that to the LILO list (omitting details here), which gave this:
LILO boot menu:
-> WindowsXP
-> linux
-> TESTMBR
That way, since every partition has its own MBR as well, I could put any whacky code I wanted in there without the risk of locking myself out (which is a little annoying to fix).
To actually change that MBR I did this:
dd if=/dev/sda3 of=/home/you/mbr−backup count=1
nasm boot.asm -o boot.bin -f bin
correcting if errorsdd if=boot.bin of=/dev/sda3
Sure, you can do that directly on the drive's MBR instead of the partition's MBR like I did here, but for my own case it was more practical.
Concerning the actual code-jumping-out-of-MBR, you'll need to use the INT 13,42 interruption, which loads any cluster on a disk. For the purpose of my test I just had to display its contents, but I can take a closer look if you want.
Hope that could help, sorry for the long reply.
Are you sure you need to write the MBR? I a disk with partitions, you can also modify the partition's VBR (Volume Boot Record). That may be easier/safer, as you don't need to touch the MBR and your machine will still able to boot to other partitions (and OS), even if you totally destroy your test partition.
The BIOS boots the computer from the hard drive (or floppy drive) by reading the first sector (512 bytes) of each boot device and checking for a specific set of signature bytes. If those bytes are found, the 512 byte sector is copied to ram (at a specific position) and BIOS jumps to run it.
Other then the signature bytes, 446 bytes in the sector are available for you to use as your boot program, but the boot program must fit entirely in that sector! Since 446 bytes isn't very large, you will have to make BIOS calls to copy other sectors off the hard drive (or floppy drive, or whatever) into ram to run those.
Once you've loaded enough into ram to run your program, jump to it and you're good to go.
That is how an operating system literally "pulls itself up by it's own bootstraps"
See http://en.wikipedia.org/wiki/Master_boot_record
Now, there's no reason you couldn't write the boot code in C or C++ (or most anything else) except that with assembly, you know exactly what code will be generated and it's easy to make BIOS calls.
I would suggest you write a 512 byte disk drive to ram copier that loads your program from the disk into ram, and then jumps to the start address of your program. You can then write your program in any language you want. Keep in mind that when your boot code starts running, those 512 bytes are the only thing you can count on as in the ram. (Well, the BIOS is there you can make BIOS calls. The BIOS will also place some system information at certain places in ram...) If you want to call any functions you've written that are outside that sector, you have to load them into ram yourself.
Also, the easiest way to test your code will probablly be to put it on a floppy disk and boot off that.
To answer your original question, you could keep a backup copy of the old MBR somewhere, and your new MBR could load your function into ram, run it, then load the original MBR and run that, allowing windows to continue booting.
Also, Michael Burr is right, getting what you want done is going to be a nightmare.
In answer to your comment about how to actually write this on the hard drive, there are several "raw write" programs that can copy to a sector on the disk. Also, you could just boot off a linux live cd and use dd to write your data to the sector of your choice on the block device of your choice. -- Simple as pie that part.
You could look into GRUB. I am by no means an expert at MBR code and it's been a long while since I ran a *nix OS, but I remember that the bootloader worked in stages and loaded the stages from the disk before the OS started. You could write your own stage to do the work you need done before the OS loads and then boot the OS. I'm not sure how practical this option is, particularly since the code seems to be in the middle of a rewrite because the "legacy" version was unmaintainable according to the documentation.