吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15164|回复: 22
收起左侧

[PC样本分析] MBR学习笔记

  [复制链接]
JoyChou 发表于 2013-9-30 18:58
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 JoyChou 于 2013-9-30 19:04 编辑

//Author: JoyChou
//Date: 2013年9月30日 19:04:55
//Blog: http://www.cnblogs.com/Joy7/

关于MBR介绍,网上已经有很多了
这里分享下自己xp的mbr分析笔记

什么是MBR?
也叫主引导记录(Master Boot Record,简称MBR) MBR位于整个硬盘的0柱面0磁头1扇区的位置处
主引导记录(Master Boot Record,缩写:MBR),又叫做主引导扇区Master Boot Sector
它在硬盘上的三维地址为(柱面,磁头,扇区)=(0,0,1)

MBR组成
MBR可以分为五个部分(512字节)
1、引导程序(440字节)
2、Windows磁盘签名(4个字节)
3、保留位(2个字节)
4、硬盘分区表(Disk Partition Table 简称DPT) 64个字节
5、结束标志 (2个字节)

也可以分成3部分(1.引导程序  2.分区表  3.结束标志)

分区表
clipboard.png
一个分区表项为0x10大小字节,所以存在4个分区表项
当然,也就只能有四个主分区或者3个主分区+1个扩展分区,但是平时看到有的电脑分成CDEFGH等盘,这是为什么呢?
因为此时,一般只有C盘是主分区,DEFGH盘一般是扩展分区细分出来的逻辑分区。也就是说扩展分区只能有一个,然后可以再细分为多个逻辑分区。

扩展分区也是主分区的一种,但它与主分区的不同在于理论上可以划分为无数个逻辑分区。


调试之前先要了解windows系统启动过程
1、开机
2、BIOS加点自检(Power On Self Test,即POST),此时电源稳定后,CPU从内存地址0fff:0000处开始执行
3、将硬盘第一个扇区(0磁头0柱面1扇区)读取内存地址0000:7c00处
4、检测(WORD)0000:7dfe是否等于0xaa55,若不等于则转去尝试其他启动介质,如果没有其他启动介质则显示"No ROM BASIC"
5、跳转到0000:7c00处执行MBR中的程序

6、MBR首先将自己复制到0000:0600处,然后继续执行
7、在主分区表中搜索标志为活动的分区。如果发现没有活动分区或有不止一个活动分区,则显示“Invalid partiton table
8、将活动分区的第一个扇区读入内存地址0000:7c00处
9、检测(WORD)000:7dfe是否等于0xaa55,若不等于则显示"Miss Operating System",然后停止,或尝试软盘启动
10、跳转到0000:7c00处继续执行DBR
11、启动系统

以上步骤中2,3,4,5步由BIOS的引导程序完成,6、7、8、9、10步由MBR中的引导程序完成。
知道了过程,调试就简单多了,所以过程是分析一个很关键的步骤。

关于MBR的调试看willJ大大的文章吧~

最好先用IDA动态跟下自己的mbr,接着静态分析(每个系统的mbr都不会是一模一样的)。

