1. 程式人生 > >主引導扇區解析

主引導扇區解析

    最近排查一個USB相關的故障,由於資訊保安就不多說工作上的事情了,順路學習了MBR的相關知識,在網上找了一些資料,現在把學習心得寫下來,拋磚引玉。感謝無數前輩的分享精神。

    我的U盤插入linux後被識別成了sdb4,我當時很納悶,為什麼是4,沒有sdb1 sdb2 sdb3,直接就sdb4 了。linux是從哪裡顯示的這個4.
 
    是這樣的,sdb,這個b是有linux 動態分配的,Linux那些事兒,我是SCSI硬碟中有精彩的講解。在Kernel程式碼中時sd_probe函式做的事情。linux對於scsi裝置,支援sda~sdzzz,因為英文字母有26個,所以支援這麼多SCSI裝置

  1. #define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26)
    因為我的板子上,有自帶的sda SCSI盤,所以我插入的U盤被識別成了sdb。為啥是sdb,LINUX是怎樣防止不同的SCSI賦予同一個disk_name 呢,這就是IDR做的事情。IDR integer ID management,是管理小整數分配的。不太瞭解的筒子請摸我 and 再摸我

    剩下的是,linux 為什麼把我的U盤識別成了sdb4。這個分割槽的資訊記錄在了U盤的mbr,這就引出了我們本文的主角 MBR。

    MBR,Master Boot Record的縮寫,可以成為主引導記錄或者主引導扇區。計算機開機之後,訪問磁碟必須先訪問這個MBR,獲取到這個磁碟的相關資訊,比如這個磁碟有幾個分割槽啊,每個分割槽從哪開始,到哪結束,每個分割槽都是啥檔案系統等等資訊。


    MBR是一個扇區,在磁碟的位置是(柱面,磁頭,扇區)=(0,0,1)。MBR是怎麼組織的呢?一個扇區512個位元組(不一定,apple有文章表示,扇區大小不一定是512)。


    其中從0x01BE到0x01FD這六十四個位元組表示的是4個主分割槽的資訊。每個主分割槽16個位元組描述,這16反個位元組的含義是:


     其中扇區最後兩個位元組是0x55 0xaa,這也可以驗證是否是標準的MBR。下面程式碼中有。     對了,有個工具winhex,可以看磁碟的資訊,我今天在我的Window 7上看了,發現MBR資訊完全不對,按照維基百科提到,分割槽啟用狀態時0x80,非啟用狀態時0x00,結果在winhex上顯示的是0xDE,搞得哥很難受。也許是我沒學會正確的使用方法。感興趣的可以搜搜這個工具。其實我們完全可以自己解析MBR的格式。

   我將我的U盤的第一個扇區的內容儲存了下來,寫了個程式分析這個扇區(MBR)的內容。本程式主要參考了網上的資源,風格不太一致,大家也可以看得出來。上面的表格是wiki百科的內容,光榮屬於前輩,我只是整理了下自己的學習心得。


  1. #include<stdio.h>
  2. #include <unistd.h>
  3. #include<sys/types.h>
  4. #include<sys/stat.h>
  5. #include<fcntl.h>
  6. #define PT_OFFSET 446
  7. #define PT_LEN 16
  8. #define PT_N 4
  9. #define CHECK_POS 510 
  10. //Cylinder-Head-Sectoradderess type
  11. typedef struct
  12. {
  13.         unsigned char head:8;
  14.         unsigned char sector:6;
  15.         unsigned short cylinder:10;
  16. } CHS;
  17. void printPT(char *buf);
  18. int main(int argc, char *argv[])
  19. {
  20.         int fd = open(argv[1], O_RDONLY);
  21.         if(fd < 0)
  22.         {
  23.                 perror("open");
  24.                 exit(1);
  25.         }
  26.         if(lseek(fd,CHECK_POS,SEEK_SET) == -1)
  27.         {
  28.                 fprintf(stderr,"lseek to CHECK_POS err %m\n");
  29.                 close(fd);
  30.                 return -1;
  31.         } 
  32.         unsigned char checkbuf[16] = {0};
  33.         if(read(fd,checkbuf,2) != 2)
  34.         {
  35.                 fprintf(stderr,"read check info failed %m\n");
  36.                 close(fd);
  37.                 return -2;
  38.         }
  39.         if(checkbuf[0] != 0x55 || checkbuf[1] != 0xaa)
  40.         {
  41.                 fprintf(stderr, "not valid mbr format\n");
  42.                 close(fd);
  43.                 return -3;
  44.         }
  45.         if(lseek(fd, PT_OFFSET, SEEK_SET) ==-1)
  46.         {
  47.                 close(fd);
  48.                 perror("lseek");
  49.                 exit(1);
  50.         }
  51.         char buf[PT_LEN];
  52.         int i;
  53.         for(= 0; i < PT_N; i++)
  54.         {
  55.                 bzero(buf, PT_LEN);
  56.                 if(read(fd, buf, PT_LEN) !=PT_LEN)
  57.                 {
  58.                         printf("can't getfull partition table[%d]\n", i);
  59.                         close(fd);
  60.                         exit(1);
  61.                 }
  62.                 if(buf[1] || buf[2] || buf[3])
  63.                         printPT(buf);
  64.         }
  65.         close(fd);
  66.         return 0;
  67. }
  68. void printPT(char *buf)
  69. {
  70.         switch((unsigned char)buf[0])
  71.         {
  72.                 case 0x80:
  73.                         printf("bootable\n");
  74.                         break;
  75.                 case 0x00:
  76.                         printf("non-bootable\n");
  77.                         break;
  78.                 default:
  79.                         printf("invalid\n");
  80.         }
  81.         CHS chs;
  82.         memcpy(&chs, buf+1, 3); 
  83.         printf("from CHSAddr: \n");
  84.         printf("%12s%12s%12s\n","head","sector","cylinder");
  85.         printf("%12d%12d%12d\n",chs.head,chs.sector,chs.cylinder);
  86.         memcpy(&chs, buf+5, 3);
  87.         printf("to CHSAddr: \n");
  88.         printf("%12s%12s%12s\n","head","sector","cylinder");
  89.         printf("%12d%12d%12d\n",chs.head,chs.sector,chs.cylinder);
  90.         printf("partition type:%d\n",(unsigned char)buf[4]);
  91.         printf("LENGTH:%d(sectors)\n\n", *(unsigned int*)&buf[12]);
  92. }
    
  1. dd if=/dev/sdb of=mbr bs=512 count=1
首先看一下我的U盤的MBR的廬山真面目:

  1. [[email protected] mbr]# cat mbr |od -tx1 -Ax
  2. 000000 fa 31 c0 8e d8 8e c0 8e d0 bc 00 7c fb fc 89 e6
  3. 000010 bf 00 06 b9 00 01 f3 a5 ea dc 06 00 00 10 00 01
  4. 000020 00 00 7c 00 00 00 00 00 00 00 00 00 00 80 3f 00
  5. 000030 ff 00 cd 03 1e 0e 1f 3a 16 10 00 74 06 1f ea 36
  6. 000040 e7 00 f0 3d fb 54 75 05 8c d8 fb eb 1d 80 fc 08
  7. 000050 75 1b e8 81 00 8a 36 13 00 fe ce 8b 0e 15 00 86
  8. 000060 cd c0 e1 06 0a 0e 11 00 31 c0 f8 eb 65 80 fc 02
  9. 000070 72 cb 80 fc 04 77 c6 60 80 cc 40 50 be 00 00 c7
  10. 000080 04 10 00 30 e4 89 44 02 89 5c 04 8c 44 06 66 31
  11. 000090 c0 66 89 44 0c 88 f0 f6 26 11 00 88 cf 88 eb c0
  12. 0000a0 ef 06 81 e1 3f 00 01 c8 48 89 c7 a1 13 00 f7 26
  13. 0000b0 11 00 f7 e3 01 f8 81 d2 00 00 89 44 08 89 54 0a
  14. 0000c0 58 30 c0 8a 16 10 00 e8 0c 00 88 26 03 00 61 a1
  15. 0000d0 02 00 1f ca 02 00 9c ff 1e 22 00 c3 80 fa 8f 7f
  16. 0000e0 04 88 16 2d 06 be 87 07 e8 8d 00 be be 07 31 c0
  17. 0000f0 b9 04 00 f6 04 80 74 03 40 89 f5 81 c6 10 00 e2
  18. 000100 f2 48 74 02 cd 18 bf 05 00 be 1d 06 c7 44 02 01
  19. 000110 00 66 8b 46 08 66 89 44 08 b8 00 42 8a 16 2d 06
  20. 000120 cd 13 73 0d 4f 74 49 30 e4 8a 16 2d 06 cd 13 eb
  21. 000130 d8 a1 fe 7d 3d 55 aa 75 37 fa 66 a1 4c 00 66 a3
  22. 000140 3f 06 be 13 04 8b 04 48 89 04 c1 e0 06 8e c0 31
  23. 000150 ff be 1d 06 b9 60 00 fc f3 a5 c7 06 4c 00 17 00
  24. 000160 a3 4e 00 fb 8a 16 2d 06 89 ee fa ea 00 7c 00 00
  25. 000170 be aa 07 e8 02 00 eb fe ac 20 c0 74 09 b4 0e bb
  26. 000180 07 00 cd 10 eb f2 c3 53 74 61 72 74 20 62 6f 6f
  27. 000190 74 69 6e 67 20 66 72 6f 6d 20 55 53 42 20 64 65
  28. 0001a0 76 69 63 65 2e 2e 2e 0d 0a 00 42 6f 6f 74 20 66
  29. 0001b0 61 69 6c 65 64 00 00 00 ea eb d4 ca 00 00 00 00
  30. 0001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  31. *
  32. 0001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01
  33. 0001f0 01 00 0b fe ff cc 3f 00 00 00 81 b9 ee 00 55 aa
