Vista的啟動調試

來源:互聯網
上載者:User

原文連結:http://advdbg.org/blogs/advdbg_system/articles/784.aspx

在Vista之前,NTLDR是Windows作業系統的載入程式,它負責將CPU從實模式切換為保護模式,載入核心檔案和啟動類型的驅動程式,然後把執行權交給核心檔案的入口函數,即KiSystemStartup。

從要完成的任務角度來看,NTLDR內部又分為兩個部分,一部分負責接受執行權,做模式切換,硬體檢查,即啟動的準備工作,這部分通常稱為boot;另一部分負責載入核心檔案,並為核心的運行做必要的準備,通常稱為OsLoader。

Vista將以上兩個部分分成兩個獨立的程式檔案,即BootMgr和WinLoad.exe。描述了BootMgr和WinLoad的相互關係和它們在啟動過程中的作用。

與調試NTLDR需要替換check版本的NTLDR不同,在BootMgr和WinLoad內部都已經內建了偵錯引擎,這與核心的做法是一致的。因此,如果要調試BootMgr和WinLoad只要啟動它們內部的偵錯引擎,不需要替換這兩個程式檔案。

啟用BOOTMGR調試的方法是在具有管理員權限的控制台視窗中執行如下命令:
bcdedit /set {bootmgr} bootdebug on
bcdedit /set {bootmgr} debugtype serial
bcdedit /set {bootmgr} debugport 1
bcdedit /set {bootmgr} baudrate 115200

其中後三行是設定調試器與偵錯引擎的串連方式,如果使用1394,那麼應該設定為:

bcdedit /set {bootmgr} debugtype 1394
bcdedit /set {bootmgr} channel 22

做以上設定後,重新啟動系統,BIOS階段過後,螢幕會保持黑色,呈現無法繼續啟動的樣子,事實上,這是BootMgr在等待與調試器建立串連。串連好電纜後,啟動WinDBG調試器,二者就會建立串連,顯示類似下面這樣的資訊:

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\com1
Waiting to reconnect...
BD: Boot Debugger Initialized
Connected to Windows Boot Debugger 6000 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: SRV*d:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows Boot Debugger Kernel Version 6000 UP Free x86 compatible
Product: unknown <ffffffff>, suite: SmallBusiness Enterprise BackOffice CommunicationServer TerminalServer SmallBusinessRestricted EmbeddedNT DataCenter SingleUserTS Personal Blade EmbeddedRestricted SecurityAppliance StorageServer ComputeServer <8000>
Primary image base = 0x00400000 Loaded module list = 0x004ffff8
System Uptime: not available

其中0x00400000是BootMgr模組的基地址。BootMgr的主要代碼都是32位的,只有一小部分16位代碼,負責從韌體那裡接過控制權。另外,值得說明的是,BootMgr是工作在保護模式下的,但它沒有啟用分頁機制,只是使用分頁機制。觀察CR0和CR3寄存器的取值,可以證明這一點:

kd> r cr0
cr0=00000011
kd> r cr3
cr3=00000000

建立串連後,WinDBG會讓BootMgr繼續運行,BootMgr通常會顯示啟動菜單。此時按下Ctrl+Break鍵,那麼BootMgr就會中斷到調試器中,此時可以執行各種核心調試命令,比如:

kd> lm
start    end        module name
00400000 00514000   bootmgr    (pdb symbols)          d:\symbols\bootmgr.pdb\819F5A93195D47E3857ED729B0D341191\bootmgr.pdb
微軟的符號伺服器提供了BootMgr的公開符號檔案,因此只要設定好符號伺服器的路徑,那麼WinDBG就可以自動下載合適的符號檔案。

kd> x bootmgr!*
0042b3fd bootmgr!TpmApiAuthSessCreateOSAP = <no type information>
0044c4da bootmgr!CmpGetIndexElementSize = <no type information>
00452d54 bootmgr!RcConsoleBaudRates = <no type information>
0042f56f bootmgr!OsxmlBrowser::~OsxmlBrowser = <no type information>
00431b10 bootmgr!XslStylesheet::getContents = <no type information>

.......

當然也可以使用棧回溯命令來觀察函數調用情況:

kd> kv
ChildEBP RetAddr  Args to Child              
00061e34 00430c7e 001b6380 00000001 00061e90 bootmgr!DbgBreakPoint 
00061e44 0043024f 00061e8c 001b63b8 00061e88 bootmgr!BlXmlConsole::getInput+0xe  
00061e90 004024c1 00000002 004021f3 00000000 bootmgr!OsxmlBrowser::browse+0xe0  
00061e98 004021f3 00000000 00000000 00061f8f bootmgr!BmDisplayGetBootMenuStatus+0x13 (FPO: [0,0,1])  
00061f10 004017a4 00104f9c 001f4280 00000002 bootmgr!BmDisplayBootMenu+0x174  
00061f6c 00401261 00104f9c 00061f9c 00000002 bootmgr!BmpGetSelectedBootEntry+0xf8 
00061ff0 000209ea 000249a8 7d8b697c 74ff8514 bootmgr!BmMain+0x261  
WARNING: Frame IP not in any known module. Following frames may be wrong.
00000000 f000ff53 f000e2c3 f000ff53 f000ff53 0x209ea
00000000 00000000 f000e2c3 f000ff53 f000ff53 0xf000ff53

通過以上棧回溯可以看到,BmMain是BootMgr的32位代碼入口函數;BmDisplayBootMenu是負責顯示和管理啟動菜單的主要函數。BmMain下方的幾個棧幀應該是16位代碼執行時留下的痕迹。

對BmpGetSelectedBootEntry函數的返回地址00401261設定個斷點後,按F5讓目標系統繼續執行,此時目標系統的菜單可以活動了,選擇引導Vista的一項後,剛才設定的斷點立刻命中,單步跟蹤可以看到BootMgr載入WinLoad的過程,其中的主要函數有:

bootmgr!BmpLaunchBootEntry

bootmgr!ImgArchPcatStartBootApplication

在BootMgr將執行權交給WinLoad之前,它會調用BlBdStop與調試器中斷連線。

如果想繼續調試WinLoad,那麼應該先啟用WinLoad中的偵錯引擎,其命令是:
bcdedit /set {GUID} bootdebug on

WinLoad啟動後,如果它的偵錯引擎已經啟用,那麼偵錯引擎也會與調試器建立串連,並顯示與前面類似的建立連結資訊。以下是WinLoad中的幾個重要函數:

winload!MmArchInitialize

winload!ArchBuildKernelGdt

winload!OslArchpKernelSetupPhase0

winload!OslArchTransferToKernel

其中最後一個負責將執行權轉交給核心。移交執行權之前,WinLoad也會調用BlBdStop函數來切斷偵錯工作階段。如果要繼續調試核心,那麼應該先啟用核心調試,然後在核心階段再與其建立串連。

如果系統是從休眠中恢複,那麼BootMgr會載入WinResume,WinResume中也整合了一個偵錯引擎,因此也可以對其進行跟蹤和調試,例如,下面的棧回溯顯示了WinResume程式初始化的過程:

kd> kPL

ChildEBP RetAddr 

00120ad8 0059da7f winresume!RtlpBreakWithStatusInstruction

00120cf0 0059d97d winresume!vDbgPrintExWithPrefixInternal+0x100

00120d00 0059641a winresume!DbgPrint+0x11

00120d28 00587550 winresume!BlStatusPrint+0x60

00120d6c 00585524 winresume!ConsoleFirmwareOpen+0x64

00120d88 0058373d winresume!ConsoleOpen+0x58

00120da8 00583242 winresume!BlpDeviceOpen+0x13c

00120dc4 0058bd5b winresume!BlDeviceOpen+0x16

00120ed8 0058bcc7 winresume!DsppRegisterConsole+0x56

00120f6c 0058b999 winresume!DsppInitialize+0xfd

00120f78 005950a2 winresume!BlpDisplayInitialize+0x26

00120f94 0057c0c6 winresume!InitializeLibrary+0x176

00120fe8 004444fa winresume!HbMain+0xc6

WARNING: Frame IP not in any known module. Following frames may be wrong.

00000000 f000eef3 0x4444fa

00000000 00000000 0xf000eef3

 

概而言之,在一個安裝好的Vista系統中,已經內建了四個偵錯引擎,分別位於BootMgr、WinLoad、WinResume和NTOSKRNL.exe中,可以將這幾個偵錯引擎同時啟用,也可以根據需要啟用其中的某一個。前三個偵錯引擎是根據位於核心中的核心偵錯引擎(KD)複製出來的,它們使用與KD相容的協議,對調試器(WinDBG)來說,它並不區分對方是真正的KD還是KD的複製。因此在BootMgr中斷偵錯工作階段時,WinDBG提示的資訊和核心退出時的資訊一樣的。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.