IDA静态分析代码
[AppleScript] 纯文本查看 复制代码
seg000:7C00 seg000          segment byte public 'CODE' use16[/size]
seg000:7C00                 assume cs:seg000
seg000:7C00                 ;org 7C00h
seg000:7C00                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:7C00                 xor     ax, ax          ; ax = 0
seg000:7C02                 mov     ss, ax          ; ss = 0
seg000:7C04                 mov     sp, 7C00h       ; sp = 0x7c00
seg000:7C07                 sti                     ; 开起段中断
seg000:7C08                 push    ax
seg000:7C09                 pop     es              ; es = 0
seg000:7C0A                 push    ax
seg000:7C0B                 pop     ds              ; ds = 0
seg000:7C0C                 cld                     ; 关闭段中断
seg000:7C0D                 push    ax
seg000:7C0E                 mov     si, 7C00h
seg000:7C11                 mov     di, 600h
seg000:7C14                 mov     cx, 200h        ; 循环次数,512次,也就是mbr的大小
seg000:7C17                 rep movsb               ; rep movsb将ds:si拷贝到es:di处,长度为cx
seg000:7C17                                         ; 即将mbr从0x7c00拷贝到0x600处
seg000:7C19                 mov     di, 61Eh
seg000:7C1C                 push    di
seg000:7C1D                 retf                    ; jmp到0x61E
seg000:7C1D                                         ; 也就是继续执行下一条指令(可以用IDA动态调试看)
seg000:7C1E ; ---------------------------------------------------------------------------
seg000:7C1E                 xor     bx, bx          ; 这里本来是7c1E,因为静态调试,就把它当成61E
seg000:7C20                 xor     dx, dx
seg000:7C22                 mov     si, 7BEh        ; 0x600+0x1BE  偏移0x1BE为分区表起始位置
seg000:7C25                 mov     cl, 4           ; 4个分区表项
seg000:7C27
seg000:7C27 loc_7C27:                               ; CODE XREF: seg000:7C32j
seg000:7C27                 test    byte ptr [si], 80h ; 判断是否是活动分区,0x80为活动分区,由于[si]是2个字节,我测试的[si]为0x180
seg000:7C2A                 jz      short loc_7C2F  ; 是活动分区的时候不跳转,否则跳转
seg000:7C2C                 mov     dx, si
seg000:7C2E                 inc     bx              ; bx=1,接着之前的0
seg000:7C2F
seg000:7C2F loc_7C2F:                               ; CODE XREF: seg000:7C2Aj
seg000:7C2F                 add     si, 10h         ; 活动分区表指向下一个
seg000:7C32                 loop    loc_7C27        ; 判断是否是活动分区,0x80为活动分区,由于[si]是2个字节,我测试的[si]为0x180
seg000:7C34                 cmp     bx, 1           ; 判断是否只有一个活动分区表
seg000:7C37                 jz      short Find_Partition ; 只有一个就跳转
seg000:7C39                 mov     si, 0C4h        ; 如果活动分区表为0或者大于1,则错误,si = C4h
seg000:7C3C                 mov     cx, 17h         ; cx = 17h 十进制的23(Invalid partition table的长度)
seg000:7C3F                 jmp     short Print_Error ; si = C4h + 600h = 6C4h,指向Invalid partition table字符串
seg000:7C41 ; ---------------------------------------------------------------------------
seg000:7C41                 nop
seg000:7C42
seg000:7C42 Find_Partition:                         ; CODE XREF: seg000:7C37j
seg000:7C43                 mov     ah, 41h         ; int13 41号功能,检测特定驱动器是否有扩展功能
seg000:7C45                 mov     dl, 80h
seg000:7C47                 mov     bx, 55AAh       ; 如果存在扩展13H功能,执行完int13,bx = AA55h,CL = 5
seg000:7C4A                 int     13h             ; DISK - Check for INT 13h Extensions
seg000:7C4A                                         ; BX = 55AAh, DL = drive number
seg000:7C4A                                         ; Return: CF set if not supported
seg000:7C4A                                         ; AH = extensions version
seg000:7C4A                                         ; BX = AA55h
seg000:7C4A                                         ; CX = Interface support bit map
seg000:7C4C                 pop     dx
seg000:7C4D                 cmp     bx, 0AA55h      ; 判断是否存在扩展INT13功能
seg000:7C51                 jnz     short loc_7C86  ; 调用int13的02号读扇区功能
seg000:7C53                 test    cl, 1           ; 此时CL = 5
seg000:7C56                 jz      short loc_7C86  ; 调用int13的02号读扇区功能
seg000:7C58                 mov     ax, 4200h
seg000:7C5B                 mov     si, 7ADh        ; si = 7ADh
seg000:7C5E                 mov     cl, 10h         ; 循环次数
seg000:7C60
seg000:7C60 loc_7C60:                               ; CODE XREF: seg000:7C64j
seg000:7C60                 mov     byte ptr [si], 0 ; 7ADh到7BDh之间这0x10全部赋值为0
seg000:7C63                 inc     si
seg000:7C64                 loop    loc_7C60        ; 7ADh到7BDh之间这0x10全部赋值为0
seg000:7C66                 mov     si, 7ADh
seg000:7C69                 mov     di, dx          ; dx = 0x7BE
seg000:7C6B                 mov     byte ptr [si], 10h ; 设置7AD到7BD之间的值分别为
seg000:7C6B                                         ; 10 00 01 00 00 7C 00 00  3F 00 00 00 00 00 00 00
seg000:7C6E                 mov     byte ptr [si+2], 1
seg000:7C72                 mov     word ptr [si+4], 7C00h
seg000:7C77                 mov     bx, [di+8]
seg000:7C7A                 mov     [si+8], bx
seg000:7C7D                 mov     bx, [di+0Ah]
seg000:7C80                 mov     [si+0Ah], bx
seg000:7C83                 jmp     short loc_7C94  ; 此时ax = 4200h,
seg000:7C83                                         ; 继续利用int 13检测驱动器的扩展性
seg000:7C83 ; ---------------------------------------------------------------------------
seg000:7C85                 db  90h ; 
seg000:7C86 ; ---------------------------------------------------------------------------
seg000:7C86
seg000:7C86 loc_7C86:                               ; CODE XREF: seg000:7C51j
seg000:7C86                                         ; seg000:7C56j
seg000:7C86                 mov     ax, 201h        ; 调用int13的02号读扇区功能
seg000:7C89                 mov     bx, 7C00h
seg000:7C8C                 mov     si, dx
seg000:7C8E                 mov     cx, [si+2]
seg000:7C91                 mov     dh, [si+1]      ; 将活动分区的第一个扇区读入到内存地址0000:7c00
seg000:7C94
seg000:7C94 loc_7C94:                               ; CODE XREF: seg000:7C83j
seg000:7C94                 mov     dl, 80h         ; 此时ax = 4200h,
seg000:7C94                                         ; 继续利用int 13检测驱动器的扩展性
seg000:7C96                 int     13h             ; DISK - READ SECTORS INTO MEMORY
seg000:7C96                                         ; AL = number of sectors to read, CH = track, CL = sector
seg000:7C96                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
seg000:7C96                                         ; Return: CF set on error, AH = status, AL = number of sectors read
seg000:7C98                 mov     si, 7DFEh
seg000:7C9B                 cmp     word ptr [si], 0AA55h ; 检测0000:7dfe是否等于0xaa55,若不等于则显示"Missing Operating System"
seg000:7C9F                 jz      short DBR       ; 相等就跳到DBR执行
seg000:7CA1                 mov     si, 0DBh
seg000:7CA4                 mov     cx, 18h         ; 循环次数十进制24,Missing Operating System长度为24
seg000:7CA7                 jmp     short Print_Error ; si = C4h + 600h = 6C4h,指向Invalid partition table字符串
seg000:7CA7 ; ---------------------------------------------------------------------------
seg000:7CA9                 db  90h ; 
seg000:7CAA ; ---------------------------------------------------------------------------
seg000:7CAA
seg000:7CAA DBR:                                    ; CODE XREF: seg000:7C9Fj
seg000:7CAA                 xor     ax, ax
seg000:7CAC                 push    ax
seg000:7CAD                 mov     ax, 7C00h
seg000:7CB0                 push    ax
seg000:7CB1                 retf                    ; jmp到0000:7c00处,将控制权交给DBR
seg000:7CB2 ; ---------------------------------------------------------------------------
seg000:7CB2
seg000:7CB2 Print_Error:                            ; CODE XREF: seg000:7C3Fj
seg000:7CB2                                         ; seg000:7CA7j
seg000:7CB2                 add     si, 600h        ; si = C4h + 600h = 6C4h,指向Invalid partition table字符串
seg000:7CB6
seg000:7CB6 loc_7CB6:                               ; CODE XREF: seg000:7CBEj
seg000:7CB6                 lodsb                   ; 块装入指令,ds:si的值赋给al
seg000:7CB6                                         ; cx = 23为循环变量(loop的循环结束条件cx = 0)
seg000:7CB6                                         ; 一次显示一个al字符
seg000:7CB7                 mov     bx, 7
seg000:7CBA                 mov     ah, 0Eh
seg000:7CBC                 int     10h             ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
seg000:7CBC                                         ; AL = character, BH = display page (alpha modes)
seg000:7CBC                                         ; BL = foreground color (graphics modes)
seg000:7CBE                 loop    loc_7CB6        ; 块装入指令,ds:si的值赋给al
seg000:7CBE                                         ; cx = 23为循环变量(loop的循环结束条件cx = 0)
seg000:7CBE                                         ; 一次显示一个al字符
seg000:7CC0
seg000:7CC0 loc_7CC0:                               ; CODE XREF: seg000:7CC2j
seg000:7CC0                 mov     cl, 0Fh
seg000:7CC2                 loop    loc_7CC0
seg000:7CC2 ; ---------------------------------------------------------------------------
seg000:7CC4 aInvalidPartitionTa db 'Invalid partition tableMissing operating system',0
[size=3]seg000:7CF4 aMasterBootReco db 'Master Boot Record Wrote by MBR By DiskGenius',0


