本周熱點(diǎn)趨勢(shì)榜雖然新項(xiàng)目不多,但是還是有幾個(gè)不錯(cuò)值得收藏的工具項(xiàng)目,比如用來(lái)做文本轉(zhuǎn)語(yǔ)音的 tortoise-tts 能生成更加貼近真實(shí)人聲的語(yǔ)音,讓 Golang 并發(fā)更出色的 conc,以及通過(guò) Hook 來(lái)管理 React 狀態(tài)的 zustand,以及本周特推調(diào)試 Windows 11 內(nèi)核的 BugChecker。
選項(xiàng)標(biāo)準(zhǔn):新發(fā)布 | 實(shí)用 | 有趣,根據(jù)項(xiàng)目 release 時(shí)間分類,發(fā)布時(shí)間不超過(guò) 14 day 的項(xiàng)目會(huì)標(biāo)注 New,無(wú)該標(biāo)志則說(shuō)明項(xiàng)目 release 超過(guò)半月。由于本文篇幅有限,還有部分項(xiàng)目未能在本文展示,望周知
主語(yǔ)言:C
New BugChecker 是一個(gè)類 SoftICE 的 Windows 11 內(nèi)核調(diào)試器,SoftICE 是一款 Windows 平臺(tái)下的動(dòng)態(tài)脫殼輔助軟件。BugChecker 支持上古的 XP 到現(xiàn)在的 Windows 11 所有版本,只要是 x86 和 x64 架構(gòu)即可。當(dāng)你使用它進(jìn)行調(diào)試工作時(shí),不需要第二臺(tái)機(jī)器同設(shè)備相連接。BugChecker 在 NTOSKRNL 中利用了內(nèi)部和非正式 KD API,而 KD API 允許 WinDbg/KD 可進(jìn)行讀寫虛擬內(nèi)存,讀寫寄存器,在地址中放置斷點(diǎn)等等操作。
部分特性:
GitHub 地址→github.com/vitoplantamura/BugChecker
New 如果你做數(shù)據(jù)分析,一定不能不懂統(tǒng)計(jì)。而本課程則教授你如何進(jìn)行數(shù)據(jù)分析,側(cè)重于科學(xué)模型的學(xué)習(xí)。共計(jì)將有 10 周的學(xué)習(xí)時(shí)間,用近 3 個(gè)月來(lái)學(xué)習(xí)統(tǒng)計(jì)知識(shí)。
GitHub 地址→github.com/rmcelreath/stat_rethinking_2023
本周 star 增長(zhǎng)數(shù):800+,主語(yǔ)言:Jupyter Notebook
還記得上個(gè)月異常火爆的 AI 項(xiàng)目 ChatGPT 么?Open-Assistant 則是開(kāi)源版的 ChatGPT,它在理解你的任務(wù)之余,輸出你想要的聊天結(jié)果。當(dāng)項(xiàng)目并不只是想幫你寫個(gè)郵件、寫簡(jiǎn)歷,希望未來(lái)能更多的個(gè)性化擴(kuò)展,因此秉持小巧的宗旨讓 Open-Assistant 不要那么臃腫。
GitHub 地址→github.com/LAION-AI/Open-Assistant
本周 star 增長(zhǎng)數(shù):700+,主語(yǔ)言:TypeScript
簡(jiǎn)化 flux 原則實(shí)現(xiàn)的小巧、快速、可擴(kuò)展的 React 狀態(tài)管理工具,提供了基于 Hook 的 API 管理狀態(tài),不用樣板或者固有模版。
GitHub 地址→github.com/pmndrs/zustand
本周 star 增長(zhǎng)數(shù):500+,主語(yǔ)言:Golang
更好的并發(fā)結(jié)構(gòu),可以更方便、安全地應(yīng)對(duì)常見(jiàn)任務(wù)。conc 的三大目標(biāo):
下面是項(xiàng)目實(shí)現(xiàn)第一點(diǎn)目標(biāo)的示例:
func main() {
var wg conc.WaitGroup
defer wg.Wait()
startTheThing(&wg)
}
func startTheThing(wg *conc.WaitGroup) {
wg.Go(func() { ... })
}
GitHub 地址→github.com/sourcegraph/conc
本周 star 增長(zhǎng)數(shù):400+,主語(yǔ)言:JavaScript
LinkTree 的開(kāi)源替代品,讓你在某個(gè)社交平臺(tái)上放置你個(gè)人相關(guān)的鏈接。
GitHub 地址→github.com/EddieHubCommunity/LinkFree
本周 star 增長(zhǎng)數(shù):850+,主語(yǔ)言:Python
TorToiSe 是基于以下兩點(diǎn)構(gòu)建的文本到語(yǔ)音應(yīng)用:
你可以用以下方式使用它:
reference_clips=[utils.audio.load_audio(p, 22050) for p in clips_paths]
tts=api.TextToSpeech()
pcm_audio=tts.tts_with_preset("your text here", voice_samples=reference_clips, preset='fast')
GitHub 地址→github.com/neonbjb/tortoise-tts
- END -
針對(duì)進(jìn)程行為的監(jiān)控需求,以往很多安全軟件都是采用的Hook技術(shù)攔截關(guān)鍵的系統(tǒng)調(diào)用,來(lái)實(shí)現(xiàn)對(duì)惡意軟件進(jìn)程創(chuàng)建的攔截。但在x64架構(gòu)下,系統(tǒng)內(nèi)核做了很多安全檢測(cè)措施,特別是類似于KDP這樣的技術(shù),使得Hook方法不再有效。為此OS推出了基于回調(diào)實(shí)現(xiàn)的行為監(jiān)控方案。本文借助IDA逆向分析該技術(shù)的實(shí)現(xiàn)原理并給出了關(guān)鍵數(shù)據(jù)結(jié)構(gòu)及調(diào)用鏈,通過(guò)雙機(jī)內(nèi)核調(diào)試驗(yàn)證了該數(shù)據(jù)結(jié)構(gòu)以及調(diào)用鏈的正確性。
涉及到的內(nèi)容如下:
1、內(nèi)核對(duì)象及內(nèi)核對(duì)象管理;
2、進(jìn)程回調(diào);
3、內(nèi)核調(diào)試;
4、Windbg雙擊調(diào)試;
近年來(lái),各種惡意軟件新變種層出不窮,攻擊方法、手段多種多樣,造成了巨大的經(jīng)濟(jì)損失。作為防守的第一個(gè)環(huán)節(jié)就是能夠識(shí)別出惡意進(jìn)程創(chuàng)建的動(dòng)作,而進(jìn)程創(chuàng)建監(jiān)控技術(shù)是為了能夠讓安全軟件有機(jī)會(huì)攔截到此動(dòng)作的技術(shù)。安全軟件根據(jù)匹配算法判斷是否準(zhǔn)許該進(jìn)程創(chuàng)建,以此達(dá)到保護(hù)用戶數(shù)據(jù)安全的目的。x86架構(gòu)下的實(shí)現(xiàn)方案多為Hook技術(shù),通過(guò)攔截內(nèi)核中進(jìn)程創(chuàng)建的關(guān)鍵API如nt!NtCreateProcess或nt!NtCreateProcessEx,通過(guò)堆棧來(lái)回溯到關(guān)鍵參數(shù),如待創(chuàng)建進(jìn)程的exe全路徑、父進(jìn)程信息,然后根據(jù)獲取到的全路徑檢測(cè)exe磁盤文件,同時(shí)也可以分析進(jìn)程鏈最終確定是否放行該動(dòng)作。但這種技術(shù)方案存在一些缺陷,一方面其破壞了內(nèi)核的完整性,導(dǎo)致系統(tǒng)的穩(wěn)定性下降;另一方面,這些API很多都是未公開(kāi)的,也就意味著需要通過(guò)逆向工程等技術(shù)手段來(lái)分析OS內(nèi)核鏡像文件,定位到關(guān)鍵的API。但如果系統(tǒng)升級(jí)了,該API可能就不存在了,這也導(dǎo)致安全軟件的兼容性特別差;最重要的是各個(gè)安全廠家的實(shí)現(xiàn)方案不一樣,掛鉤的點(diǎn)也不同,很容易出現(xiàn)相互競(jìng)爭(zhēng)的情況,極有可能會(huì)導(dǎo)致BSoD(Blue Screen of Death)。另一種傳統(tǒng)的基于特征碼的攔截方式,也同樣存在類似的問(wèn)題。需要為每個(gè)子版本的系統(tǒng)關(guān)鍵API做逆向分析,取出特征碼,當(dāng)系統(tǒng)更新或者打補(bǔ)丁,則需要再次逆向分析取出特征碼。工作量巨大,效率低下,適配性很低,如果沒(méi)有及時(shí)更新特征碼,很可能會(huì)使得監(jiān)控失效,情況糟糕的時(shí)候會(huì)直接導(dǎo)致BSoD。為此,在x64架構(gòu)下,內(nèi)核一方面為了保護(hù)關(guān)鍵數(shù)據(jù)的完整性,另一方面也為了提高內(nèi)核程序自身的穩(wěn)定性,推出了諸如KDP(Kernel Data Protection)、PG等安全措施,使得傳統(tǒng)的 Hook技術(shù)失效;同時(shí)OS為了規(guī)范化安全相關(guān)信息的獲取,使得安全軟件能夠在內(nèi)核可控的情況下提供安全服務(wù),Windows系統(tǒng)層面提供了一種基于回調(diào)的方式來(lái)通知安全軟件注冊(cè)的內(nèi)核回調(diào)例程。這種方式優(yōu)點(diǎn)是方便高效,可移植性好,穩(wěn)定性高,且各個(gè)安全廠商之間也不會(huì)出現(xiàn)競(jìng)爭(zhēng)的關(guān)系。
本文基于逆向工程及內(nèi)核調(diào)試技術(shù),分析了該技術(shù)的具體實(shí)現(xiàn)及系統(tǒng)額外增加的數(shù)據(jù)檢測(cè)機(jī)制。借助逆向工具IDA靜態(tài)逆向分析了系統(tǒng)關(guān)鍵API的內(nèi)部動(dòng)作及具體的實(shí)現(xiàn),相關(guān)的數(shù)據(jù)結(jié)構(gòu),得到該技術(shù)實(shí)際觸發(fā)的調(diào)用源以及整個(gè)調(diào)用鏈。借助VMWare搭建雙機(jī)調(diào)試環(huán)境,利用Windbg動(dòng)態(tài)調(diào)試系統(tǒng)內(nèi)核,查看系統(tǒng)中所涉及到的關(guān)鍵數(shù)據(jù),并與PCHunter給出的數(shù)據(jù)做對(duì)比分析,驗(yàn)證了分析結(jié)論的正確性。此外還通過(guò)對(duì)調(diào)用鏈中的關(guān)鍵函數(shù)下斷點(diǎn),通過(guò)棧回溯技術(shù),動(dòng)態(tài)觀察了整個(gè)調(diào)用鏈及觸發(fā)時(shí)間。分析得到的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)和系統(tǒng)對(duì)數(shù)據(jù)做的檢測(cè)校驗(yàn)算法可用于檢測(cè)病毒木馬等軟件惡意構(gòu)造的表項(xiàng),且還可以應(yīng)用到安全廠商對(duì)抗惡意代碼時(shí),自動(dòng)構(gòu)造表項(xiàng)來(lái)檢測(cè)系統(tǒng)行為,完全脫離系統(tǒng)提供的注冊(cè)卸載API。
根據(jù)微軟官方技術(shù)文檔MSDN上的說(shuō)明,通過(guò)PsSetCreateProcessNotifyRoutine、PsSetCreateProcessNotifyRoutineEx和PsSetCreateProcessNotifyRoutineEx2這三API來(lái)安裝一個(gè)進(jìn)程創(chuàng)建、退出通知回調(diào)例程,當(dāng)有進(jìn)程創(chuàng)建或者退出時(shí),系統(tǒng)會(huì)回調(diào)參數(shù)中指定的函數(shù)。以PsSetCreateProcessNotifyRoutine為例子,基于IDA逆向分析該API的具體實(shí)現(xiàn)。如圖1所示,由圖可知,該API內(nèi)部?jī)H僅是簡(jiǎn)單的調(diào)用另一個(gè)函數(shù),其自身僅僅是一個(gè)stub,具體的實(shí)現(xiàn)在PspSetCreateProcessNotifyRoutine中,此函數(shù)的安裝回調(diào)例程的關(guān)鍵實(shí)現(xiàn)如圖所示。
調(diào)用ExAllocateCallBack,創(chuàng)建出了一個(gè)回調(diào)對(duì)象,并將pNotifyRoutine和bRemovel作為參數(shù)傳入,以初始化該回調(diào)對(duì)象,代碼如圖所示;其中pNotifyRoutine即是需要被回調(diào)的函數(shù)例程,此處的bRemovel為false,表示當(dāng)前是安裝回調(diào)例程。
緊接著調(diào)用ExCompareExchangeCallBack將初始化好的CallBack對(duì)象添加到PspCreateProcessNotifyRoutine所維護(hù)的全局?jǐn)?shù)組中。值得注意的是,ExCompareExchangeCallBack中在安裝回調(diào)例程時(shí),對(duì)回調(diào)例程有一個(gè)特殊的操作如圖所示。
與0x0F做了或操作,等價(jià)于將低4位全部置1;若ExCompareExchangeCallBack執(zhí)行失敗,則接著下一輪循環(huán)繼續(xù)執(zhí)行。由圖2中第66行代碼可知,循環(huán)的最大次數(shù)是0x40次。如果一直失敗,可調(diào)用ExFreePoolWithTag釋放掉pCallBack所占用的內(nèi)存,且返回0xC000000D錯(cuò)誤碼。
然后根據(jù)v3的值判斷是通過(guò)上述三個(gè)API中的哪個(gè)安裝的回調(diào),來(lái)更新相應(yīng)的全局變量。其中PspCreateProcessNotifyRoutineExCount和PspCreateProcessNotifyRoutineCount分別記錄當(dāng)前通過(guò)PsSetCreateProcessNotifyRoutineEx和PsSetCreateProcessNotifyRoutine安裝回調(diào)例程的個(gè)數(shù)。PspNotifyEnableMask用以表征當(dāng)前數(shù)組中是否安裝了回調(diào)例程,該值在系統(tǒng)遍歷回調(diào)數(shù)組執(zhí)行回調(diào)例程時(shí),用以判斷數(shù)組是否為空,加快程序的執(zhí)行效率。
除了能夠安裝回調(diào)例程,這三個(gè)API也能卸載指定的回調(diào)例程。以PsSetCreateProcessNotifyRoutine為例,分析其實(shí)現(xiàn)的關(guān)鍵部分,如圖所示。
通過(guò)一個(gè)while循環(huán)遍歷PspCreateProcessNotifyRoutine數(shù)組,調(diào)用ExReferenceCallBackBlock取出數(shù)組中的每一項(xiàng),該API內(nèi)部會(huì)做一些檢驗(yàn)動(dòng)作且對(duì)返回的數(shù)據(jù)也做了特殊處理,如圖所示。圖6中*pCallBackObj即是取出回調(diào)對(duì)象中的回調(diào)例程的函數(shù)地址,通過(guò)判斷其低4位是否為1來(lái)做一些數(shù)據(jù)的校驗(yàn),如17行所示。系統(tǒng)做這個(gè)處理也是起到保護(hù)作用,防止惡意構(gòu)造數(shù)據(jù)填入表中,劫持正常的系統(tǒng)調(diào)用流程。此外,圖中第33行處的代碼,在將回調(diào)例程返回給父調(diào)用時(shí),也將回調(diào)例程的低4位全部清零,否則返回的地址是錯(cuò)誤的,調(diào)用立馬觸發(fā)CPU異常。
ExReferenceCallBackBlock成功返回后,調(diào)用ExGetCallBackBlockRoutine從返回的回調(diào)對(duì)象中取出回調(diào)例程,并判斷取出的是否為當(dāng)前指定需要卸載的項(xiàng),如果是則調(diào)用ExDereferenceCallBackBlock遞減引用計(jì)數(shù),接著調(diào)用ExFreePoolWithTag釋放掉Callback所占用的內(nèi)存。期間也會(huì)更新PspCreateProcessNotifyRoutineExCount或PspCreateProcessNotifyRoutineCount的值。根據(jù)源碼還可以得知,該數(shù)組總計(jì)64項(xiàng),也即只能安裝64個(gè)回調(diào)例程。如果遍歷完數(shù)組的64項(xiàng)依舊沒(méi)有找到,則返回0xC000007A錯(cuò)誤碼。
回調(diào)例程安裝完之后,如果有新的進(jìn)程創(chuàng)建或退出,內(nèi)核則便會(huì)遍歷該數(shù)組來(lái)執(zhí)行其中安裝的每一項(xiàng)回調(diào)例程。通過(guò)IDA的交叉引用功能,可分析出內(nèi)核其他地方對(duì)PspCreateProcessNotifyRoutine的交叉引用,如圖所示,
共計(jì)5個(gè)地方涉及到此變量。其中PspCallProcessNotifyRoutines是直接調(diào)用回調(diào)例程的函數(shù),該函數(shù)的關(guān)鍵部分如圖所示。
通過(guò)while循環(huán),遍歷PspCreateProcessNotifyRoutine數(shù)組中安裝的所有回調(diào)例程,依次執(zhí)行。PspNotifyEnableMask & 2的操作即為判斷當(dāng)前數(shù)組中是否安裝有回調(diào)例程,加快程序的執(zhí)行效率,這個(gè)變量的值在PsSetCreateProcessNotifyRoutine中安裝回調(diào)例程時(shí)設(shè)置。bRemove & 2這個(gè)if分支,是用來(lái)判斷當(dāng)前的回調(diào)例程是通過(guò)PsSetCreateProcessNotifyRoutine還是PsSetCreateProcessNotifyRoutineEx安裝,因?yàn)檫@兩個(gè)API安裝的回調(diào)例程的原型不同,在實(shí)際調(diào)用時(shí)傳入的參數(shù)也不同。兩者的回調(diào)例程原分別為:void PcreateProcessNotifyRoutine(HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create)和void PcreateProcessNotifyRoutineEx(PEPROCESS Process,HANDLE ProcessId,PPS_CREATE_NOTIFY_INFO CreateInfo)。此外,圖8中IDA給出的偽C代碼RoutineFun((unsigned __int64)RoutineFun)明顯不對(duì),因?yàn)榛卣{(diào)例程的參數(shù)個(gè)數(shù)是3個(gè),而IDA分析出的參數(shù)只有1個(gè),顯然有問(wèn)題。直接看下反匯編代碼即可得知,如圖所示,
根據(jù)x64下的調(diào)用約定可知,函數(shù)的前4個(gè)參數(shù)是通過(guò)rcx、rdx、r8和r9這四個(gè)寄存器傳遞,圖給出的正是回調(diào)例程的前三個(gè)參數(shù),_guard_dispatch_icall內(nèi)部會(huì)直接取rax的值調(diào)用過(guò)去,而rax的值正是ExGetCallBackBlockRoutine調(diào)用返回的回調(diào)例程函數(shù)地址。
上圖中的第二個(gè)涉及到PspCreateProcessNotifyRoutine數(shù)組的是PspEnumerateCallback函數(shù),該函數(shù)是系統(tǒng)內(nèi)部函數(shù),沒(méi)有導(dǎo)出,其具體實(shí)現(xiàn)如圖所示。
該函數(shù)根據(jù)dwEnumType來(lái)判斷想要枚舉的是哪個(gè)數(shù)組,由代碼分析可知,系統(tǒng)內(nèi)核維護(hù)了三個(gè)回調(diào)相關(guān)的數(shù)組,分別為鏡像加載回調(diào)數(shù)組,進(jìn)程創(chuàng)建退出回調(diào)數(shù)組,線程創(chuàng)建退出數(shù)組。類似之前的函數(shù)校驗(yàn),這里也檢測(cè)了索引是否超過(guò)0x40,超過(guò)了則返回0,以示失敗。
上節(jié)分析了回調(diào)例程的直接調(diào)用上級(jí)函數(shù),本節(jié)分析整個(gè)調(diào)用鏈,主要分析調(diào)用源及調(diào)用過(guò)程中涉及到的關(guān)鍵函數(shù)。根據(jù)IDA給出的交叉引用圖如圖所示。
涉及到的函數(shù)調(diào)用非常多,很多不相關(guān)的也被包含進(jìn)來(lái),不便于分析。經(jīng)手動(dòng)分析整理后的調(diào)用鏈,其鏈路中的關(guān)鍵API如圖所示。
虛線以上部分為用戶態(tài)程序,虛線以下為內(nèi)核態(tài)程序,紅色標(biāo)注的都是標(biāo)準(zhǔn)導(dǎo)出的API。根據(jù)圖12可知,當(dāng)用戶態(tài)進(jìn)程調(diào)用RtlCreateUserProcess、RtlCreateUserProcesersEx或RtlExitUserProcess時(shí),內(nèi)核都會(huì)去遍歷PspCreateProcessNotifyRoutine數(shù)組,依次執(zhí)行回調(diào)例程,通知給驅(qū)動(dòng)程序做相應(yīng)的處理。驅(qū)動(dòng)接管之后,可以做安全校驗(yàn)處理,分析進(jìn)程的父進(jìn)程或者進(jìn)一步分析進(jìn)程鏈,此外還可以對(duì)即將被拉起的子進(jìn)程做特征碼匹配,PE指紋識(shí)別,導(dǎo)入表檢測(cè)等防御手段。這種方式不需要去Hook任何API,也無(wú)需做特征碼定位等重復(fù)繁瑣的工作,完全基于系統(tǒng)提供的回調(diào)機(jī)制,且在Windows系統(tǒng)中都可以無(wú)縫銜接。且各個(gè)安全廠家之間也不存在相互競(jìng)爭(zhēng),大大縮小了系統(tǒng)藍(lán)屏的風(fēng)險(xiǎn)。圖12中NtCreateUserProcess調(diào)用PspInsertThread的原因是創(chuàng)建進(jìn)程的API內(nèi)部會(huì)創(chuàng)建該進(jìn)程的主線程。將遍歷回調(diào)例程數(shù)組的工作統(tǒng)一到PspInsertThread中,由其去調(diào)用下層的PspCallProcessNotifyRoutines更為合理。
實(shí)驗(yàn)環(huán)境如表1所示,借助于VMWare進(jìn)行雙機(jī)調(diào)試。
Guest OS Build 10.0.16299.125
Host OS Build 10.0.17134.885
Windbg版本 10.0.17134.1
VMWare 14.1.1 build-7528167
PCHunter V1.56
在Windbg中觀察PspCreateProcessNotifyRoutine數(shù)組,共計(jì)14項(xiàng)有效數(shù)據(jù),如下所示;
1: kd> dd PspCreateProcessNotifyRoutineCount l1
fffff802`151f4e78 00000009
1: kd> dd PspCreateProcessNotifyRoutineExCount l1
fffff802`151f4e7c 00000005
1: kd> dq PspCreateProcessNotifyRoutine l40
fffff802`14da2a80 ffffcc8b`d884b9bf ffffcc8b`d8d9c96f
fffff802`14da2a90 ffffcc8b`d939975f ffffcc8b`da00044f
fffff802`14da2aa0 ffffcc8b`d9bd382f ffffcc8b`da41e8df
fffff802`14da2ab0 ffffcc8b`da53815f ffffcc8b`da5ca8bf
fffff802`14da2ac0 ffffcc8b`dac5178f ffffcc8b`dbef624f
fffff802`14da2ad0 ffffcc8b`dce333af ffffcc8b`dcec67df
fffff802`14da2ae0 ffffcc8b`dc735def ffffcc8b`dcabd32f
拆解第一項(xiàng),尋找其所對(duì)應(yīng)的回調(diào)例程,如下:
1: kd> dq ffffcc8b`d884b9b0 l3
ffffcc8b`d884b9b0 00000000`00000020 fffff802`13fd6268
ffffcc8b`d884b9c0 00000000`00000000
由此可知,安裝的回調(diào)例程起始地址為fffff802`13fd6268,且還可知道Remove為0,即這個(gè)是已經(jīng)安裝的。尋找該回調(diào)例程對(duì)應(yīng)的驅(qū)動(dòng)模塊,如下:
1: kd> u fffff802`13fd6268
360qpesv64+0x26268:
fffff802`13fd6268 mov qword ptr [rsp+08h],rbx
fffff802`13fd626d mov qword ptr [rsp+10h],rbp
fffff802`13fd6272 mov qword ptr [rsp+18h],rsi
fffff802`13fd6277 push rdi
1: kd> lmvm 360qpesv64
start end module name
fffff802`13fb0000 fffff802`14002000 360qpesv64
Loaded symbol image file: 360qpesv64.sys
Image path: 360qpesv64.sys
Image name: 360qpesv64.sys
Timestamp: Wed May 27 20:13:22 2020 (5ECF2C52)
CheckSum: 00054A2A
ImageSize: 00052000
可知該回調(diào)例程是360官方提供。借助PCHunter來(lái)對(duì)比下,其給出的數(shù)據(jù)如圖所示,
以表項(xiàng)的第14項(xiàng)為例,內(nèi)容如下,
1: kd> dq ffffcc8b`dcabd320 l3
ffffcc8b`dcabd320 00000000`00000020 fffff802`13d795b4
ffffcc8b`dcabd330 00000000`00000006
1: kd> bp fffff802`13d795b4
1: kd> g
斷點(diǎn)命中,查看父進(jìn)程相關(guān)信息,如下,
Breakpoint 0 hit
fffff802`13d795b4 48895c2408 mov qword ptr [rsp+8],rbx
1: kd> dt _EPROCESS @$proc -yn ImageFileName
nt!_EPROCESS
+0x450 ImageFileName : [15] "svchost.exe"
由此可知,是svchost.exe這個(gè)父進(jìn)程創(chuàng)建或者銷毀了一個(gè)子進(jìn)程,更具體的信息如下分析;查看下當(dāng)前的上下文環(huán)境;
1: kd> r
rax=fffff80213d795b4 rbx=ffffcb8050526c80 rcx=ffffcc8bdd67e080
rdx=0000000000001f28 rsi=000000000000000d rdi=ffffcc8bdd67e080
rip=fffff80213d795b4 rsp=ffffcb8050526c38 rbp=ffffcb8050526ca9
r8=ffffcb8050526c80 r9=ffffcc8bdc735de0 r10=ffff9401cdcc2760
r11=0000000000000000 r12=0000000000000001 r13=0000000000000000
r14=ffffcc8bdcabd320 r15=fffff80214da2ae8
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000246
根據(jù)x64的調(diào)用約定可知,rcx寄存器中存儲(chǔ)的是EPROCESS對(duì)象指針,該對(duì)象存儲(chǔ)的是即將被創(chuàng)建的子進(jìn)程的相關(guān)信息,可以獲取到的作為身份識(shí)別或者安全檢測(cè)的關(guān)鍵信息如下:
1: kd> dt _EPROCESS ffffcc8bdd67e080 -yn ImageFile
ntdll!_EPROCESS
+0x448 ImageFilePointer : 0xffffcc8b`dc97c5c0 _FILE_OBJECT
+0x450 ImageFileName : [15] "UpdateAssistan"
1: kd> dt 0xffffcc8b`dc97c5c0 _FILE_OBJECT -yn FileName
ntdll!_FILE_OBJECT
+0x058 FileName : _UNICODE_STRING "\Windows\UpdateAssistant\UpdateAssistant.exe"
1: kd> .process /p ffffcc8bdd67e080; !peb 186ef07000
Implicit process is now ffffcc8b`dd67e080
.cache forcedecodeuser done
PEB at 000000186ef07000
CurrentDirectory: 'C:\Windows\system32\'
WindowTitle: 'C:\Windows\UpdateAssistant\UpdateAssistant.exe'
ImageFile: 'C:\Windows\UpdateAssistant\UpdateAssistant.exe'
CommandLine: 'C:\Windows\UpdateAssistant\UpdateAssistant.exe /ClientID Win10Upgrade:VNL:NHV19:{} /CalendarRun'
可以獲取到該進(jìn)程的EXE路徑,創(chuàng)建時(shí)的命令行參數(shù),父進(jìn)程的PID等信息,這些足以用于安全軟件的檢測(cè)。
父進(jìn)程的完整調(diào)用棧如下,
1: kd> k
# Child-SP RetAddr Call Site
00 ffffcb80`50526c38 fffff802`14ef4ae5 0xfffff802`13d795b4
01 ffffcb80`50526c40 fffff802`14ef752c nt!PspCallProcessNotifyRoutines+0x249
02 ffffcb80`50526d10 fffff802`14f2797b nt!PspInsertThread+0x5a4
03 ffffcb80`50526dd0 fffff802`14b79553 nt!NtCreateUserProcess+0x9c7
04 ffffcb80`50527a10 00007ffe`547d1654 nt!KiSystemServiceCopyEnd+0x13
05 0000002f`4b67d258 00007ffe`50b406df ntdll!NtCreateUserProcess+0x14
06 0000002f`4b67d260 00007ffe`50b3d013 KERNELBASE!CreateProcessInternalW+0x1b3f
07 0000002f`4b67dec0 00007ffe`5216ee0f KERNELBASE!CreateProcessAsUserW+0x63
08 0000002f`4b67df30 00007ffe`4ce0a136 KERNEL32!CreateProcessAsUserWStub+0x5f
09 0000002f`4b67dfa0 00007ffe`4ce0bdd9 UBPM!UbpmpLaunchAction+0xb36
0a 0000002f`4b67e280 00007ffe`4ce08ee0 UBPM!UbpmLaunchTaskExe+0x279
0b 0000002f`4b67e490 00007ffe`4ce10a86 UBPM!UbpmpLaunchOneTask+0x6c0
0c 0000002f`4b67e8f0 00007ffe`4ce0b8bc UBPM!UbpmpHandleGroupSid+0x236
0d 0000002f`4b67ea10 00007ffe`4ce0b78b UBPM!UbpmpLaunchExeAction+0xec
0e 0000002f`4b67eaf0 00007ffe`4ce0b5a3 UBPM!UbpmpTakeAction+0xeb
0f 0000002f`4b67eb50 00007ffe`4ce0b193 UBPM!UbpmpPerformTriggerActions+0x293
10 0000002f`4b67eca0 00007ffe`4ce1316c UBPM!UbpmpHandleTriggerArrived+0x563
11 0000002f`4b67ef50 00007ffe`508c32d0 UBPM!UbpmpRepetitionArrived+0x1c
12 0000002f`4b67ef90 00007ffe`508c3033 EventAggregation!EaiSignalAggregateEvent+0x16c
13 0000002f`4b67f060 00007ffe`508c27aa EventAggregation!EaiSignalCallback+0xe7
14 0000002f`4b67f140 00007ffe`508c253e EventAggregation!EaiProcessNotification+0x1aa
15 0000002f`4b67f270 00007ffe`508caef8 EventAggregation!WnfEventCallback+0x506
16 0000002f`4b67f3a0 00007ffe`5476769f EventAggregation!AggregateEventWnfCallback+0x38
17 0000002f`4b67f3f0 00007ffe`54767a51 ntdll!RtlpWnfWalkUserSubscriptionList+0x29b
18 0000002f`4b67f4e0 00007ffe`5476b510 ntdll!RtlpWnfProcessCurrentDescriptor+0x105
19 0000002f`4b67f560 00007ffe`54766b59 ntdll!RtlpWnfNotificationThread+0x80
1a 0000002f`4b67f5c0 00007ffe`54764b70 ntdll!TppExecuteWaitCallback+0xe1
1b 0000002f`4b67f600 00007ffe`52171fe4 ntdll!TppWorkerThread+0x8d0
1c 0000002f`4b67f990 00007ffe`5479ef91 KERNEL32!BaseThreadInitThunk+0x14
1d 0000002f`4b67f9c0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
由于前四個(gè)參數(shù)是通過(guò)的寄存器傳遞的,所以無(wú)法直接通過(guò)棧來(lái)回溯到參數(shù),但可以通過(guò)手動(dòng)方式分析得到。分析ntdll!NtCreateUserProcess的調(diào)用父函數(shù),其返回地址處的匯編代碼如下所示:
1: kd> ub 00007ffe`50b406df
KERNELBASE!CreateProcessInternalW+0x1b11:
00007ffe`50b406b1 488b842440040000 mov rax,qword ptr [rsp+440h]
00007ffe`50b406b9 4889442420 mov qword ptr [rsp+20h],rax
00007ffe`50b406be b800000002 mov eax,2000000h
00007ffe`50b406c3 448bc8 mov r9d,eax
00007ffe`50b406c6 448bc0 mov r8d,eax
00007ffe`50b406c9 488d942448010000 lea rdx,[rsp+148h]
00007ffe`50b406d1 488d8c24e0000000 lea rcx,[rsp+0E0h]
00007ffe`50b406d9 ff1521901600 call qword ptr [KERNELBASE!_imp_NtCreateUserProcess (00007ffe`50ca9700)]
可知,NtCreateUserProcess第一個(gè)參數(shù)和第二個(gè)參數(shù)再rsp+0xE0和rsp+0x148處;查看該處的數(shù)據(jù)如下:
1: kd> dpu 0000002f`4b67d260+E0 0000002f`4b67d260+148
0000002f`4b67d340 00000000`00000000
0000002f`4b67d348 00000000`00000004
0000002f`4b67d350 00000100`00000000
0000002f`4b67d358 00000000`00000020
0000002f`4b67d360 000001f2`d9b87cc0 "C:\Windows\UpdateAssistant\UpdateAssistant.exe"
0000002f`4b67d368 00000000`00000000
0000002f`4b67d370 00000000`00000000
0000002f`4b67d378 0000002f`00000000
0000002f`4b67d380 000001f2`d8d43580 "C:\Windows\UpdateAssistant\UpdateAssistant.exe /ClientI"
0000002f`4b67d388 00000000`00000000
0000002f`4b67d390 00000000`00008664
0000002f`4b67d398 000001f2`d9d73c40 "ALLUSERSPROFILE=C:\ProgramData"
0000002f`4b67d3a0 00000000`00000000
0000002f`4b67d3a8 00000000`00000000
由此可知,svchost拉起的子進(jìn)程為UpdateAssistant.exe,與之前分析得到的參數(shù)也相吻合。從調(diào)用棧可知,是在svchost創(chuàng)建子進(jìn)程UpdateAssistant.exe時(shí)遍歷的回調(diào)例程,通知給驅(qū)動(dòng)軟件做相應(yīng)的處理。
本文詳細(xì)地分析了系統(tǒng)實(shí)現(xiàn)進(jìn)程回調(diào)安全機(jī)制的內(nèi)部原理,借助IDA工具逆向系統(tǒng)鏡像文件,分析了實(shí)現(xiàn)的關(guān)鍵代碼部分,得到了關(guān)鍵數(shù)據(jù)結(jié)構(gòu)及系統(tǒng)額外做的數(shù)據(jù)檢測(cè)校驗(yàn)算法。對(duì)關(guān)鍵全局變量的作用也做了詳細(xì)解釋。此外,通過(guò)逆向分析,給出了整個(gè)機(jī)制的調(diào)用源與調(diào)用鏈。最后基于雙機(jī)調(diào)試環(huán)境,動(dòng)態(tài)查看內(nèi)核中維護(hù)的進(jìn)程回調(diào)例程表,并且下斷點(diǎn)實(shí)際動(dòng)態(tài)調(diào)試了整個(gè)過(guò)程。對(duì)于驅(qū)動(dòng)開(kāi)發(fā),內(nèi)核安全相關(guān)方面的研究工作者提供了該技術(shù)實(shí)現(xiàn)原理與機(jī)制。基于得到的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)和系統(tǒng)數(shù)據(jù)檢驗(yàn)保護(hù)算法,可以解密關(guān)鍵字段后檢測(cè)表項(xiàng)中的惡意代碼,也可以用于安全廠商在對(duì)抗過(guò)程中,完全脫離系統(tǒng)提供的API手工構(gòu)建表項(xiàng),達(dá)到監(jiān)控系統(tǒng)行為的目的。