解读WindowsXPFAT32⽂件系统引导程序
解读 Windows XP FAT32 ⽂件系统引导程序
WINXP引导程序分2部分,第⼀部分在分区的第1扇区,第⼆部分在分区的第12扇区.(在我电脑磁盘中是这样的)
以下是我对引导程序的分析,由于本⼈⽔平有限,难免有不当之处,望⼤家不吝指出!
联系⽅式:
E-mail:yth9@www.doczj/doc/ac413b0f52ea551810a68765.html
⽹易博客⽤户名:yth9
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 7C00 EB 58 JMP 7C5A
7C02 90 nop
7C03-7C59 磁盘信息
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 7C5A 33C9 XOR CX,CX
7C5C 8ED1 MOV SS,CX
7C5C BCF47B MOV SP,7BF4
7C61 8EC1 MOV ES,CX
7C63 8ED9 MOV DS,CX
7C65 BD007C MOV BP,7C00
7C68 884E02 MOV [BP+02],CL
7C6B 8A5640 MOV DL,[BP+40] ;驱动器编号软盘为00H,硬盘为80H
7C6E B408 MOV AH,08 ;ah=08h 读取驱动器参数
7C70 CD13 INT 13
7C72 7305 JNB 7C79 ;CF=0 成功转7c79
7C74 B9FFFF MOV CX,FFFF ;读参数失败,则取最⼤值:柱⾯数=1024,磁头数=256,扇区数=63
7C77 8AF1 MOV DH,CL
7C79 660FB6C6 MOVZX EAX,DH ;读参数成功,则dh=磁头数,CH=柱⾯数的低8位;CL(7-6)=柱⾯数的⾼2位,CL(5-0)=扇区数
7C7D 40 INC AX ;ax=磁头数
7C7E 660FB6D1 MOVZX EDX,CL
7C82 80E23F AND DL,3F ;dx=扇区数
7C85 F7E2 MUL DX ;ax=扇区数x磁头数
7C87 86CD XCHG CH,CL
7C89 C0ED06 SHR CH,06
7C8C 41 INC CX ;cx=柱⾯数
7C8D 660FB7C9 MOVZX ECX,CX
7C91 66F7E1 MUL ECX ;eax=扇区数x磁头数x柱⾯数=磁盘的总扇区数
7C94 668946F8 MOV [BP-08],EAX ;[bp-8]=磁盘的总扇区数
7C98 837E1600 CMP WORD PTR [BP+16],0000 ;[bp+16]=每个FAT表占多少个扇区⽤于FAT16等,FAT32时置零
7C9C 7538 JNE 7CD6 ;不为FAT32格式转7CD6
7C9E 837E2A00 CMP WORD PTR [BP+2A],0000 ;[bp+2a]=⽂件系统格式版本号
7CA2 7732 JA 7CD6 ;⼤于0转7CD6
7CA4 668B461C MOV EAX,[BP+1C] ;[bp+1c]=有多少个隐藏扇区即分区起始扇区之前的绝对物理扇区数(63)
7CA8 6683C00C ADD EAX,0000000C ;下⼀段引导程序在分区的第12扇区
7CAC BB0080 MOV BX,8000 ;缓冲地址
7CAF B90100 MOV CX,0001 ;读⼀个扇区
7CB2 E82B00 CALL 7CE0 ;读盘
7CB5 E94803 JMP 8000 ;读盘正确,则转程序正确出⼝
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;显⽰出错信息
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 7CB8 A0FA7D MOV AL,[7DFA] ;ax=7dbfh [7dbf]=Disk error
7CBB B47D MOV AH,7D
7CBD 8BF0 MOV SI,AX ;si=ax
7CBF AC LODSB
7CC0 81C0 TEST AL,AL
7CC2 7417 JE 7CDB ;zf=1 即al = 0 转 7cdb 错误信息显⽰完成
7CC4 3CFF CMP AL,FF
7CC6 7409 JE 7CD1 ;zf=1 即al = ff 转 7cd1
7CC8 B40E MOV AH,0E ;在Teletype模式下显⽰字符
7CCA BB0700 MOV BX,0007 ;BH
=页码 BL=前景⾊
7CCD CD10 INT 10 ;显⽰服务
7CCF EBEE JMP 7CBF ;显⽰下⼀个字符
7CD1 A0FB7D MOV AL,[7DFB] ;ax=7dcc [7dcc]=Press any key to restart
7CD4 EBE5 JMP 7CBB
7CD6 A0F97D MOV AL,[7DF9] ;ax=7dac [7dac]=NTLDR is missing
7CD9 EBE0 JMP 7CBB
7CDB 98 CBW ;ax=0
7CDC CD16 INT 16 ;等待从键盘读⼊字符
7CDE CD19 INT 19 ;重启动系统
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;读盘⼦程序
;⼊⼝参数: eax=磁盘起始绝对块地址 ecx=要读的扇区数 es:bx=读盘缓冲地址
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 7CE0 6660 PUSHAD ;把寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI和EDI等压栈
7CE2 663B46F8 CMP EAX,[BP-08] ;要读的起始扇区号和最⼤扇区号⽐较
7CE6 0F824A00 JB 7D34 ;⼩于则⽤常规int13h读盘
7CEA 666A00 PUSH 00000000 ;扩展 Int13H 构造磁盘地址数据包
7CED 6650 PUSH EAX ;磁盘起始绝对块地址,和分区⽆关占8字节(以扇区为单位)
7CEF 06 PUSH ES ;读盘缓冲地址(ES=segment:BX=offset)
7CF0 53 PUSH BX
7CF1 666810000100 PUSH 00010010 ;要传输的数据块个数(0001扇区),保留字段(00),磁盘地址数据包尺⼨(10h)
7CF7 807E0200 CMP BYTE PTR [BP+02],00
7CFB 0F852000 JNE 7D1F ;不是⾸次读盘,则直接转读盘
7CFF B441 MOV AH,41 ;否则检验扩展int13h功能是否存在
7D01 BBAA55 MOV BX,55AA
7D04 8A5640 MOV DL,[BP+40] ;[BP+40]=驱动器号
7D07 CD13 INT 13
7D09 0F821C00 JB 7D29 ;cf=1则此驱动器不⽀持扩展功能,转出错
7D0D 81FB55AA CMP BX,AA55 ;如果进位标志为0,同时 BX = AA55h,则存在扩展功能
7D11 0F851400 JNE 7D29 ;不相等转出错
7D15 F6C101 TEST CL,01 ;测试是否⽀持扩展功能第⼀个⼦集
7D18 0F840D00 JE 7D29 ;不⽀持转出错
7D1C FE4602 INC BYTE PTR [BP+02] ;通过检验则[bp+02]=1
7D1F B442 MOV AH,42 ;调⽤扩展读功能
7D21 8A5640 MOV DL,[BP+40] ;[BP+40]=驱动器号
7D24 8BF4 MOV SI,SP ;si=磁盘地址数据包
7D26 CD13 INT 13
7D28 B0F9 MOV AL,F9 ;注意:顺序执⾏mov AL,F9在此没实际意义,⽽前⾯有3条转移指令都转到7D29
;即执⾏7D29 F9 stc 置进位标志,因为前⾯的⽐较、测试指令改变了进位标志
7D2A 6658 POP EAX ;以下四条指令平衡堆栈去掉磁盘地址数据包占⽤堆栈
7D2C 6658 POP EAX
7D2E 6658 POP EAX
7D30 6658 POP EAX
7D32 EB2A JMP 7D5E ;跳过常规int13h代码
7D34 6633D2 XOR EDX,EDX
7D37 660FB74E18 MOVZX ECX,WORD PTR [BP+18] ;[BP+18]=每个磁道有多少个扇区
7D3C 66F7F1 DIV ECX ;磁盘起始绝对扇区数/每个磁道扇区数=磁道数
7D3F FEC2 INC DL
7D41 8ACA MOV CL,DL ;cl=剩余扇区数
7D43 668BD0 MOV EDX,EAX
7D46 66C1EA10 SHR EDX,10 ;dx:ax=总磁道数
7D4A F7761A DIV WORD PTR [BP+1A] ;总磁道数/磁头数
=柱⾯数
7D4D 86D6 XCHG DH,DL
7D4F 8A5640 MOV DL,[BP+40] ;[BP+40]=驱动器号
7D52 8AE8 MOV CH,AL ;CH=柱⾯号低8位
7D54 C0E406 SHL AH,06
7D57 0ACC OR CL,AH ;cl=扇区号低6位柱⾯号⾼2位(6-7)bit
7D59 B80102 MOV AX,0201 ;读1个扇区
7D5C CD13 INT 13
7D5E 6661 POPAD ;把寄存器EDI、ESI、EBP、ESP、EBX、EDX、ECX和EAX等弹出栈
7D60 0F8254FF JB 7CB8 ;读盘失败转7cb8
7D64 81C30002 ADD BX,0200 ;缓冲区+200h字节,为读下⼀扇区作准备
7D68 6640 INC EAX ;磁盘起始绝对块地址号+1
7D6A 49 DEC CX ;要读的扇区数减⼀
7D6B 0F8571FF JNE 7CE0 ;不为0读下⼀扇区
7D6F C3 RET
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 7D70 db 'NTLDR '
7D7C db 31h dup(0)
7DAC db 0DH,0AH,'NTLDR is missing',0FFH,
7DBF db 0DH,0AH,'Disk error',0FFH,
7DCC db 0DH,0AH,'Press any key to restart',0DH,0AH
7DE8 db 11h dup(0),0ACH,0BFH,0CCH,00H,00H,55H,AAH
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;引导程序的第⼆部分
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;在根⽬录搜索NTLDR⽂件⽬录项
8000 660fb64610 movzx eax,byte ptr [bp+10] ;这个卷有多少个FAT表
8005 668b4e24 mov ecx,[bp+24] ;每个⽂件分配表的扇区数
8009 66f7e1 mul ecx ;eax=⽂件分配表所占扇区数
800c 6603461c add eax,[bp+1c] ;有多少个隐藏扇区即分区起始扇区之前的绝对物理扇区数
8010 660fb7560e movzx edx,word ptr [bp+0e] ;保留扇区数⽬,指的是第⼀个FAT表开始之前的扇区数,包括DBR本⾝
8015 6603c2 add eax,edx
8018 668946fc mov [bp-04],eax ;[bp-04]=⽂件分配表所占扇区数+隐藏扇区数+保留扇区数
801c 66c746f4ffffffff mov dword ptr [bp-0c],ffffffff
8024 668b462c mov eax,[bp+2c] ;根⽬录起始簇之簇号
8028 6689f802 cmp eax,2
802c 0f82a6fc jb 7cd6 ;⼩于2出错
8030 663df8ffff0f cmp eax,0ffffff8
8036 0f839cfc jnb 7cd6 ;⼤于等于0fffffff8出错
803a 6650 push eax ;根⽬录起始簇号⼊栈
803c 6683e802 sub eax,2
8040 660fb65e0d movzx ebx,byte ptr [bp+0d] ;每个簇有多少个扇区
8045 8bf3 mov si,bx ;si=每个簇有多少个扇区
8047 66f7e3 mul ebx ;eax=根⽬录相对数据区的起始扇区数
804a 660346fc add eax,[bp-04] ;eax=根⽬录绝对起始扇区号
804e bb0082 mov bx,8200 ;传输缓冲地址(ES=segment:BX=offset)
8051 8bfb mov di,bx
8053 b90100 mov cx,1 ;读⼀个扇区
8056 e887fc call 7ce0 ;调⽤读盘⼦程序,读根⽬录
8089 382d cmp [di],ch
805b 741e je 807b ;根⽬录第⼀个字节为0则转807b
805d b10b mov cl,0b
805f 56 push si
8060 be707d mov si,7d70 ;[7d70]='NTLDR '
8063 f3a6 rep cmpsb ;查⽂件NTLDR
8065 5e pop si
8066 741b je 8083 ;到则转8083
8068
03f9 add di,cx
806a 83c715 add di,0015 ;转到下⼀个⽬录项
806d 3bfb cmp di,bx ;bx=缓冲地址+200h
806f 72eb jb 8059 ;cf=1 搜索下⼀个⽬录项
8071 4e dec si ;该簇已读⼀个扇区,则减少⼀个扇区
8072 75da jne 804e ;zf=0 还没读完⼀簇,继续读下⼀扇区
;到此已读完⼀簇,还没到NTLDR,准备读下⼀簇
8074 6658 pop eax ;根⽬录起始簇号出栈
8076 e86500 call 80de ;取下⼀簇簇号
8079 72bf jb 803a ;没到根⽬录结尾,则继续查⽂件
807b 83c404 add sp,4 ;平衡堆栈
807e e955fc jmp 7cd6 ;转出错
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;读⽂件NTLDR,并转到NTLDR⽂件偏移0000h处执⾏
8081 0020 dw 2000 ;读盘缓冲区段⾸址
8083 83c404 add sp,4
8086 8b7509 mov si,[di+09] ;FAT32中第⼀个簇的两个⾼字节(09h+0bh=14h)
8089 8b7d0f mov di,[di+0f] ;FAT32中第⼀个簇的两个低字节(0fh+0bh=1ah)
808c 8bc6 mov ax,si
808e 66c1e010 shl eax,10
8092 8bc7 mov ax,di ;eax=⽂件第⼀簇簇号
8094 6683f802 cmp eax,2
8098 0f823afc jb 7cd6 ;簇号⼩于2转出错
809c 663df8ffff0f cmp eax,0ffffff8
80a2 0f8330fc jnb 7cd6 ;簇号不⼩于0ffffff8转出错
80a6 6650 push eax ;⽂件簇号⼊栈
80a8 6683e802 sub eax,2
80ac 660fb64e0d movzx ecx,byte ptr [bp+0d] ;[bp+0d]=每个簇有多少个扇区,CX=要读的扇区数,即每次读⼀簇
80b1 66f7e1 mul ecx ;eax=⽂件相对数据区扇区号
80b4 660346fc add eax,[bp-04] ;eax=⽂件绝对扇区号
80b8 bb0000 mov bx,0
80bb 06 push es
80bc 8e068180 mov es,[8081] ;es:0000=读盘缓冲区⾸址
80c0 e81dfc call 7ce0 ;调⽤读盘⼦程序读⽂件NTLDR
80c3 07 pop es
80c4 6658 pop eax ;⽂件第⼀簇簇号出栈
80c6 c1eb04 shr bx,04
80c9 011e8180 add [8081],bx ;段⾸址+bx右移4位,实际上就是加上已读字节数
80cd e80e00 call 80de ;取下⼀簇簇号
80d0 0f830200 jnb 80d6 ;cf=0到了⽂件末尾转80D6
80d4 72d0 jb 80a6 ;cf=1 没到⽂件末尾转80a6,继续读下⼀簇
80d6 8a5640 mov dl,[bp+40] ;驱动器号
80d9 ea00000020 jmp 2000:0000 ;转到NTLDR偏移0000h(20000h)处执⾏,到此引导程序圆满完成任务
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;取下⼀簇簇号
;⼊⼝参数:eax=当前簇号
;出⼝参数:eax=下⼀簇簇号
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 80de 66c1e002 shl eax,02 ;当前簇号 X 4 = 当前簇在FAT表中的偏移字节数
80e2 e81100 call 80f6 ;读FAT表
80e5 26668b01 mov eax,es:[bx+di] ;eax=下⼀簇簇号(当前簇号中的内容为下⼀簇的簇号)
80e9 6625ffffff0f and eax,0fffffff ;去掉⾼4位
80ef 663df8ffff0f cmp eax,0ffffff8 ;没到⽂件最后⼀个簇,则cf=1
80f5 c3
ret
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;读FAT表
;⼊⼝参数:eax=当前簇在FAT表中的字节偏移
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 80f6 bf007e mov di,7e00
80f9 660fb74e0b movzx ecx,word ptr [bp+0b] ;[bp+0b]=每个扇区多少字节
80fe 6633d2 xor edx,edx
8101 66f7f1 div ecx ;eax=当前簇在FAT表中的相对扇区号 edx=剩余字节偏移
8104 663b46f4 cmp eax,[bp-0c] ;[bp-0c]=前⼀簇在FAT表中的相对扇区号
8108 743a je 8144 ;相等转8144(不⽤读)
810a 668946f4 mov [bp-0c],eax
810e 6603461c add eax,[bp+1c] ;[bp+1c]=有多少个隐藏扇区即分区起始扇区之前的绝对物理扇区数
8112 660fb74e0e movzx ecx,word ptr [bp+0e] ;[bp+0e]=保留扇区数⽬,指的是第⼀个FAT表开始之前的扇区数,包括DBR本⾝
8117 6603c1 add eax,ecx ;eax=当前簇开始绝对扇区号
811a 660fb75e28 movzx ebx,word ptr [bp+28] ;[bp+28]最左端⼆进制位为零则所有FAT表是同步的,为1则有损坏的FAT表。
;低4位表⽰在⽤的FAT表编号,从零开始计
811f 83e30f and bx,000f
linux怎么读取windows文件8122 7416 je 813a ;fat表1 没有损坏则转816e
8124 3a5e10 cmp bl,[bp+10] ;[bp+10]=这个卷有多少个FAT表
8127 0f83abfb jnb 7cd6 ;不⼩于转出错
812b 52 push dx
812c 668bc8 mov ecx,eax ;ecx=当前簇开始绝对扇区号
812f 668b4624 mov eax,[bp+24] ;每个⽂件分配表的扇区数
8133 66f7e3 mul ebx
8136 6603c1 add eax,ecx ;eax=当前簇开始绝对扇区号
8039 5a pop dx
813a 52 push dx
813b 8bdf mov bx,di ;bx=7e00
813d b90100 mov cx,1
8140 e89dfb call 7ce0 ;读盘
8143 5a pop dx
8144 8bda mov bx,dx ;bx=剩余字节偏移
8146 c3 ret
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 8547 db 0B7 dup(0),55h,0aah
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论