Created
February 1, 2018 18:19
-
-
Save BigNerd95/29284ed351c9bcff678a361660228419 to your computer and use it in GitHub Desktop.
x86 MBR Bootloader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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