Passworded MBR

This is an example of how to write some MBR code, which reads in a password and only continues booting if the password is correct.

Refer to How to write MBR code for introductory information.

Source:


	org 100h
fake_start:
	jmp	prog_start		; so the .COM file can be executed

	org	7c00h			; for MBR code
prog_start:
	... MBR code ...

This assembles the MBR code starting at offset 7C00h. This is necessary so that all memory references are correct when the BIOS loads the code to 0:7C00. The org 100h is present so that passmbr.asm can be assembled as a .COM file (.COM files are loaded to offset 100h when they are executed). Once PASSMBR.ASM is assembled, the MBR code can be found at offset 7B00 in PASSMBR.COM. The jump prog_start is there so that the .COM file can be run in a debugger (like DEBUG).

The code reads in a password one character at a time, printing out the message

	Non-System disk or disk error
	Replace and press any key when ready

as a 'prompt' before each character is pressed. The password itself is encrypted, so that anyone who views the code with a hex editor will not see the password.


	; set INT 60 - identifies the fact that the PC was booted from this MBR
	cli				; modifying the interrupt table!
	mov	dword ptr ds:[60h*4], 'DL00'
	sti

This code 'marks' the interrupt table so that once DOS is booted, it is easy to check if the computer was booted from this MBR. Why INT 60? Ralf Brown's interrupt list tells us:

INT 60 - reserved for user interrupt; multiple purposes
INT 61 - reserved for user interrupt; multiple purposes
INT 62 - reserved for user interrupt; multiple purposes
INT 63 - reserved for user interrupt; multiple purposes
INT 64 - reserved for user interrupt; multiple purposes
INT 65 - reserved for user interrupt; multiple purposes
INT 66 - reserved for user interrupt; multiple purposes

If we pick another interrupt (like 2F) chances are when DOS boots it will install its own handler for that interrupt. Note that this code does not really provide an interrupt handler (so executing an INT 60 will not work) but a program can just check the address of the INT 60 handler.


Once that is done, the code then executes the original MBR code, which is assumed to be saved at sector 2, head 0, track 0. Care needs to be taken with the partition table, because the real partition table is stored at sector 1, head 0, track 0 (and is currently in memory at 0:7DBE):

To install this code, the following needs to be done:
  1. Assemble PASSMBR.ASM
  2. Extract 446 bytes starting at offset 7B00 in PASSMBR.COM
  3. Read in the original MBR into a buffer
  4. Write the buffer to sector 2, head 0, track 0
  5. Replace the first 446 bytes in the buffer with the data from Step 2
  6. Write the modified MBR back to sector 1, head 0, track 0

© ztank
February 1999