NFwin10藍屏怎么解決?很多玩家在使用win10系統玩DNF的時候會出現藍屏的情況,對此網絡有很多的解決方式,以下的方式據悉有用,那么到底DNFwin10藍屏怎么處理,來看下網友的方法分享。
網友原話是:“找一份游戲根目錄下較早版本的vsddrvdll.dll替換游戲里的較新版本的。”
這位網友對于藍屏進行了分析,期間嘗試過恢復備份的系統(懷疑驅動沖突)重新安裝系統,重新安裝wegame,在重新安裝游戲時,第一次啟動沒有藍屏(其實第一次就是嘗試這個,但一次不能說明問題當時也沒有太在意),之后繼續100%藍,就懷疑是有些游戲核心文件出的問題。
于是再次安裝了游戲在其他目錄,和之前運行過的目錄進行對比,我才不會說運行了一下就憑白多了近200M的東西,比較之后發現多出的文件多為些日志緩存(通常這些即使出了問題也不會對游戲本身造成惡劣影響),還有臭名昭著的tp相關的幾個驅動文件,比如TesMon.sys tesrsdt.sys 是的你沒看錯,這些文件不但在系統驅動目錄里有,這里也有,而且是運行后才出現的,剛安好的游戲是沒有這些的,但又因為之前嘗試別的解決辦法時已經試過把那幾個系統目錄下的sys文件改寫,并沒有用,所以感覺不是這里的問題。最后就發現了這個vsddrvdll.dll 文件版本不同,經過多次嘗試后可以確定是它的問題了,近20次的嘗試100%復現。
通過種種的試驗,這位網友對于DNFwin10藍屏怎么解決提出了自己的方法,且根據回帖似乎還是很有用的,小伙伴們不妨一試。
【神奇黑科技,游戲不用下載點開即玩,微信關注太平洋游戲網(pcgames_com_cn),《傳奇》《口袋妖怪》《全民捕魚贏話費》等著你~】
0.背景
在build 2016大會上,微軟宣布windows10 中將原生支持bash,并且號稱在windows中加入了一個Linux子系統(Windows Subsystem for Linux),而不是一個虛擬機。而后在發布的win10 14316(x64)更新上就開啟了bash功能,但32位版本沒有bash。
筆者隨即下載了14316想體驗一下windows上執行bash命令,并且想了解這個Linux子系統機制的實現。
一.介紹
首先打開system32\bash.exe后,隨便輸入一個ls命令,通過procmon發現有進程訪問了C:\Users\xxxxx\AppData\Local\lxss\rootfs\bin\ls文件。
隨即發現了linux根目錄掛載在C:\Users\xxxxx\AppData\Local\lxss\rootfs,可以看到目錄結構和ubuntu基本一致。
反過來看到訪問ls這個elf文件的進程比較奇怪,procmon無法顯示進程名字,而且掛上調試器還會發現這個進程對象內不僅沒有名字,也沒有section,peb等信息。
二. Pico Process
這種沒有名字的進程稱為pico process,也就是ELF的宿主進程。關于picoprocess介紹: http://research.microsoft.com/en-us/projects/drawbridge/#Picoprocess。簡單來說Pico Process是一種Container,實現drawbridge沙盒技術的一種機制,并且之前被微軟斃掉的“Project Astoria”項目也用到了lxcore+picoprocess這種技術。現在微軟把這種技術應用到了win10 linux子系統當中。
Picoprocess 統一由 PspCreatePicoProcess 創建,而 PspCreatePicoProcess 里面主要的工作是由PsCreateMinimalProcess實現的,PsCreateMinimalProcess這個函數的名字像是用于創建一個精簡進程,實際上確實也是這樣。PsCreateMinimalProcess里面會調用PspAllocateProcess,PspAllocateProcess函數本身的功能是用來創建EPROCESS對象,進程地址空間,PEB等信息。
PspAllocateProcess函數的原型大致如下:
NTSTATUS PspAllocateProcess( void *ParentProcess, int PreviousMode, void *ObjectAttributes, char Protection, char SignatureLevel, char SectionSignatureLevel, void *SectionObject, void *TokenObject, int Flags, void *UserProcessParameters, int bSystemToken, OUT int a12, OUT void *Process)
而PsCreateMinimalProcess中調用PspAllocateProcess的參數如下圖所示,可以發現ObjectAttributes,SectionObject,等都為NULL,這也論證了之前我們看到picoprocess沒有進程名,沒有用戶空間信息等現象。
再回來看PspCreatePicoProcess這個函數的調用棧,可以看到ring3的調用是由PsPicoSystemCallDispatch這個函數分發到lxcore驅動中的,這里需要引出另一個東西:PicoProvider
三. PicoProvider
Nt導出了一個函數PsRegisterPicoProvider提供注冊一個PicoProvider,在目前只有lxss.sys會調用這個接口,lxss.sys和lxcore.sys這兩個驅動負責實現linux子系統的大部分功能。Lxss.sys作為一個boot start driver會在初始化時調用lxcore.sys->PsRegisterPicoProvider,而且PsRegisterPicoProvider在系統啟動后只允許調用一次,在所有boot driver初始化完畢后,nt會把PspPicoRegistrationDisabled設置為TRUE,從而禁止以后所有的PsRegisterPicoProvider調用,也就是說當前系統只允許存在一個Provider。
注意因為目前最新的符號只是14295,14316的符號微軟還沒有放出,但lxss.sys相關的文件在14295就存在了并且大部分功能nt中已經使用了,只是上層機制并沒有實現。所以筆者使用14295的符號配合14316文件來分析lxss內核相關機制,如有不正確歡迎指出。
PsRegisterPicoProvider的原型大致如下:
NTSTATUS PsRegisterPicoProvider(
IN PICO_INTERFACE *PicoInterface, OUT PSP_INTERFACE *PspInterface );struct PICO_INTERFACE{ __int64 cbSize; //目前只支持0x48,不排除以后會有EX PVOID PicoSystemCallDispatch; PVOID PicoThreadExit; PVOID PicoProcessExit; PVOID PicoDispatchException; PVOID PicoProcessTerminate; PVOID PicoWalkUserStack; PVOID LxpProtectedRanges; PVOID PicoGetAllocatedProcessImageName;}struct PSP_INTERFACE{ __int64 cbSize; //目前只支持0x60 PVOID PspCreatePicoProcess; PVOID PspCreatePicoThread; PVOID PspGetPicoProcessContext; PVOID PspGetPicoThreadContext; PVOID PspGetContextThreadInternal; PVOID PspSetContextThreadInternal; PVOID PspTerminateThreadByPointer; PVOID PsResumeThread; PVOID PspSetPicoThreadDescriptorBase; PVOID PsSuspendThread; PVOID PspTerminatePicoProcess;}
Lxss通過PsRegisterPicoProvider向NT提供一組PICO操作接口,以獲取系統調用分發、進線程退出、異常訪問等消息、自己進行處理。并且會獲取NT的一組進線程操作接口,用于對nt進線程進行操作。其中有一個PICO接口PicoGetAllocatedProcessImageName,比較感興趣,因為之前提到了我們用procmon觀察pico process是沒有名字的,并且內核調試器也無法看到名字,如果能知道pico process對應哪個ELF會對分析有很大幫助。
通過分析,Pico Provider把這個接口提供給NT,在NtQuerySystemInformation獲取進程名相關信息的時候,正常情況下會從EPROCESS->SeAuditProcessCreationInfo中取進程名信息,但如果發現這是個pico process則調用PicoGetAllocatedProcessImageName獲取。所以邏輯上說NT已經做了對pico process的兼容,但為什么procmon還是無法獲取進程名?果然筆者自己試了下用最簡單的CreateToolhelp32Snapshot是可以輕松枚舉到elf進程相關的名字。
所以procmon可能并不是用標準接口來獲取進程名字的。
但pico process的進程名保存在哪里呢?通過分析這個函數,發現pico process對應的ELF路徑信息保存在EPROCESS->PicoContext +0x15b0處,而PicoContext是在創建pico process的時候,由PspCreatePicoProcess設置的,保存了pico process的各種信息。用一個簡單的腳本,用來遍歷當前系統的pico process的名字信息,這是當我使用bash執行一個wget下載任務的時候的pico進程信息:
繼續說回PsRegisterPicoProvider,PICO Interface中的PicoSystemCallDispatch也比較重要。負責分發pico process傳來的系統調用,用于picoprocess和provider進行通信。在pico process的一次系統調用中,當ring3代碼sysenter后,內核入口為KiSystemCall64,如果當前thread->_DISPATCHER_HEADER中設置了Minimal標志位,則KiSystemCall64會調用nt!PsPicoSystemCallDispatch進行pico相關分發,不走原始的sdt分發表。Lxcore!LxpSyscalls保存這個分發表的地址。
這是打印的部分分發函數,類似SDT表一樣,仍然是通過rax作為id分發,但參數的傳遞和走sdt的有一些不一樣。使用rdi,rsi,rdx,r10傳遞參數。
(分析過程中還發現14316后多了一張新的SDT表KeServiceDescriptorTableFilter,當一個線程flag被設置為RestrictedGuiThread時,則使用KeServiceDescriptorTableFilter這張表,這張表會限制很多native api的調用,主要限制edge等進程調用win32k等函數,做更嚴格的安全性隔離,不過目前KeServiceDescriptorTableFilter的內容還是和普通的SDT一樣,應該還未使用)
我們來看下lxcore提供給Linxu子系統一些功能的實現。比如當我們使用bash創建一個ELF進程的時候,lxcore的調用流程大概是:LxpSyscall_FORK->LxpThreadGroupFork ->LxpThreadGroupCreate –>PspCreatePicoProcess。PspCreatePicoProcess在之前PsRegisterPicoProvider的時候已經從NT中獲取了,所以lxsscore可以操作nt的進線程,但對于沒有向NT獲取響應的接口的其他功能呢?
對于文件系統的操作則直接調用相應的nt api,而并非直接和文件系統打交道,比如當使用rm命令刪除一個文件的時候,調用流程:LxpSyscall_UNLINK->LxpUnlinkHelper->VfsPerformUnlink->VfsUnlinkChild->LxDrvFsRemoveChild->LxDrvFsDeleteFile->ZwSetInformationFile,其中會通過LxDrvFsDeleteFile 會使用IoCreateFile打開文件,再進行刪除。 lxcore.sys中實現了一套VfsXXXX接口向上虛擬了VFS,向下使用LxDrvFsXXXX的一組API提供文件訪問能力。
對于網絡的操作,分為UNIX協議簇和INET協議簇,兩個有不同的分發表,比如當上層發送一個UDP包的時候,lxcore的調用流程: LxpSyscall_SENDMMSG->LxpSocketSendMultipleMessages->LxpSocketInetSendMessage->LxpSocketInetSend->LxpSocketInetDatagramSend->afd!WskProAPISendTo。最終會進入到afd執行相應的功能。這是打印出來的lxcore使用的Afd相關函數:
再其它的一些,比如獲取當前系統信息,lxcore也是直接調用Nt相應的函數獲取,例如date命令,lxcore通過LxpSyscall_CLOCK_GETTIME->KeQuerySystemTimePrecise獲取。
四. 注入Pico Process
最后試了一下注入到pico process,打算注入進去調用一下pico process的分發表,由于pico process沒有section對象所以無法用遠程線程注入。最后使用SetThreadContext方法注入到了pico process進程。雖然可以注入成功,但windbg是無法調試pic process的,因為lxcore接管了pico process的異常分發,nt!KiDispatchException中如果發現異常在pico thread中,則使用PicoDispatchException處理異常,lxcore中使用APC模擬signal機制處理進程通信與異常分發。
五.總結
目前來說LxpSyscalls目前包含0×138個調用,而且有些調用目前內部沒有邏輯實現,所以微軟在未來會逐漸完善各種命令的支持。上面簡單分析了一下lxcore對于linux子系統操作的支持,當然只是部分操作,還有一些比如ELF加載,內存管理,設備管理等都還沒有分析。但從目前已經分析的結果來看,微軟確實是自己實現一套linux子系統支持,并不是一個Linux虛擬機,所以執行效率會好很多,比如pico process的進程的時間片分配和原生的process基本一致。但是缺點也是有,增加了一套lxss機制后,同時也增加了復雜性,也就是說win10以后可能會面臨win和linux二進制安全的雙重考驗,這可能對windows的安全性保障又增加了新的難題。
若想了解更多,微信或QQ搜索公眾號「互聯網安全」