此处我分析系统操作系统加载前的事(从按开机键开始),有心人一起讨论下。
电脑启动过程:(如果明白可直接跳过看下面MBR分析)
1.按下开机电源,电源向主板和其他设备供电,此时电压不稳,主板控制芯片会向CPU发送并保持RESET(复位信号),让CPU初始化。当电源开始稳定后,芯片组撤去RESERT信号。如果按RESERT信号,当放开RESERT时,就撤去RESERT信号。CPU从FFFF0h处执行指令,此处为一条跳转指令,使CPU跳转到系统BIOS的启动代码处。(这边是ROM改不了了,否则就从这开始拦截)
2.系统BIOS的启动代码首先进行POST(加点自检)。POST主要对一些关键硬件进行检查。如显卡,内存,主板等。由于此处在显卡初始化之前,所以无法图像显示,只能通过声音了。即我们所知道的通过声音判断硬件问题。
3.接着,系统BIOS查找显卡BIOS(通常地址C0000h处),找到后调用它的初始化代码,由显卡BIOS完成显卡的初始化,此处会在屏幕上显示显卡信息,厂商,显卡容量等。
4.接着系统BIOS会查找其他设备的BIOS,并调用它们的初始化代码
5.接着系统BIOS检查CPU类型和工作频率,并显示检测结果。之后系统BIOS检测内存并显示信息
6.内存测试通过后,检测其他安装的硬件设备,包括:硬盘,CD-ROM,串行接口,并行接口等。
7.标准设备查完后,系统BIOS内部的支持即插即用的代码检测和配置系统中安装的即插即用设备,每检测到一个,系统BIOS在屏幕上显示该设备信息,同时为设备分配中断,DMA通道和I/O端口资源
8.到此,硬件设备检测完毕,系统BIOS会重新清屏并在屏幕上显示出一个系统配置表,其中概略列出系统中安装的各种标准硬件设备,及他们使用的资源和一些相关参数。
9.接下来系统BIOS更新ESCD(扩展系统配置数据)。ESCD是系统BIOS用来与操作系统交换硬件配置信息的数据,存放在CMOS中。通常ESCD数据只有系统硬件配置改变时才更新。
10.ESCD更新完毕后,系统BIOS根据用户指定的启动顺序从指定设备启动(加载MBR到7c00h处,同时还会把设备的驱动号给dl,这点很重要,一定要记得)
MBR分析(如果大家已知MBR结构直接 看后面MBR程序吧)
1.MBR结构由 446字节的引导代码 和 64字节的4个分区表 加 0xaa55引导区标志组成
2.64字节分区表(DPT)由4个分区表组成,没个16个字节
3.DPT中分区表结构:
硬盘分区表(DPT)[主分区+扩展分区<= 4,每个分区占16字节]
偏移地址 字节数 含义分析
0 1 00表示非活动分区;80表示活动分区; 其他为无效分区
1 3 分区的起始地址 (面/扇区/磁道)
4 1 分区的操作系统类型
5 3 该分区的结束地址(面/扇/道)
8 4 该分区起始逻辑扇区
0ch 4 该分区占用的总扇区数
MBR引导代码分析:
;****************************************************
; Analyzer:zhanT
; Time:2013/9/17 2:10
;****************************************************
xor ax,ax
mov ss,ax
mov sp,7c00h
mov es,ax
mov ds,ax
mov si,7c00h
mov di,0600h
mov cx,0200h ;区块初始化
cld
repz movsb ;复制引导扇区内容到 0600h
push ax ;压入的 cs
push 61ch ;压入的 ip
retf ;远返回指令,相当跳转到 0:61ch
loc_1c:
sti
mov cx,4 ;
mov bp,7beh ;栈底 7beh 即指向DPT表
loc_23:
cmp byte ptr[bp+0],0 ;对介质类型判断
jl loc_34 ;if(如果是(活动分区)硬盘类){转移
jnz loc_13b ;if(非软驱){转移
add bp,10h ;继续判断下一个分区表
loop loc_23
int 18h
loc_34: ;对活动分区的处理
mov [bp+0],dl ;置分区号(bios启动后,引导主扇区时,分区号就是dl,用于13h 读写)
push bp ;驱动表的保护
mov byte ptr [bp+11h],05h ;重复加载的次数即最多加载分区引导扇区(DBR)
mov byte ptr [ebp+10h],0 ;API 位图是否支持的判断标志
mov ah,41h
mov bx,55aah
int 13
pop bp
jc loc_59 ;if(支持扩展13h){
cmp bx,aa55h
jnz loc_59 ;if(再次确定支持扩展){
test cx,1
jz loc_59 ;if(支持 API位图){
inc byte ptr [bp+10h]
loc_59:
pushad ;寄存器保护
cmp byte ptr [bp+10h],0
jz loc_87 ;if(支持 API位图){
push large 0 ;BlockNum_H4
push large dword ptr [ebp+8] ;BlockNum_L4
push 0 ;BufferAddr_H2
push 7c00h ;BufferAddr_L2
push 1 ;BlockCount=1
push 10h ;PacketSize=16 PReserved=0
;磁盘地址数据包
mov ah,42h
mov dl,[bp+0]
mov si,sp
int 13h ;扩展读
lahf ;保存标志位
add sp,10h ;堆栈平衡,即平衡刚才的地址数据包
sahf ;恢复标志位
jmp loc_9b
loc_87: ;非活动分区,或者说软盘类介质
mov ax,0201h
mov bx,7c00h
mov dl,[bp+0]
mov dh,[bp+1]
mov cl,[bp+2]
mov ch,[bp+3]
int 13h ;(由于一般软盘等<=8G,就不考虑扩展int13h了)
loc_9b:
popad ;恢复寄存器
jnb loc_bb ;if(不低于){转移 ?? I don't know
dec byte ptr[bp+11h] ;if(不等于0){跳转
jnz loc_b0
cmp byte ptr [bp+0],80h ;[ebp+11h]==0时执行
jz loc_136
mov dl,80h
jmp short loc_34 ;置分区号80h,再次执行
loc_b0:
push bp ;堆栈基址保护
xor ah,ah
mov dl,[bp+0]
int 13h ;初始化13h
pop bp ;堆栈基址恢复
jmp loc_59
loc_bb:
cmp word ptr [7dfe],0aa55h
jnz loc_131 ;if(读入的是引导扇区){
push [bp+0]
call sub_156
jnz loc_e2 ;if(始终一定时间状态寄存器 位1 仍 不等于 0){跳转
cli
mov al,0d1h
out 64h,al
call sub_156
mov al,0dfh
out 60h,al
call sub_156
mov al,0ffh
out 64h,al
call sub_156 ;键盘操作指令
sti
loc_e2:
mov ax,0bb00h
int 1ah
and eax,eax
jnz loc_127
cmp ebx,'TCPA'
jnz short loc_127
cmp cx,102h
jc short loc_127
push large 0bb07h
push large 200h
push large 8
push ebx
push ebx
push ebp
push large 0
push large 7c00h
pushad
push 0
pop es
int 1ah
loc_127:
pop dx
xor dh,dh
jmp far ptr 0:7c00h ;跳转到分区引导指令执行
int 18h
loc_131: ;使处理器暂停
mov al,[7b7h]
jmp short loc_13e
loc_136:
mov al,[7b6h]
jmp short loc_13e
loc_13b:
mov al,[7b5h]
loc_13e:
xor ah,ah
add ax,700h
mov si,ax
loc_145:
lodsb
cmp al,0
jz short loc_153
mov bx,7
mov ah,0eh
int 10h
jmp short loc_145
loc_153:
hlt ;处理器暂停
jmp short loc_153
sub_156 proc near ;状态寄存器判断函数(只有状态寄存器 位1 为0时,才能进行I/O 64h 和60h的操作)
sub cx,cx
loc_158:
in al,64h
jmp short $+2
and al,2
loopne loc_158 ;对端口64h内容的 位1 一直判断,直到判断为0
and al,2
retn
sub_156 endp
到此分析结束了,欢迎大家讨论.大家想做U盘引导程序可以参考 13h 中断所需用的驱动号,我刚才在电脑启动过程第10点说了,大家应该都会了。
还有,谁能传我几个病毒样本分析下啊,谢谢了啊。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)