- 论坛徽章:
- 0
|
由机器上电到 vista 加载完毕,大致分为 6 大部分:
流程如下:
POST(INT 19h)---> 0x7c00 ---> 0x20000 ---> bootmgr ---> winload ---> nt(kernel)加载完华
第一部分:
机器上电做自检 POST 后,最后一步工作是调用 INT 19h,进行加载 MBR 到 0x7c00,并转入 0x7c00 执行,Int 19h 是永不返回,Int 19h 加载完 MBR 后,直接跳转到 0x7c00 处执行,它不会返回到 POST 自检代码。
第二部分:
进入 0x7c00 后,它会自己复制到 0x6000 然后执行,此时它将 Boot Sector 重新加载到 0x7c00,再跳回到 0x7c00 执行,在这个加载过程中,它遍历检查 4 个磁盘分区,遇到第一个可启动分区时,就将这个分区的 Boot Sector 加载到 0x7c00 执行,最后,转入到 0x20000 领域继续执行。
第三部分:
进入 0x20000 领域,这个领域主要是负责环境的初步建立,开启保护模式,加载更多的模块及驱动程序。此间后进行反复多次的模式转换,即:real mode --> protection mode ---> real mode ....
再进入 vista 的 boot 管理模块时,已经建立了保护模式,但分页机制尚未开启。
这个部分的最后工作是转入 bootmgr 的入口函断 bootmgr!BmMain()
第四部分:
进入 vista 的 bootmgr 模块,此时屏幕上仍旧是黑屏。这个模块经由 bootmgr!BmMain() 入口函数转入。
1、下面是 windbg 在 bootmgr 响应断点时的信息:
Microsoft (R) Windows Debugger Version 6.9.0003.113 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Opened \\.\pipe\com_1
Waiting to reconnect...
BD: Boot Debugger Initialized
Connected to Windows Boot Debugger 6000 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established. (Initial Breakpoint requested)
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path. *
* Use .symfix to have the debugger choose a symbol path. *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
* *
* The Symbol Path can be set by: *
* using the _NT_SYMBOL_PATH environment variable. *
* using the -y <symbol_path> argument when starting the debugger. *
* using .sympath and .sympath+ *
*********************************************************************
*** ERROR: Module load completed but symbols could not be loaded for bootmgr
Windows Boot Debugger Kernel Version 6000 UP Free x86 compatible
Primary image base = 0x00400000 Loaded module list = 0x004ffff8
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
bootmgr+0x37ea4:
00437ea4 cc int 3 |
---------------------------------------------------------------------------------------------------------------
2、bootmgr 模块被加载到 0x00400000 处,其入口函数 BmMain() 在 0x00401000
bootmgr!BmMain:
00401000 8bff mov edi,edi
00401002 55 push ebp
00401003 8bec mov ebp,esp
00401005 83e4f8 and esp,0FFFFFFF8h
00401008 83ec64 sub esp,64h
0040100b 53 push ebx
0040100c 56 push esi
0040100d 57 push edi
0040100e 6a07 push 7
00401010 33db xor ebx,ebx
00401012 59 pop ecx
00401013 ff7508 push dword ptr [ebp+8]
00401016 8d742454 lea esi,[esp+54h]
0040101a 8d7c2438 lea edi,[esp+38h]
0040101e c744245404000000 mov dword ptr [esp+54h],4
00401026 c744245801000000 mov dword ptr [esp+58h],1
0040102e c744245c00040000 mov dword ptr [esp+5Ch],400h
00401036 c744246000002000 mov dword ptr [esp+60h],200000h
0040103e 895c2464 mov dword ptr [esp+64h],ebx
00401042 895c2468 mov dword ptr [esp+68h],ebx
00401046 895c246c mov dword ptr [esp+6Ch],ebx
0040104a f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0040104c 8d442438 lea eax,[esp+38h]
00401050 c744243808000000 mov dword ptr [esp+38h],8
00401058 895c243c mov dword ptr [esp+3Ch],ebx
0040105c c744244010000000 mov dword ptr [esp+40h],10h
00401064 c744244400000100 mov dword ptr [esp+44h],10000h
0040106c c744244c3c154500 mov dword ptr [esp+4Ch],offset bootmgr!`string' (0045153c)
00401074 e89dc90100 call bootmgr!BlInitializeLibrary (0041da16)
00401079 8bf0 mov esi,eax
0040107b 3bf3 cmp esi,ebx
0040107d 7d1c jge bootmgr!BmMain+0x9b (0040109b)
... ...
|
3、来看看 0x20000 模块是怎样进入 bootmgr 的:
000209cd: mov cx, 0x30
000209d0: mov ss, cx
000209d2: mov ds, cx
000209d4: mov es, cx
000209d6: mov esp, 0x00061ffc
000209dc: push edx
000209de: push ebp
000209e0: xor ebp, ebp
000209e3: push 0x00000020
000209e6: push ebx
000209e8: retf
|
0x20000 模块给 bootmgr!BmMain() 传送了 2 个参数,ebx 此时为 0x00401000
代码直接转到了 0020:00401000 处,即 bootmgr 模块的入口 BmMain() 函数。
4、最后 bootmgr 模块完成工作后转到 winload 模块进行加载 nt 核心,来看看 bootmgr 模块是如何转入 winload 模块的
bootmgr!Archx86TransferTo32BitApplicationAsm:
004444c0 55 push ebp
004444c1 56 push esi
004444c2 57 push edi
004444c3 53 push ebx
004444c4 06 push es
004444c5 1e push ds
004444c6 8bdc mov ebx,esp
004444c8 0f010590ad4700 sgdt fword ptr [bootmgr!GdtRegister (0047ad90)]
004444cf 0f010db8ad4700 sidt fword ptr [bootmgr!IdtRegister (0047adb8 )]
004444d6 0f0115d0ad4700 lgdt fword ptr [bootmgr!BootAppGdtRegister (0047add0)]
004444dd 0f011da0ad4700 lidt fword ptr [bootmgr!BootAppIdtRegister (0047ada0)]
004444e4 33ed xor ebp,ebp
004444e6 8b2588ad4700 mov esp,dword ptr [bootmgr!BootApp32Stack (0047ad88 )]
004444ec 53 push ebx
004444ed a1c8ad4700 mov eax,dword ptr [bootmgr!BootApp32Parameters (0047adc8 )]
004444f2 50 push eax
004444f3 a178ad4700 mov eax,dword ptr [bootmgr!BootApp32EntryRoutine (0047ad78 )]
004444f8 ffd0 call eax
004444fa 5b pop ebx
004444fb 8be3 mov esp,ebx
004444fd 0f011590ad4700 lgdt fword ptr [bootmgr!GdtRegister (0047ad90)]
00444504 0f011db8ad4700 lidt fword ptr [bootmgr!IdtRegister (0047adb8 )]
0044450b 1f pop ds
0044450c 07 pop es
0044450d 5b pop ebx
0044450e 5f pop edi
0044450f 5e pop esi
00444510 5d pop ebp
00444511 c3 ret |
最后由 bootmgr!Archx86TransferTo32BitApplicationAsm() 函数转入到 winload 模块。
bootmgr!Archx86TransferTo32BitApplicationAsm() 函数也是永不返回的,它直接由 call eax 来调用 winload 入口函数。
此时 eax 的值是 0x0057c000,即 winload 的入口函数。
第五部分:
由 bootmgr 模块入 winload 后,此时接 F8 键时,屏幕上可以看到 vista 的启动菜单以供选择。
1、来看看 winload 模块的信息
Connected to Windows Boot Debugger 6000 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established. (Initial Breakpoint requested)
Symbol search path is: E:\Symbols;SRV*d:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows Boot Debugger Kernel Version 6000 UP Free x86 compatible
Primary image base = 0x0057b000 Loaded module list = 0x00678d38
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
winload!RtlpBreakWithStatusInstruction:
005b0b58 cc int 3 |
winload 模块被加载到地址 0x0057b000 上,此时依旧是未开启分页机制。
2、winload 的入口函数 winload!OslMain()
winload!OslMain:
0057c000 8bff mov edi,edi
0057c002 55 push ebp
0057c003 8bec mov ebp,esp
0057c005 83e4f8 and esp,0FFFFFFF8h
0057c008 83ec54 sub esp,54h
0057c00b 53 push ebx
0057c00c 56 push esi
0057c00d 8b7508 mov esi,dword ptr [ebp+8]
0057c010 8b5634 mov edx,dword ptr [esi+34h]
0057c013 57 push edi
0057c014 03d6 add edx,esi
0057c016 6a07 push 7
0057c018 59 pop ecx
0057c019 33c0 xor eax,eax
0057c01b 8bfa mov edi,edx
0057c01d f3ab rep stos dword ptr es:[edi]
0057c01f c70201000000 mov dword ptr [edx],1
0057c025 8b5e28 mov ebx,dword ptr [esi+28h]
0057c028 03de add ebx,esi
0057c02a 6a08 push 8
0057c02c bf64a25c00 mov edi,offset winload!`string' (005ca264)
0057c031 8bf3 mov esi,ebx
0057c033 59 pop ecx
0057c034 33c0 xor eax,eax
0057c036 f3a6 repe cmps byte ptr [esi],byte ptr es:[edi]
0057c038 89542418 mov dword ptr [esp+18h],edx
0057c03c 740d je winload!OslMain+0x4b (0057c04b) |
由 bootmgr!Archx86TransferTo32BitApplicationAsm() 传过来两个参数给 OslMain()
3、最后 winload 引导真正的 vista 内核模块 nt 模块,经由 winload!OslArchTransferToKernel() 函数转入 vista 内核
看看 winload!OslArchTransferToKernel() 是如何转到 nt 模块的
winload!OslArchTransferToKernel:
005b0854 e86018fdff call winload!BlBdStop (005820b9)
005b0859 0f0115488d6700 lgdt fword ptr [winload!OslKernelGdt (00678d4]
005b0860 0f011d408d6700 lidt fword ptr [winload!OslKernelIdt (00678d40)]
005b0867 66b81000 mov ax,10h
005b086b 668ed8 mov ds,ax
005b086e 668ec0 mov es,ax
005b0871 668ed0 mov ss,ax
005b0874 668ee8 mov gs,ax
005b0877 66b83000 mov ax,30h
005b087b 668ee0 mov fs,ax
005b087e 66b82800 mov ax,28h
005b0882 0f00d8 ltr ax
005b0885 8b4c2404 mov ecx,dword ptr [esp+4]
005b0889 8b442408 mov eax,dword ptr [esp+8] /* nt (kernel) 入口 */
005b088d 33d2 xor edx,edx
005b088f 51 push ecx
005b0890 52 push edx
005b0891 6a08 push 8 /* kernel selector */
005b0893 50 push eax
005b0894 cb retf |
winload!OslArchTransferToKernel() 也是传递两个参数给 nt 的入口函数,这个函数也是永不返回,直接转入到
0008:0x818e6000 即入口函数 nt!KiSystemStartup()
第六部分:
进入 vista 内核执行体模块 nt,它的入口函数是 nt!KiSystemStartup()
1、看看 nt 模块的信息
kd> lmvm nt
start end module name
81800000 81ba1000 nt (pdb symbols) d:\symbols\ntkrpamp.pdb\EE06EF9F8438441DA22118869ADE8A872\ntkrpamp.pdb
Loaded symbol image file: ntkrpamp.exe
Image path: ntkrpamp.exe
Image name: ntkrpamp.exe
Timestamp: Thu Sep 18 09:56:32 2008 (48D1B550)
CheckSum: 0036433F
ImageSize: 003A1000
File version: 6.0.6000.16754
Product version: 6.0.6000.16754
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
File type: 1.0 App
File date: 00000000.00000000
Translations: 0409.04b0
CompanyName: Microsoft Corporation
ProductName: Microsoft® Windows® Operating System
InternalName: ntkrpamp.exe
OriginalFilename: ntkrpamp.exe
ProductVersion: 6.0.6000.16754
FileVersion: 6.0.6000.16754 (vista_gdr.080917-1612)
FileDescription: NT Kernel & System
LegalCopyright: © Microsoft Corporation. All rights reserved. |
nt 模块被加载到地址 0x81800000 之上,即 0x8180000 之上的地址空间属内核空间。实际映象名为 ntkrpamp.exe
2、看看 nt 的入口函数 KiSystemStartup()
nt!KiSystemStartup:
818e6000 55 push ebp
818e6001 8bec mov ebp,esp
818e6003 83ec20 sub esp,20h
818e6006 8b5d08 mov ebx,dword ptr [ebp+8]
818e6009 891df4199381 mov dword ptr [nt!KeLoaderBlock (819319f4)],ebx
818e600f 0fb60db01a9381 movzx ecx,byte ptr [nt!KeNumberProcessors (81931ab0)]
818e6016 894de8 mov dword ptr [ebp-18h],ecx
818e6019 0bc9 or ecx,ecx
... ...
|
总结一下:
Int 19h ----> 0x7c00 ---> 0x20000 --->
---> (0x00401000) bootmgr!BmMain ---> (0x004444c0) bootmgr!Archx86TransferTo32BitApplicationAsm
---> (0x0057c000) winload!OslMain --> (0x005b0854) winload!OslArchTransferToKernel
---> (0x818e6000)nt!KiSystemStartup
对于每个模块的分析,后续篇章再分析。
|
评分
-
查看全部评分
|