"Deep
in the sea are riches beyond compare.
But if you seek safety, it is on the shore."
How
to write MBR Code
Description: There is lots of info on how to make MBR(Master Boot
Record)
-based programs, but its all scattered or outdated. This is an
attempt to collect the useful information into a single relevant
tutorial/example.
And
the text:
Ok,
so you want to write some code and put it on your MBR for some
stupid
reason... well here's the basics on getting it to work!
WARNINGS!!
This
stuff isn't guaranteed to work, for all you know I could have
a monkey typing this... and also this will only work with a "standard"
computer... i.e... with no special MBR programs already installed.
You have been warned!
Also,
it has come to my attention that Win2k/XP have special features
that apparently have no need for a partition table, and thus no
need for an MBR.
I haven't played with these yet, but you probably will have to
be more creative if these facts happen to be true (i.e.. don't
use this tut for those computers with that system on them).
1.
Usefulness/Prior Knowledge
Is
there really a purpose for stuff like this except as a virus?
Well, if you think about it there are plenty of things you can
use it for.. security, encryption, for the hell of it, curiosity..
any number of reasons, most of them focused on security and screwing
someone's computer up.
I’m
going to assume you know about programming x86 assembly language
and how to do BIOS calls. If you dont know, look somewhere else...
Search for Ralf Brown's Interrupt List... excellent reference
on BIOS calls. Also, I’m going to assume you have a fairly
good idea about how windows and DOS work... if
you're writing your own OS you should already know most of this
anyway.. and Linux has a great boot sector loader so you aren't
writing that either.
2.
How to install
Ok,
well you have to get the code there before you figure out what
to write, but how exactly can you do this? What you do is this:
Write
a program that will drop your MBR code where it’s supposed
to be (CHS 0/0/1 or LBA 1) and you're done. Make sure you DONT
overwrite the partition table otherwise the hard drive is useless.
The partition table starts at offset 1BEh within the boot sector.
Also, make sure that the last two bytes of the
sector are 55AAh otherwise the BIOS will complain. One bad thing
about doing this: It’s not easy to do it within Windows!
Windows has antivirus like protections that prevent "direct
disk access", which can be annoying but makes sense to have
in the OS. Here's two ways of doing this:
(a)
Run install program from DOS
This
is the easiest way, because of you can use BIOS calls to make
changes.
Usually this will work from installing from a boot disk or using
autoexec.bat to run the installer before Windows comes up (although
this may not work in WinNT/2000/XP!). Most reliable way is make
a bootable floppy to automatically run the install program. Once
again, needs to be a DOS/Win9x
boot disk otherwise you boot into windows (which is really stupid...
what’s the purpose of using a boot disk to repair windows
if it tries to start windows?? Microsoft is so *smart*... grr).
Anyway, stick the installer on the floppy and make it run automatically
when it boots itself (autoexec.bat... duh).
(b) Run install program from within Windows... maybe
Well, I said it’s hard to do it from within Windows, and
it is mainly
because I haven’t been able to get it to work. There is
a way that uses a VXD, but that would only work in Win9x only
anyway... and I don't know how to code VXD's anyway... there must
be an easier way because I've seen programs write MBR from within
Windows before... but maybe you can, maybe
you can't. I honestly don't know. Anyone who can provide me with
more information on how this is done email me, as I would really
appreciate it... :-)
3.
Writing the code
Ok,
if you're anything like me you don’t like being bothered
with size restraints and wish that all computers have tons of
memory and hard drive space and etc... but you only have 512 bytes
to work with on the MBR. This can pose a problem for most people,
so here's how I get around it.
The
way Windows is set up, the first cylinder has no data on it
whatsoever... zilch. On most computers this is equivalent to 63
sectors.
Some of the newer partitioning schemes are getting rid of this,
but we'll assume that we're using a "standard" computer.
Anyway, all partitions start on a cylinder boundary... even with
LBA addressing, so we have around 32k to work with here... but
to be safe you shouldn't use more than 20-30 sectors and make
sure your install program checks to make sure that there really
isn't anything there... otherwise you can screw a computer up.
Not a good thing (usually).
So,
with this in mind, I write my program however long I want... but
put it AFTER the MBR. I write a simple MBR that loads my program
into memory and runs it. Make sure you use the proper offset though;
otherwise your program will act funny because the data it thinks
is there isn't there, but somewhere else. The sample code included
does exactly this, and even keeps
the correct offset for you. When you load your program into memory,
make sure that you don’t overwrite any important system
tables... not a good idea.
Technically,
you could write the program in C or something like that, and just
write the MBR in asm and use it to load the program, just make
sure you compile in binary mode and that you DONT use protected
mode stuff unless you switch to protected mode. Also, don’t
worry about allocating memory, the
code will be overwritten as soon as the OS loads.
One
other thing: NO OPERATING SYSTEM SPECIFIC CALLS!! Windows/DOS/Linux/ETC
hasn't loaded yet, so whatever services they provide don't exist
yet. You must use BIOS calls or direct hardware access to do what
you need to do.
This
makes MBR programs very powerful indeed..
Now,
when your program finishes doing whatever the hell it’s
doing, you need to load the OS otherwise the user is screwed.
Once again, 2 ways to do this.
(a)
Keep the old MBR and load it at 0000:7c00h and let it do its thing.
This is my personal preference because of it guards against having
a weird boot loader and then you screw the computer up. Only conflict
is if you have a multiple sector loader like your own program.
(See warnings)
(b)
Automatically detect partitions and load the OS that way. Just
load the first sector of the partition to 0:7c00h and run it.
As this is considerably harder to implement for various reasons,
I prefer method A. But to each their own... just make sure the
program can differentiate between LBA
partitions and CHS. Look on the net for more info...
Ok,
I think I've covered the basics...
4.
Testing
Some
rules for testing your program...
#1
Don’t use the system you use for everything and have all
your important data on... not smart. If possible, get an emulator
such as VMWare and test program using that... although before
final release/deployment of your final version test it on a real
computer that way you KNOW it works. Even better,
test on multiple computers with different hardware configurations
and BIOS on them.
#2
Make a backup of the MBR of the computer you're testing it on
so you can easily restore system after each test.
#3
It won't work at first! This is kinda a given, but with this in
mind build debugging features into the program so you know what’s
wrong. If you crash the program you can't really tell what happened
if all you see is a blank screen. I usually echo characters to
the screen to tell how far the program has progressed before it
crashes.
#4
If the program does crash, fully power down the computer before
testing again, otherwise system tables or other important stuff
could have been erased. CTRL-ALT-DEL won't help you.. or the reset
button.
#5
Test program on different platforms... just because Win95 does
one thing doesn't mean Win2k will do the same thing... or even
Win98 for that matter.
#6
Patience...
5.
Uninstallation
Here's
a nice trick that you've probably heard before... but it works
(sometimes). If you write an MBR that keeps the partition table
in the original place and doesn't modify it, you can use fdisk
/mbr to remove your code. (To newbies: boot to DOS, type that
at the prompt) Bad thing is fdisk doesn't exist in NT/2k/XP (at
least to my knowledge), so it only works on Win9x computers. Now,
if you do something to the partition table, then you have to have
a custom uninstallation program.
Uninstallation is as easy as installing.. just replace new MBR
with old and zero out the rest of the sectors. Piece of cake if
you can do the installation...
6.
Conclusion
Ok,
there really isn't much to programming your MBR, you just need
to be really creative in some cases, but that’s what programming
is about, right?
I hope this was useful and if you have any questions/comments
e-mail me.
- Random Person
|