PS:
我动态跟的时候,不知道为什么,没有看到“将活动分区的第一个扇区读入到内存地址0000:7c00”这个步骤,
而是直接进行了两次int13 41功能号函数,最后跳到了DBR执行,然后启动。

慢慢分析,觉得还是蛮简单,贵在坚持。如果有分析得错误的地方,忘指点交流。

附件:idb和mbr文件 Desktop.rar (8.45 KB, 下载次数: 55)

免费评分

参与人数 1热心值 +1 收起 理由
鱼无论次 + 1 我正好需要部分内容,谢谢分享

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

零度x 发表于 2013-10-2 00:38
赞,好详细的注释
鱼无论次 发表于 2016-8-25 22:47
本帖最后由 鱼无论次 于 2016-8-25 23:04 编辑

test    cl, 1           ; 此时CL = 5
这里是笔误吗cl前面寻找活动分区不是赋值为4吗?
难道不是cl=4?
不好意思看错了,如果存在int13h扩展功能返回是CL = 5
ILoveBBS 发表于 2013-11-11 21:35
soleil 发表于 2013-11-16 12:39
受教学习了,没想到这东西细分的话还有这么多的知识啊
吾乐乐丶小米 发表于 2013-11-16 12:41
楼主辛苦了~
风2013 发表于 2013-11-24 08:11
好东西,先收藏起来
拆及鸡鸡 发表于 2013-11-24 21:06
好神奇的 感觉 哈哈
zxszx4 发表于 2013-12-20 12:10
我去,可能楼主图片略大,我用遨游和ie全都崩溃,之后只能用火狐,差点呀,就差那么一点点。我现在怀疑我这电脑还能活几年
小人物大智慧 发表于 2013-12-23 19:45
好文章 mark下 多谢楼主
Fochess 发表于 2014-2-23 16:17
Thanks LZ.
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-10 19:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表