首页
社区
课程
招聘
[原创]【逆向分析】MBR主引导扇区结构分析
发表于: 2020-3-28 15:48 7668

[原创]【逆向分析】MBR主引导扇区结构分析

2020-3-28 15:48
7668

MBR(Main Boot Record 主引导记录区)

可以通过打开物理设备获取MBR的数据,需要管理员权限运行。

在512字节的主引导到分区中,MBR占据446字节,是主引导程序的代码,另外64字节时DPT(Disk Partition Table硬盘分区表)

图片来自网络,方便理解


硬盘分区DPT分区表由四项组成,每想16字节,共64字节。每一项描述一个分区的基本信息。

这个分区(C盘)活动分区。即系统会从C盘启动

00H -- 该分区未使用

06H -- FAT16基本分区

0BH -- FAT32基本分区

05H -- 扩展分区

07H -- NTFS分区

0FH -- 扩展分区(LBA模式)(83H为Linux分区等)

00 70 47 06

开机-BIOS加电自检内存地址0x0FFF:0000-将硬盘的第一个扇区boot sector读取到0x0000:7c00处--检查 55 AA -- 跳转到7c00执行MBR代码--MBR将自身 0x200 长度的数据拷贝到0x0600处继续执行--判断是否一个活动分区--将活动分区的第一扇区复制到7c00,检查 55 AA--开始中7c00处代码。VBR 代码执行后会通过紧随其后的 IPL 数据在磁盘中找到 Bootmgr 代码数据,加载到 2000:0 执行 Bootmgr 实模式代码( startup.com )

Bootmgr 代码数据分为两个部分,会分为两个部分(startup.com 16位 和 bootmgr.exe 32位 保护模式)分别进行加载执行。两次加载地址分别为 0x20000(实模式 + 保护模式) 和 0x400000(保护模式)

startup.com用于解压、bootmgr.exe

具有NTFS解析功能,加载winload.exe

设置好调试环境后,附加到gdb调试,这时会在bios启动后的第一条指令处断下

BIOS会 把MBR加载到0x7c00;这时候所有的段都是0x0,

MBR运行在实模式下,地址都是16bit.


Int 13 获取磁盘参数(ah = 0x48) (详细结构可自行搜搜)

返回内容存放地址ds:si;  具体结构如下:

标志位flag

0   DMA boundary errors handled transparently 
1   C/H/S Information is valid.                     
2   Removable Drive.                            
3   Write with verify supported.                
4   Drive has change-line support:(Required if Drive is Removable!)  
5   Drive can be locked: (Required if Drive is Removable!) 
6    CHS Information set to maximum supported values; _not_ current media.         
15-7   Reserved (0).        


函数中的代码(byte_E表引导标志)

MBR病毒会篡改MBR结构,所以分析MBR的结构对MBR病毒可以快速处理。
将获取到的数据保存进程分析

在512字节的主引导到分区中,MBR占据446字节,是主引导程序的代码,另外64字节时DPT(Disk Partition Table硬盘分区表)

最后时分区的结束标志"55 AA",由他们构成硬盘主引导分区 
/*
MBR_struct: 0x0000 -- 0x1BE  (446字节) 主引导逻辑代码 + 硬盘签名
00000000:  33 C0 8E D0-BC 00 7C 8E-C0 8E D8 BE-00 7C BF 00  3???? |????? |?   
00000010:  06 B9 00 02-FC F3 A4 50-68 1C 06 CB-FB B9 04 00  ♠? ☻???Ph∟♠???♦   
00000020:  BD BE 07 80-7E 00 00 7C-0B 0F 85 0E-01 83 C5 10  ??•€~  |♂☼?♫☺??►  
00000030:  E2 F1 CD 18-88 56 00 55-C6 46 11 05-C6 46 10 00  ???↑?V U?F◄♣?F►   
00000040:  B4 41 BB AA-55 CD 13 5D-72 0F 81 FB-55 AA 75 09  ?A??U?‼]r☼??U?u○  
00000050:  F7 C1 01 00-74 03 FE 46-10 66 60 80-7E 10 00 74  ??☺ t♥?F►f`€~► t  
00000060:  26 66 68 00-00 00 00 66-FF 76 08 68-00 00 68 00  &fh    fv◘h  h   
00000070:  7C 68 01 00-68 10 00 B4-42 8A 56 00-8B F4 CD 13  |h☺ h► ?B?V ???‼  
00000080:  9F 83 C4 10-9E EB 14 B8-01 02 BB 00-7C 8A 56 00  ???►??¶?☺☻? |?V   
00000090:  8A 76 01 8A-4E 02 8A 6E-03 CD 13 66-61 73 1C FE  ?v☺?N☻?n♥?‼fas∟?  
000000A0:  4E 11 75 0C-80 7E 00 80-0F 84 8A 00-B2 80 EB 84  N◄u♀€~ €☼?? ?€??  
000000B0:  55 32 E4 8A-56 00 CD 13-5D EB 9E 81-3E FE 7D 55  U2??V ?‼]???>?}U  
000000C0:  AA 75 6E FF-76 00 E8 8D-00 75 17 FA-B0 D1 E6 64  ?unv ?? u↨????d  
000000D0:  E8 83 00 B0-DF E6 60 E8-7C 00 B0 FF-E6 64 E8 75  ?? ???`?| ??d?u  
000000E0:  00 FB B8 00-BB CD 1A 66-23 C0 75 3B-66 81 FB 54   ?? ??→f#?u;f??T  
000000F0:  43 50 41 75-32 81 F9 02-01 72 2C 66-68 07 BB 00  CPAu2??☻☺r,fh•?   
00000100:  00 66 68 00-02 00 00 66-68 08 00 00-00 66 53 66   fh ☻  fh◘   fSf  
00000110:  53 66 55 66-68 00 00 00-00 66 68 00-7C 00 00 66  SfUfh    fh |  f  
00000120:  61 68 00 00-07 CD 1A 5A-32 F6 EA 00-7C 00 00 CD  ah  •?→Z2?? |  ?  
00000130:  18 A0 B7 07-EB 08 A0 B6-07 EB 03 A0-B5 07 32 E4  ↑??•?◘??•?♥??•2?  
00000140:  05 00 07 8B-F0 AC 3C 00-74 09 BB 07-00 B4 0E CD  ♣ •???< t○?• ?♫?  
00000150:  10 EB F2 F4-EB FD 2B C9-E4 64 EB 00-24 02 E0 F8  ►?????+??d? $☻??  
00000160:  24 02 C3 49-6E 76 61 6C-69 64 20 70-61 72 74 69  $☻?Invalid parti  
00000170:  74 69 6F 6E-20 74 61 62-6C 65 00 45-72 72 6F 72  tion table Error  
00000180:  20 6C 6F 61-64 69 6E 67-20 6F 70 65-72 61 74 69   loading operati  
00000190:  6E 67 20 73-79 73 74 65-6D 00 4D 69-73 73 69 6E  ng system Missin  
000001A0:  67 20 6F 70-65 72 61 74-69 6E 67 20-73 79 73 74  g operating syst  
000001B0:  65 6D 00 00-00 63 7B 9A-00 00 00 00-00 00             em   c{?          

DPT_struct 0x01BE -- 0x01ff (64字节)
000001BE:  80 20 21 00 07 FE FF FF 00 08 00 00 00 70 47 06  --表分区C
000001CE:  00 FE FF FF 07 FE FF FF 00 78 47 06 00 78 38 01  --表分区E
000001DE:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000001EE:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000001FE:  55 AA      -           -           -                  
*/

图片来自网络,方便理解


硬盘分区DPT分区表由四项组成,每想16字节,共64字节。每一项描述一个分区的基本信息。

000001BE: 80 20 21 00 07 FE FF FF 00 08 00 00 00 70 47 06

第一字节
引导标志, 80H表示活动分区、00H表示非活动分区 
80

这个分区(C盘)活动分区。即系统会从C盘启动

第二至三字节
  分别表示起始磁头号(2)、扇区号(3低6位)、柱面号(3高2+4字节)
20 21 00
 CHS寻址方式
第五字节
  分区类型

00H -- 该分区未使用

06H -- FAT16基本分区

0BH -- FAT32基本分区

05H -- 扩展分区

07H -- NTFS分区

0FH -- 扩展分区(LBA模式)(83H为Linux分区等)

07 
NTFS分区
  第六至八字节
  本分区的结束磁头号(6)、扇区号(7低6位)、柱面号(7高2位+8字节)。   FE FF FF
 对应上面的2-3结束
第九至十二字节
逻辑其起始区号。(该分区之前引用了多少的扇区数)
  00 08 00 00
  起始扇区号
  第十三至十六字节
本分区的总扇区数。

00 70 47 06

扇区总数

//受到64字节大小的限制所以分区最多只能有四个。
typedef struct _MBR
{
     uint8_t bootCode[440];
     uint32_t diskSignature;                 //硬盘签名
     uint16_t reserved;
     PARTITION partitionTable[4];            //主分区,最多四个
     uint16_t sectorEndSignature;            //55 AA
} MBR, *PMBR;
//还有一些其他的字段会用到。

//分区表
typedef struct _PARTITION
{
     BYTE bootIndicator;            // +0 自举标志
     Word head;                   // +1  起始磁头号
     Word sector;                // 起始扇区号
     BYTE cylinder;                 // +3 起始柱面号CYL
     BYTE type;                     // +4 分区格式标志
     BYTE lastHead;                 // +5 终止磁头号
     BYTE lastSector;               // +6 终止扇区号
     BYTE lastCylinder;             // +7 终止柱面号CYL
     DWORD relativeSector;            // +8 本分区之前已用扇区数,可以理解为起始位置
     DWORD numberSectors;                // +0xC 本分区扇区总数
} PARTITION;    
                       
//VBR
typedef struct _NTFS_VOLUME_BOOT_RECORD
{
     BYTE jumpInstruction [3]; +0
     BYTE oemID [4];   
     BYTE dummy [4];  
     // BIOS Parameter Block
     struct NTFS_BPB
     {
          WORD bytesPerSector;//每扇区字节数
          BYTE sectorsPerCluster; //每簇扇区数,簇是ntfs文件系统的基本单位
          WORD reservedSectors; 
          BYTE fatCopies;  
          WORD rootDirEntries;
          WORD smallSectors;
          BYTE mediaDescriptor;//介质描述符 硬盘为0xf8
          WORD sectorsPerFAT;
          WORD sectorsPerTrack;//每磁道扇区数 ntfs不用
          WORD numberOfHeads;//磁头数 ntfs不用
          DWORD hiddenSectors; //隐藏扇区数 
          DWORD largeSectors;
          DWORD reserved;
          ULONGLONG totalSectors; //扇区总数
          ULONGLONG MFTLogicalClusterNumber;//$MFT起始簇号
          ULONGLONG MirrorLogicalClusterNumber;//$MFTMir起始簇号
          DWORD clustersPerMFTRecord;
          DWORD clustersPerindexRecord;
          ULONGLONG volumeSerial;//卷序列号
          DWORD checksum;//效验和
     } bpb ;
     BYTE bootStrapCode [426];
     WORD sectorEndSignature;
} NTFS_VOLUME_BOOT_RECORD 


000001BE: 80 20 21 00 07 FE FF FF 00 08 00 00 00 70 47 06
第一字节
引导标志, 80H表示活动分区、00H表示非活动分区 
80

这个分区(C盘)活动分区。即系统会从C盘启动

第二至三字节
  分别表示起始磁头号(2)、扇区号(3低6位)、柱面号(3高2+4字节)
20 21 00
 CHS寻址方式
第五字节
  分区类型

00H -- 该分区未使用

06H -- FAT16基本分区

0BH -- FAT32基本分区

05H -- 扩展分区

07H -- NTFS分区

0FH -- 扩展分区(LBA模式)(83H为Linux分区等)

07 
NTFS分区
  第六至八字节
  本分区的结束磁头号(6)、扇区号(7低6位)、柱面号(7高2位+8字节)。   FE FF FF
 对应上面的2-3结束
第九至十二字节
逻辑其起始区号。(该分区之前引用了多少的扇区数)
  00 08 00 00
  起始扇区号
  第十三至十六字节
本分区的总扇区数。

00 70 47 06

扇区总数

//受到64字节大小的限制所以分区最多只能有四个。
typedef struct _MBR
{
     uint8_t bootCode[440];
     uint32_t diskSignature;                 //硬盘签名
     uint16_t reserved;
     PARTITION partitionTable[4];            //主分区,最多四个
     uint16_t sectorEndSignature;            //55 AA
} MBR, *PMBR;
//还有一些其他的字段会用到。

//分区表
typedef struct _PARTITION
{
     BYTE bootIndicator;            // +0 自举标志
     Word head;                   // +1  起始磁头号
     Word sector;                // 起始扇区号
     BYTE cylinder;                 // +3 起始柱面号CYL
     BYTE type;                     // +4 分区格式标志
     BYTE lastHead;                 // +5 终止磁头号
     BYTE lastSector;               // +6 终止扇区号
     BYTE lastCylinder;             // +7 终止柱面号CYL
     DWORD relativeSector;            // +8 本分区之前已用扇区数,可以理解为起始位置
     DWORD numberSectors;                // +0xC 本分区扇区总数
} PARTITION;    
                       
//VBR
typedef struct _NTFS_VOLUME_BOOT_RECORD
{
     BYTE jumpInstruction [3]; +0
     BYTE oemID [4];   
     BYTE dummy [4];  
     // BIOS Parameter Block
     struct NTFS_BPB
     {
          WORD bytesPerSector;//每扇区字节数
          BYTE sectorsPerCluster; //每簇扇区数,簇是ntfs文件系统的基本单位
          WORD reservedSectors; 
          BYTE fatCopies;  
          WORD rootDirEntries;
          WORD smallSectors;
          BYTE mediaDescriptor;//介质描述符 硬盘为0xf8
          WORD sectorsPerFAT;
          WORD sectorsPerTrack;//每磁道扇区数 ntfs不用
          WORD numberOfHeads;//磁头数 ntfs不用
          DWORD hiddenSectors; //隐藏扇区数 
          DWORD largeSectors;
          DWORD reserved;
          ULONGLONG totalSectors; //扇区总数
          ULONGLONG MFTLogicalClusterNumber;//$MFT起始簇号
          ULONGLONG MirrorLogicalClusterNumber;//$MFTMir起始簇号
          DWORD clustersPerMFTRecord;
          DWORD clustersPerindexRecord;
          ULONGLONG volumeSerial;//卷序列号
          DWORD checksum;//效验和
     } bpb ;
     BYTE bootStrapCode [426];
     WORD sectorEndSignature;
} NTFS_VOLUME_BOOT_RECORD 


第一字节
引导标志, 80H表示活动分区、00H表示非活动分区 
80
第二至三字节
  分别表示起始磁头号(2)、扇区号(3低6位)、柱面号(3高2+4字节)
20 21 00
 CHS寻址方式
第五字节
  分区类型
07 
NTFS分区
  第六至八字节
 对应上面的2-3结束
第九至十二字节
逻辑其起始区号。(该分区之前引用了多少的扇区数)
  起始扇区号
本分区的总扇区数。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-3-28 15:51 被Cc28256编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (5)
雪    币: 4313
活跃值: (1534)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
2
感谢分享。
2020-3-28 15:52
1
雪    币: 1608
活跃值: (80)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
3
围观大佬,学习一下
2020-3-28 16:01
0
雪    币: 6664
活跃值: (957)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不错,不错,围观下
2020-3-28 22:06
0
雪    币: 2107
活跃值: (1429)
能力值: ( LV8,RANK:126 )
在线值:
发帖
回帖
粉丝
5
优秀
2020-4-1 09:55
0
雪    币: 1485
活跃值: (1135)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
可以写一个驱动级MBR保护.防修改
2020-4-12 21:43
0
游客
登录 | 注册 方可回帖
返回
//