2020-02-19 18:48:24 +00:00
|
|
|
|
/********************************************************************************/
|
2020-02-19 14:22:14 +00:00
|
|
|
|
/* MSG - A protective MBR that displays an ASCII message located in the */
|
2020-02-19 18:48:24 +00:00
|
|
|
|
/* subsequent sectors. */
|
2020-02-19 14:22:14 +00:00
|
|
|
|
/* */
|
|
|
|
|
/* Copyright (c) 2019-2020 Pete Batard <pete@akeo.ie> */
|
|
|
|
|
/* */
|
|
|
|
|
/* This program is free software; you can redistribute it and/or modify it */
|
|
|
|
|
/* under the terms of the GNU General Public License as published by the Free */
|
|
|
|
|
/* Software Foundation, either version 3 of the License, or (at your option) */
|
|
|
|
|
/* any later version. */
|
|
|
|
|
/* */
|
|
|
|
|
/* This program is distributed in the hope that it will be useful, but WITHOUT */
|
|
|
|
|
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
|
|
|
|
|
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
|
|
|
|
|
/* more details. */
|
|
|
|
|
/* */
|
|
|
|
|
/* You should have received a copy of the GNU General Public License along with */
|
|
|
|
|
/* this program; if not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
/* */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* GNU Assembler Settings: */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
.intel_syntax noprefix
|
|
|
|
|
.code16
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* Constants: */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
MBR_ADDR = 0x7c00
|
|
|
|
|
MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.)
|
2020-04-13 16:05:33 +00:00
|
|
|
|
MSG_SECTOR = 0x22 # First sector of the message (must be after the GPT)
|
2020-02-19 14:22:14 +00:00
|
|
|
|
NB_SECTORS = 0x08 # Number of sectors to read
|
|
|
|
|
PT_MAX = 0x04 # Number of partition entries in the partition table
|
|
|
|
|
PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* Reference list of colours: */
|
|
|
|
|
/* You can escape these numeric values in your message text to set the colours *
|
|
|
|
|
/* for the background and foreground. For instance "\17HIGHLIGHT" will display */
|
|
|
|
|
/* light grey text (0x07) over a blue (0x01) background */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
BLACK = 0x00
|
|
|
|
|
BLUE = 0x01
|
|
|
|
|
GREEN = 0x02
|
|
|
|
|
CYAN = 0x03
|
|
|
|
|
RED = 0x04
|
|
|
|
|
MAGENTA = 0x05
|
|
|
|
|
BROWN = 0x06
|
|
|
|
|
LIGHT_GREY = 0x07
|
|
|
|
|
DARK_GREY = 0x08
|
|
|
|
|
LIGHT_BLUE = 0x09
|
|
|
|
|
LIGHT_GREEN = 0x0a
|
|
|
|
|
LIGHT_CYAN = 0x0b
|
|
|
|
|
LIGHT_RED = 0x0c
|
|
|
|
|
LIGHT_MAGENTA = 0x0d
|
|
|
|
|
LIGHT_YELLOW = 0x0e
|
|
|
|
|
WHITE = 0x0f
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* MBR: This section resides at 0x00007c00 and is exactly 512 bytes */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
.section main, "ax"
|
|
|
|
|
.globl mbr
|
|
|
|
|
mbr:
|
|
|
|
|
// xchg bx, bx # Uncomment to trigger Bochs magic breakpoint
|
|
|
|
|
inc cx
|
|
|
|
|
dec bx
|
|
|
|
|
inc bp
|
|
|
|
|
dec di
|
|
|
|
|
cld
|
|
|
|
|
xor ax, ax
|
|
|
|
|
cli # Disable interrupts when fiddling with the stack
|
|
|
|
|
mov ss, ax # First order of the day it to set up the stack
|
|
|
|
|
mov sp, MBR_ADDR # This places the stack right before the MBR copy in RAM
|
|
|
|
|
sti
|
|
|
|
|
mov ds, ax # MBR and stack reside in segment 0
|
|
|
|
|
mov bx, 0x0413 # McAfee thinks we are a virus if we use 413 directly...
|
|
|
|
|
mov ax,[bx]
|
|
|
|
|
sub ax, NB_SECTORS / 2 # Amount of RAM we need to read the message sectors
|
|
|
|
|
mov [bx],ax
|
|
|
|
|
shl ax, 6 # Convert to segment address
|
|
|
|
|
mov es, ax # Keep allocated RAM segment in ES
|
|
|
|
|
|
|
|
|
|
clear_display:
|
|
|
|
|
mov bh, 0x07
|
|
|
|
|
mov ax, 0x007f
|
|
|
|
|
int 0x10 # Set Video Mode to 640x480 16 color graphics (VGA)
|
|
|
|
|
xor bx, bx
|
|
|
|
|
xor cx, cx
|
|
|
|
|
mov dx, 0x184f
|
|
|
|
|
mov ax, 0x0600
|
|
|
|
|
int 0x10 # Clear screen
|
|
|
|
|
xor dx, dx
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
int 0x10 # Set cursor pos to top left
|
|
|
|
|
|
|
|
|
|
read_sectors: # Copy the next sectors into RAM
|
|
|
|
|
mov ah, 0x41
|
|
|
|
|
mov bx, 0x55aa
|
|
|
|
|
int 0x13
|
|
|
|
|
jb no_ext # failure to get ext
|
|
|
|
|
cmp bx, 0xaa55
|
|
|
|
|
jnz no_ext
|
|
|
|
|
test cx, 1 # is packet access supported?
|
|
|
|
|
jz no_ext
|
|
|
|
|
|
|
|
|
|
ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h:_Extended_Read_Sectors_From_Drive
|
|
|
|
|
xor eax, eax
|
|
|
|
|
push eax # bits 32-63 of sector address
|
2020-04-13 16:05:33 +00:00
|
|
|
|
push MSG_SECTOR # bits 0-31 of sector address
|
2020-02-19 14:22:14 +00:00
|
|
|
|
push es # destination segment
|
2020-04-13 16:05:33 +00:00
|
|
|
|
push eax # destination address (0)
|
2020-02-19 14:22:14 +00:00
|
|
|
|
push NB_SECTORS # number of sectors to be read
|
|
|
|
|
push 0x0010 # size of DAP struct
|
|
|
|
|
mov si, sp # DAP address (= stack)
|
|
|
|
|
mov ah, 0x42 # Extended Read Sectors From Drive
|
|
|
|
|
int 0x13
|
|
|
|
|
lahf
|
|
|
|
|
add sp,0x10
|
|
|
|
|
sahf
|
|
|
|
|
jmp check_error
|
|
|
|
|
|
|
|
|
|
no_ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive
|
|
|
|
|
mov ax, 0x0200 + NB_SECTORS
|
2020-04-13 16:05:33 +00:00
|
|
|
|
mov cx, (MSG_SECTOR + 1) # Sector address (starts at 1)
|
2020-02-19 14:22:14 +00:00
|
|
|
|
mov dx, 0x0080 # Drive ID
|
|
|
|
|
xor bx, bx # Destination address in ES
|
|
|
|
|
int 0x13
|
|
|
|
|
|
|
|
|
|
check_error:
|
|
|
|
|
mov bx, 0x0007 # Default text to light grey on black
|
|
|
|
|
jc display_err
|
|
|
|
|
|
|
|
|
|
display_msg: # Display the message
|
|
|
|
|
xor si, si
|
|
|
|
|
mov ax, es
|
|
|
|
|
mov ds, ax
|
|
|
|
|
call print_msg
|
2020-02-19 18:48:24 +00:00
|
|
|
|
jmp prompt_user
|
2020-02-19 14:22:14 +00:00
|
|
|
|
|
|
|
|
|
display_err: # Read error -> display shorter message from this MBR
|
|
|
|
|
mov si, offset err_msg
|
|
|
|
|
call print_msg
|
2020-02-19 18:48:24 +00:00
|
|
|
|
|
|
|
|
|
prompt_user:
|
|
|
|
|
xor ax, ax
|
|
|
|
|
mov ds, ax
|
|
|
|
|
mov si, offset prompt_string
|
|
|
|
|
call print_msg # Prompt the user
|
|
|
|
|
call flush_keyboard
|
|
|
|
|
|
|
|
|
|
wait_for_keyboard:
|
|
|
|
|
mov ah, 0x01
|
|
|
|
|
int 0x16 # KEYBOARD - CHECK BUFFER, DO NOT CLEAR
|
|
|
|
|
jnz reboot # Z is clear when characters are present in the buffer
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
int 0x16 # KEYBOARD - GET SHIFT STATUS
|
|
|
|
|
and al, 0x04 # AL = shift status bits
|
|
|
|
|
jz wait_for_keyboard
|
|
|
|
|
|
|
|
|
|
reboot: # Trigger a reboot
|
|
|
|
|
xor ax, ax
|
|
|
|
|
mov ds, ax
|
|
|
|
|
mov ax, 0x1234
|
|
|
|
|
mov [0x473], ax
|
|
|
|
|
jmp 0xffff:0000
|
2020-02-19 14:22:14 +00:00
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* Subroutines */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
|
2020-02-19 18:48:24 +00:00
|
|
|
|
flush_keyboard: # Flush the keyboard buffer
|
|
|
|
|
mov ah, 0x01
|
|
|
|
|
int 0x16 # KEYBOARD - CHECK BUFFER, DO NOT CLEAR
|
|
|
|
|
jz 0f # Z is set if no character in buffer
|
|
|
|
|
mov ah, 0x00
|
|
|
|
|
int 0x16 # KEYBOARD - READ CHAR FROM BUFFER
|
|
|
|
|
loop flush_keyboard
|
|
|
|
|
0: ret
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
2020-02-19 14:22:14 +00:00
|
|
|
|
print_msg: # Print NUL terminated string in DS:SI to console
|
|
|
|
|
lodsb
|
|
|
|
|
cmp al, 0x00 # NUL?
|
|
|
|
|
jz 4f
|
|
|
|
|
cmp al, 0x0d # Ignore CR
|
|
|
|
|
jz print_msg
|
|
|
|
|
cmp al, 0x0a # Handle LF
|
|
|
|
|
jnz 0f
|
|
|
|
|
push bx
|
|
|
|
|
mov ah, 0x03
|
|
|
|
|
int 0x10 # Get Cursor pos
|
|
|
|
|
inc dh # Move to next line
|
|
|
|
|
mov dl, 0 # Set column to 0
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
int 0x10 # Set Cursor pos
|
|
|
|
|
pop bx
|
|
|
|
|
jmp print_msg
|
|
|
|
|
0: cmp al, 0x5c # '\' Escape sequence to set FG/BG color
|
|
|
|
|
jnz 3f
|
|
|
|
|
mov cl, 2
|
|
|
|
|
1: lodsb
|
|
|
|
|
cmp al, 0x46
|
|
|
|
|
jg print_msg # Invalid escape sequence
|
|
|
|
|
sub al, 0x30 # '0'
|
|
|
|
|
cmp al, 0x09
|
|
|
|
|
jle 2f
|
|
|
|
|
sub al, 0x07
|
|
|
|
|
2: shl bl, 4
|
|
|
|
|
and al, 0x0f
|
|
|
|
|
or bl, al
|
|
|
|
|
dec cl
|
|
|
|
|
jnz 1b
|
|
|
|
|
jmp print_msg
|
|
|
|
|
3: mov cx, 0x0001
|
|
|
|
|
mov ah, 0x09
|
|
|
|
|
int 0x10
|
|
|
|
|
push bx
|
|
|
|
|
xor bx, bx
|
|
|
|
|
mov ah, 0x03
|
|
|
|
|
int 0x10
|
|
|
|
|
inc dl
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
int 0x10
|
|
|
|
|
pop bx
|
|
|
|
|
jmp print_msg
|
|
|
|
|
4: ret
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* Data section */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
err_msg:
|
2020-02-19 18:48:24 +00:00
|
|
|
|
.string "\r\n \\04*** ERROR: THIS MEDIA CANNOT BOOT IN LEGACY MODE ***\\07\r\n"
|
|
|
|
|
prompt_string:
|
|
|
|
|
.string "\r\n\r\n \\70Please remove this media and press any key to reboot\\07"
|
2020-02-19 14:22:14 +00:00
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
/* From offset 0x1b8, the MBR contains the partition table and signature data */
|
|
|
|
|
/********************************************************************************/
|
|
|
|
|
.org MBR_RESERVED
|
|
|
|
|
disk_signature:
|
|
|
|
|
.space 0x04
|
|
|
|
|
filler:
|
|
|
|
|
.space 0x02
|
|
|
|
|
partition_table:
|
|
|
|
|
.space PT_ENTRY_SIZE * PT_MAX
|
|
|
|
|
mbr_signature:
|
|
|
|
|
.word 0xAA55
|