【逆向分析】MBR主引导扇区结构分析
2020-04-03 04:43:36 Author: bbs.pediy.com(查看原文) 阅读量:209 收藏

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

5天前 585

前言

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

MBR病毒会篡改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 

windows的启动流程

开机-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

winload.exe 用来加载系统内核,最终运行  ntoskrnl


动态调试MBR

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

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

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

IDA调试在0x7c00设置断点,调整段为16bit. 


//扩展int 13读硬盘
//在堆栈上构建调用int 13扩展读所需要的参数块,在这里将活动分区的VBR拷贝到0x7c00偏移处。
//如果从硬盘读取VBR数据成功,则cf=0,ah=0
 struct DiskAddressPacket 
{
   BYTE PacketSize;//数据包尺寸(16字节) 
   BYTE Reserved;//==0 
   WORD BlockCount;//要传输的数据块个数(以扇区为单位) 
   DWORD BufferAddr;//传输缓冲地址(segment:offset) 
   QWORD BlockNum;//磁盘起始绝对块地址 
}; 


跳转的位置设置一些数值,返回一个地址7c66执行。


如果执行过程判断了一些错误会跳转执行int 10中断,停止执行 


没有错误则继续执行 

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

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

 offset range
 size description
 00h..01h 2 bytes buffer大小(一般是0x1a)
 02h..03h 2 bytes 

标志位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).        

 04h..07h
 4 bytes 柱面数
 08h..0Bh 4 bytes 磁头数
 0Ch..0Fh 4 bytes 每个磁道的扇区数
 10h..17h 8 bytes 绝对扇区数,
 18h..19h 2 bytes

 每个扇区所占字节,通常是0x200



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

int 0x13 的 0x42 号功能从磁盘读 n 个 sectors 到 buffer 中。 

把IPL的数据全部都从硬盘读到内存后,调用 Int 1a中断, ah为0xbb,检测是否支持TCG 

跳转到IPL执行 

IPL的扇区复制完毕后,接着便是解析NTFS文件系统 找到bootmgr文件。 

再往下接比较复杂了,暂时分析到这里就已经能够非常快速的分析MBR病毒查询逻辑。这个是去年分析的,现在已经有点记不清所有的点了,所以拿出来记一下,方便回阅。

2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!

最后于 5天前 被驱动骑士编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-258439.htm
如有侵权请联系:admin#unsafe.sh