Windows有三種語法:multi , scsi 和signature。scsi語法則是當(dāng)磁盤控制器不支持INT 0x13指令時(shí)使用的,此時(shí),NTLDR在確定了引導(dǎo)項(xiàng)后,會(huì)從根目錄加載一個(gè)名為NtBootdd.sys的文件,將其綁定到OSLoader上,OSLoader中包含的只讀NTFS/FAT32代碼會(huì)使用該驅(qū)動(dòng)來讀寫磁盤,實(shí)現(xiàn)Windows內(nèi)核文件(ntoskrnl.exe)、硬件抽象層文件(hal.dll)和BOOT驅(qū)動(dòng)文件的加載。
NtBootdd.sys要完成的工作就是:
1、不導(dǎo)出任何函數(shù),這樣就不會(huì)影響OSLoader的引入表
2、在初始化函數(shù)中完成相關(guān)的鉤子例程及處理例程,然后返回失敗,讓系統(tǒng)仍然使用INT 0x13來讀寫磁盤
3、需要注意的是,我們需要在初始化例程中將ntldr中已讀入的boot.ini進(jìn)行修改,將scsi語法重新改回multi語法,否則在后面的引導(dǎo)過程中ntldr會(huì)認(rèn)為我們使用了錯(cuò)誤的引導(dǎo)語法,導(dǎo)致系統(tǒng)無法啟動(dòng)。讀入的boot.ini是保存在OSLoader的數(shù)據(jù)段的一個(gè)全局變量中的,我們掃描整個(gè)OSLoader鏡像,即可找到需要修改的數(shù)據(jù)。
4、為了劫持內(nèi)核,Tophet.a進(jìn)行了這樣的工作:因?yàn)檎{(diào)用 NtBootdd.sys的初始化例程的函數(shù)是AEInitializeIo,那么我們?cè)诔跏蓟讨型ㄟ^堆棧就可以輕松找到該函數(shù) call DriverEntry的下一條指令位置,然后我們從這條指令向上搜索,就可以準(zhǔn)確穩(wěn)定地找到BlLoadImage函數(shù)的地址,OSLoader正是通過這個(gè)函數(shù)來加載包括Windows內(nèi)核文件、HAL和boot驅(qū)動(dòng)的模塊的,我們掛鉤該函數(shù),就可以準(zhǔn)確地知道Windows內(nèi)核文件加載的瞬間,并對(duì)其內(nèi)存鏡像進(jìn)行修改和劫持。
Tophet.a的NtBootdd.sys的DriverEntry函數(shù)