Skip to content

Instantly share code, notes, and snippets.

@BigNerd95
Created February 1, 2018 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BigNerd95/29284ed351c9bcff678a361660228419 to your computer and use it in GitHub Desktop.
Save BigNerd95/29284ed351c9bcff678a361660228419 to your computer and use it in GitHub Desktop.
x86 MBR Bootloader
[BITS 16] ;modalita' a 16 bit
[ORG 0x600] ;indirizzo origine 0x600 (dopo la copia dell'mbr il codice sara' eseguito con indirizzi relativi a partire da 0x600)
; ********* Inizio codice **********
;questa prima parte di codice sara' eseguita in [0x7C00, 0x7DFF]
; ----- copia mbr da [0x7C00, 0x7DFF] a [0x600, 0x7FF] -----
XOR CX,CX ;azzera CX con uno XOR su se stesso (Counter 16bits)
MOV DS,CX ;copia CX in DS (Data Segment)
MOV ES,CX ;copia CX in ES (Extra Data Segment)
MOV SS,CX ;copia CX in SS (Stack Segment)
MOV SP,0x7C00 ;setta SP (Stack Pointer) a 0x7C00
MOV SI,SP ;copia SP (0x7C00) in SI (Source Index) (indirizzo sorgente da cui iniziare la copia)
MOV DI,0x600 ;setta DI (Destination Index) a 0x600 (indirizzo destinazione da cui iniziare la copia)
MOV CL,0x80 ;setta CL (Counter 8bits) a 0x80 (CX = dec: 128) (in CX risiede numero di volte da ripetere MOVSD) (CH e' azzerato)
CLD ;azzera il flag direzione (Clear Direction Flag 1bit nel registro dei flag) (CLD forward, STD backward)
REP ;ripete l'istruzione successiva fino a quando CX e' diverso da 0 (ad ogni giro decrementa CX di 1)
MOVSD ;sposta 4 byte (Move String Double Word) alla volta a partire da DS:SI (0x7C00) in ES:DI (0x600) e incrementa SI e DI (se il Direction Flag e' azzerato (CLD), se settato (STD) invece decrementa)
JMP WORD 0x0000:Main ;salta alla funzione Main nella nuova area di memoria (Main = 0x600 + offset)
; ----- fine copia mbr -----
;da qui il codice sara' eseguito in [0x600, 0x7FF]
; --- main ---
Main:
MOV SI, WelcomeS ;setta SI (Source Index) con l'indirizzo della stringa WelcomeS (titolo dell'mbr)
CALL PrintS ;richiama la funzione PrintS (stampa su schermo)
Control: ;controllo delle partizioni avviabili
MOV SI, [Padd] ;setta SI con il contenuto di Padd (Partition address)
CMP BYTE [SI],0x80 ;controlla se il contenuto dell'indirizzo in SI (primo byte della tabella delle partizioni) e' 0x80
JNE Control2 ;se non e' vero prosegue
CALL ShowBP ;se vero la partizione e' avviabile e chiama ShowBP (Show Boot Partition)
Control2:
CMP BYTE [Pnum],0x04 ;controlla se Pnum e' 0x04
JE Control3 ;se vero (tutte le partizioni sono state controllate) salta a Control3
INC BYTE [Pnum] ;incrementa Pnum per tenere traccia di quando ha controllato tutte le partizioni
ADD WORD [Padd], 0x10 ;aggiunge 16 a Padd per puntare alla prossima partizione nella tabella
JMP Control ;riavvia il ciclo di controllo
Control3:
CMP BYTE [CountP],0x00 ;se CountP e' a 0, nessuna delle 4 partizioni e' avviabile
JNE SelectP ;se non e' 0 salta a SelectP
INT 0x18 ;altrimenti passa al prossimo dispositivo di boot
SelectP: ;input partizione da avviare
MOV SI, InstrS ;stampa Select volume
CALL PrintS
SelectP2: ;controlla il tasto premuto
XOR AH, AH ;azzera AH (per int 16h)
INT 0x16 ;attende input da tastiera
MOV AH, AL ;copia l'ascii in AH
SUB AH, 0x30 ;sottrae dall'ascii 0x30 per trasformarlo in numero
CMP AH, 0x4 ;confronta AH con 4
JG SelectP2 ;se e' meggiore di 4 ripete l'input
CMP AH, 0x1 ;confronta AH con 1
JL SelectP2 ;se e' minore di 1 ripete l'input
MOV WORD SI, 0x7BE ;altrimenti mette in SI l'indirizzo della prima partizione della tabella delle partizioni
DEC BYTE AH ;sottrae 1 ad AH
XOR DX,DX
MOV DL, AH ;mette AH in DL (per sicurezza ci vorrebbe uno XOR DX prima di assegnare AH a DL)
IMUL CX, DX, 0x10 ;moltiplica 16 per DX volte (0-3) e mette il risultato in CX
ADD WORD SI, CX ;aggiunge CX ad SI (calcolato l'indirizzo della partizione selezionata in base al numero premuto)
CMP BYTE [SI], 0x80 ;controlla se il primo byte della partizione selezionata e' uguale a 0x80
JNE SelectP2 ;se non e' uguale torna all'input
PUSH SI
CALL PrintCh ;altrimenti la partizione e' avviabile, stampa a video il numero premuto e passa al bootstrap
MOV SI, LoadS ;stampa la scritta Loading
CALL PrintS
POP BP
PUSH 0x0000
PUSH 0x0000
PUSH DWORD [BP+0x08]
PUSH 0x0000
PUSH 0x7C00
PUSH 0x0001
PUSH 0x0010
MOV AH,0x42
MOV DL,[BP+0x00]
MOV SI,SP
INT 0x13
JMP WORD 0x0000:0x7C00
; --- main --- end
; --- stampa il numero corrispondente alla partizione avviabile e copia il vbr in ram ---
ShowBP:
INC BYTE [CountP] ;incrementa CountP per segnalare che esiste almeno una partizione avviabile
MOV AL,[Pnum] ;mette il contenuto di Pnum (Partition number) in AL
ADD BYTE AL,0x30 ;trasforma da intero in ascii
CALL PrintCh ;stampa il carattere a video
MOV AL,0x20 ;stampa spazio
CALL PrintCh ;stampa il carattere a video
MOV SI, PartLable
MOV DL, [Pnum]
DEC DL
IMUL CX, DX, 0x20
ADD SI, CX
CALL PrintS
MOV AL,0xD
CALL PrintCh
MOV AL,0xA
CALL PrintCh
RET ;prosegue la funzione principale di controllo
; --- stampa una stringa a video ---
PrintS:
nxtCh: ;ciclo caratteri
LODSB ;sposta il contenuto dell'indirizzo di si in al (MOV AL,[SI]) e incrementa SI (Direction Flag a 0: CLD impostato ad inizio programma)
TEST AL,AL ;conrolla se al e' azzerato
JZ exitF ;se vero (zero) esce
CALL PrintCh ;altrimenti richiama la stampa a video del carattere
JMP nxtCh ;riavvia il ciclo di stampa
; --- stampa un carattere a video ---
PrintCh:
MOV AH,0x0E ;imposta i parametri per la stampa a video
INT 0x10 ;stampa a video il contenuto di al
exitF:
RET
; ********** Fine codice **********
; ********** Inizio variabili **********
CountP DB 0x00
Pnum DB 0x01
Padd DW StartPT ;org 0x600 --> 0x7BE, org 0x7C00 --> 0x7DBE (old: Padd DW 0x7BE)
WelcomeS DB 'OrangeSec MBR',13,10,0
InstrS DB 13,10,'Select volume: ',0
LoadS DB 13,10,'Loading...',0
; ********** Fine variabili **********
PartLable:
DB 'Windows XP'
TIMES 22 DB 0
;TIMES PartLable + 32 - ($ - $$) DB 0
DB 'Arch Linux'
TIMES 22 DB 0
;TIMES PartLable + 32 + 32 - ($ - $$) DB 0
;DB 'ccccccccccccccc',0
;TIMES PartLable + 32 + 32 + 32 - ($ - $$) DB 0
;DB 'ddddddddddddddd',0
TIMES 444 - ($ - $$) DB 0
DW PartLable - 0x600
; ********** Inizio offset tra codice e tabella partizioni **********
TIMES 446 - ($ - $$) DB 0 ;offset dinamico tra codice e tabella partizioni (deve sempre iniziare al 446esimo byte (0x1BE) dell'mbr)
; ********** Fine offset tra codice e tabella partizioni **********
; ********* Inizio tabella delle partizioni ************
StartPT:
; * partizione 1 *
DB 0x80,0xFE,0xFF,0xFF,0x0B,0xFE,0xFF,0xFF,0x02,0x00,0x00,0x00,0x00,0x18,0x1E,0x00 ;DB 0x80
TIMES 462 - ($ - $$) DB 0 ;offset dinamico in caso la prima partizione sia nulla (446 + 16 = 462)
; * partizione 2 *
DB 0x80,0xFE,0xFF,0xFF,0x0B,0xFE,0xFF,0xFF,0x03,0x18,0x1E,0x00,0xFD,0x17,0x1E,0x00 ;DB 0x80
TIMES 478 - ($ - $$) DB 0 ;offset dinamico in caso la seconda partizione sia nulla (446 + 32 = 478)
; * partizione 3 *
;DB 0x80
TIMES 494 - ($ - $$) DB 0 ;offset dinamico in caso la seconda partizione sia nulla (446 + 48 = 494)
;partizione 4
;DB 0x80
TIMES 510 - ($ - $$) DB 0 ;offset dinamico in caso la seconda partizione sia nulla (446 + 64 = 510)
; ********** Fine tabella delle partizioni ************
; ********** Inizio firma **********
DW 0xAA55 ;mbr magic number
; ********** Fine firma **********
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment