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 fv◘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 ?unv ?? 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
开机-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
设置好调试环境后,附加到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 |
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天前 被驱动骑士编辑 ,原因: