免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4678 | 回复: 0

调试 vista 启动 [复制链接]

论坛徽章:
0
发表于 2009-01-27 01:50 |显示全部楼层
由机器上电到 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&reg; Windows&reg; 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:   &copy; 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



对于每个模块的分析,后续篇章再分析。

评分

参与人数 1可用积分 +15 收起 理由
prolj + 15 原创内容

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP