Building a Secure Boot Loader from Scratch — BIOS, Assembly, and Password Lockout

A hands-on walkthrough of building a secure BIOS boot loader in pure assembly, with two-stage execution and pre-OS password protection.

May 16, 2025
HarrisonSec
3 min read
Low-Level Programming Operating Systems Assembly Security

Building a Secure Boot Loader from Scratch — BIOS, Assembly, and Password Lockout

See Also:

Project Summary

This post documents the construction of a BIOS-compatible x86 boot loader written entirely in 16-bit assembly. Unlike most tutorials, this project implements a two-stage loader with password-based lockout, forming the secure base for the QuantumVault cold storage system.


🔧 Why Build a Boot Loader?

  • To fully control a system from the first CPU instruction
  • To understand BIOS memory layout, MBR structure, and CHS addressing
  • To build a secure cold boot decryption system without any OS, runtime, or file system

🧠 Core Technical Features

✅ Stage 1: MBR Boot Loader (512 bytes)

  • Runs at 0x7C00 after BIOS loads first sector
  • Sets up segment registers and stack
  • Prints welcome message via INT 10h
  • Parses partition table to find active entry
  • Loads Stage 2 using INT 13h (CHS mode)
  • Passes geometry and drive info via real-mode shared memory

✅ Stage 2: Authenticated Loader

  • Loaded into RAM at 0x2000:0000
  • Prompts for password input using INT 16h
  • Verifies against hardcoded string
  • Allows 3 attempts only — then locks system
  • If correct, chains to FreeDOS system or AES decryption payload

✅ Security Mechanisms

  • BIOS interrupt vector usage only (no OS calls)
  • No reliance on FAT/FS — raw disk read via CHS
  • Memory-passed parameters for clean transition
  • Infinite loop lockout after failed attempts
  • Assembly routines for hex display and keystroke handling

🖥 Bootloader Execution Video

Watch the Demo


🔍 Key Technologies and Concepts

Area Technique Used
BIOS Interaction INT 10h (video), INT 13h (disk), INT 16h (keyboard)
Boot Sector Constraints 512 bytes incl. signature (0xAA55)
Segment Model Uses mov ss, ax, stack at 0x7C00 - 0x20
CHS Disk Access Cylinder/Head/Sector extracted from MBR
Password Input Loop reads keystrokes via INT 16h, compares with buffer
Lockout Control Loop halts system after 3 invalid tries
Debugging Toolchain QEMU + NASM + GDB (-s -S remote debug)
Real Mode Handoff Jump to 0x2000:0000, then to FreeDOS or vault.exe

🧪 Development Workflow Summary

  1. stage1.asm assembled into 446 bytes of MBR, leaving partition table untouched
  2. stage2.asm placed in sectors following MBR (sector 2 onward)
  3. Boot image prepared using dd to inject both stages into a FreeDOS disk
  4. Boot validated via QEMU:
    nasm -f bin stage1.asm -o stage1.bin
    nasm -f bin stage2.asm -o stage2.bin
    dd if=stage1.bin of=freedos.img bs=446 count=1 conv=notrunc
    dd if=stage2.bin of=freedos.img bs=512 seek=1 count=2 conv=notrunc
    qemu-system-i386 -drive file=freedos.img,format=raw
    

📆 What’s Next

More technical posts will follow to expand on CHS vs. LBA loading, stage 2 enhancements, and real-mode memory security. But for now, this bootloader demo stands alone as a clean, minimal, and auditable real-world implementation.

Stay curious, and keep digging down to the metal.

Comments

This space is waiting for your voice.

Comments will be supported shortly. Stay connected for updates!

Preview of future curated comments

This section will display user comments from various platforms like X, Reddit, YouTube, and more. Comments will be curated for quality and relevance.