用寫的程式可以分析出藍色部分,分割槽的結果。可以看到各分割槽的filetype,起始位置,結束位置等資訊。

執行結果為:

相關推薦

引導解析

    最近排查一個USB相關的故障,由於資訊保安就不多說工作上的事情了,順路學習了MBR的相關知識,在網上找了一些資料,現在把學習心得寫下來,拋磚引玉。感謝無數前輩的分享精神。     我的U盤插入linux後被識別成了sdb4,我當時很納悶,為什麼是4,沒有sdb1 sdb2 sdb3,直接就sdb4

分割槽,擴充套件分割槽,邏輯分割槽,活動分割槽,系統分割槽,啟動分割槽。。。。。。。。。 引導,MBR,bootloader。。。。。。。。。。

主分割槽,擴充套件分割槽,邏輯分割槽,活動分割槽,系統分割槽,啟動分割槽。。。。。。。。。 主引導扇區,MBR,bootloader。。。。。。。。。。 各種概念,你都清楚什麼意思嗎? 花了一天的時間終於研究清楚了,網上好多帖子的解釋都是錯的,或者沒有深入到本質,都是什麼C盤啊,D盤啊,都被wind

編寫引導

在看《x86組合語言從真實模式到保護模式》這本書時,因為我是用fedora進行學習的,所以書上的很多工具是用不了的,只能用另外的方法來建立硬碟了: nasm mbr.asmqemu-img create -f qcow disk.img 128Mdd if=mbr of

引導(MBR),分割槽表(DPT)及活動分割槽(DBR)

主引導扇區:硬碟的0柱面、0磁頭、1扇區(也叫主引導記錄MBR),大小為512Byte。 分割槽表(DPT):位於主引導分割槽,從偏移01BEH開始到偏移01FDH結束的64位元組。 活動分割槽DBR:DBR(DOS BOOT RECORD,原意為DOS引導記錄),位於柱面0

修復引導(windows、linux)

在罈子裡找到一篇關於grub和mbr工作原理的文章,以前一直都是一頭霧水,今天轉這文章學習下。。哈。。 能正常工作的grub應該包括一下檔案:stage1、stage2、*stage1_5、menu.lst。 其中stage1要被安裝(也就是寫入)某個硬碟的主引導記錄,或者某個活動分割槽(這個分割槽要用fd

引導(Master Boot Record:MBR)

主引導記錄(Master Boot Record,縮寫:MBR),又叫做主引導扇區,是計算機開機後訪問硬碟時所必須要讀取的首個扇區,它在硬碟上的三維地址為(柱面,磁頭,扇區)=(0,0,1)。在深入討論主引導扇區內部結構的時候,有時也將其開頭的446位元組內容特指為“

使用引導維護工具BOOTICE編輯系統啟動列表BCD文件

mar log down think button 內存條 系列 dsm sso 使用引導扇區維護工具BOOTICE編輯系統啟動列表BCD文件系列文章:筆記本電腦提速之加裝內存條、SSD固態硬盤、光驅位換SSD固態硬盤筆記本ThinkPad E430c加裝內存和SSD固態

讀取硬碟的MBR引導(Windows各系統通用)

原文: ----------------------------------------------------------------------------------------------------------- 知識普及: 硬碟的引導扇區位於 0 磁軌

作業系統1——引導的理解

在作業系統這個方面,我記得自己經常聽到主引導記錄這個名詞,但是對於它的理解並不深,只知道它在系統載入的時候很重要。現在我想自己寫一個作業系統,但是想到第一步該怎麼做呢?書上說是用匯編寫載入程式。那麼這個載入程式是什麼呢?它正是我們經常所說的主引導記錄,或者說,它儲存在引導扇

RedHat6.5引導過程與MBR修復

tro 6.5 VM 執行命令 內存 目錄 執行 進入 命令 RedHat6.5引導過程與MBR扇區修復 實驗目標:1了解Linux系統的引導過程2 學會解決常見的啟動類故障**實驗環境:1:VMware虛擬機2:RedHat6.5系統實驗原理:1:Linux系統引導過程分

內存緩沖解析

sys com 錯誤信息 set while 通過 數據 mode bsp 一.緩沖區顧名思義即為:內存中開辟的一片緩沖區域  按類型分為:全緩沖,行緩沖,不帶緩沖  可以通過標準庫函數setvbuf(_Inout_ FILE * _File, _Inout_updates

分配粒度和內存頁面大小(x86處理器平臺的分配粒度是64K,內存頁是4K,所以section都是0x1000對齊,硬盤大小是512字節,所以PE文件默認文件對齊是0x200)

tail details lpad 硬件 512字節 地址 系統 pad 原因 分配粒度和內存頁面大小x86處理器平臺的分配粒度是64K,32位CPU的內存頁面大小是4K,64位是8K,保留內存地址空間總是要和分配粒度對齊。一個分配粒度裏包含16個內存頁面。這是個概念,具體

使用HDTune規避硬盤上損壞的

需要 跳過 工具 分區 而是 ... hspa 如何使用 這一 如何使用HDTune掃描磁盤上的錯誤在網上已經有很多帖子了,但掃描到之後如何用HDTune來規避硬盤上損壞的扇區呢? HDTune並不能直接規避,而是需要重新劃分磁盤的卷。HDTune一行有50個小方格,一格代

[Win32] 直接讀寫磁盤(磁盤絕對讀寫)

ref return rac cpp sig i/o phy 類型 表示 ??本博文由CSDN博主zuishikonghuan所作,版權歸zuishikonghuan全部。轉載請註明出處:http://blog.csdn.net/zuishikonghuan/artic

Linux修復MBR故障

ext vml dir 命令 AMF 之前 一個 備份 ges 給虛擬機增加一塊硬盤,用於備份mbr的信息 fdisk -l 查看硬盤系統是否認識 fdisk /dev/sdb 進行分區 fdisk -l 查看分區是否出來 mkfs -t ext4 /dev/sbd1 進行

磁盤結構中 簇、塊、等概念

磁頭 itl htm happy 磁道 操作 window 是什麽 inux 柱面(cylinder) 磁頭(head) 圓盤(platter) 扇面 磁道(track) 扇區(sector) 簇、塊 扇區是磁盤最小的物理存儲單元,但由於操作系統無法對數目眾多的扇區進行

硬盤、柱面的基本知識;

同心圓 ref lin png 一段 區域 成了 存儲 style 轉自:http://www.intohard.com/article-436-1.html 概述:本文介紹硬盤的扇區基本知識, 同時對邏輯扇區和物理扇區的概念做出說明 盤片上涉及的基本概念 整個硬盤上一般有

Linux 入門記錄:六、Linux 硬件相關概念(硬盤、磁盤、磁道、柱面、磁頭、、分、MBR、GPT)

存儲信息 鋁合金 性能 升級 image 新的 part 分享 即使 一、硬盤 硬盤的功能相當簡單但很重要,它負責記錄系統所需要的各種數據。硬盤記錄數據有兩個方面,一個是硬件方面的存儲原理和結構,另外一方面則是軟件方面的數據和文件系統。硬盤的主要行為就是數據的存放和取出。

與磁盤第一塊有關的:分與開機流程

font bsp 整合 inux 不同 對待 兩個 bytes 能夠 引入: 在linux系統中,每個設備都被當成一個文件來對待。 幾乎所有硬件設備都在/dev這個目錄下。 需要掌握的是磁盤的設備文件名:IDE接口的為/dev/hd[a-d],SATA的為/dev/

MBR引導記錄

編號 工具 elf 開始 開頭 sin address 規劃 org LBA的尋址方式可以讓我們支持2TB,這是因為分區相對起始扇區號(分區項08-11個字節)和分區最大扇區數(分區項12-15個字節)的位數都是32bit.也就是0xFFFFFFFF*512/1024