C# 讀寫文件從用戶態切到內核態,到底是個什么流程?

一:背景

1. 一個很好奇的問題

我們在學習 C# 的過程中,總會聽到一個詞叫做 內核態 ,比如說用 C# 讀寫文件,會涉及到代碼從 用戶態內核態 的切換,用 HttpClient 獲取遠端的數據,也會涉及到 用戶態內核態 的切換,那到底這是個什么樣的交互流程?畢竟我們的程序是無法操控 內核態 ,今天我們就一起探索下。

二:探究兩態的交互流程

1. 兩個態的交界在哪里

我們知道人間和地府的交界處在 鬼門關,同樣的道理 用戶態內核態 的交界處在 ntdll.dll 層,畫個圖就像下面這樣:

36ec02a9edde5928b3e183257fe219e4.png

操作系統為了保護 內核態 的代碼,在用戶態直接用指針肯定是不行的,畢竟一個在 ring 3,一個在 ring 0,而且 cpu 還做了硬件保護兜底,那怎么進入呢?為了方便研究,先上一個小例子。

2. 一個簡單的文件讀取

我們使用 File.ReadAllLines() 實現文件讀取,代碼如下:

internal?class?Program{public?static?object?lockMe?=?new?object();static?void?Main(string[]?args){var?txt=?File.ReadAllLines(@"D:\1.txt");Console.WriteLine(txt);Console.ReadLine();}}

在 Windows 平臺上,所有內核功能對外的入口就是 Win32 Api ,言外之意,這個文件讀取也需要使用它,可以在 WinDbg 中使用 bp ntdll!NtReadFile 在 鬼門關 處進行攔截。

0:000>?bp?ntdll!NtReadFile
breakpoint?0?redefined
0:000>?g
ModLoad:?00007ffe`fdb20000?00007ffe`fdb50000???C:\Windows\System32\IMM32.DLL
ModLoad:?00007ffe`e2660000?00007ffe`e26bf000???C:\Program?Files\dotnet\host\fxr\6.0.5\hostfxr.dll
Breakpoint?0?hit
ntdll!NtReadFile:
00007ffe`fe24c060?4c8bd1??????????mov?????r10,rcx

哈哈,很順利的攔截到了,接下來用 uf ntdll!NtReadFile 把這個方法體的匯編代碼給顯示出來。

0:000>?uf?ntdll!NtReadFile
ntdll!NtReadFile:
00007ffe`fe24c060??mov?????r10,rcx
00007ffe`fe24c063??mov?????eax,6
00007ffe`fe24c068??test????byte?ptr?[SharedUserData+0x308?(00000000`7ffe0308)],1
00007ffe`fe24c070??jne?????ntdll!NtReadFile+0x15?(00007ffe`fe24c075)?
00007ffe`fe24c072??syscall
00007ffe`fe24c074??ret
00007ffe`fe24c075??int?????2Eh
00007ffe`fe24c077??ret

從匯編代碼看,邏輯非常簡單,就是一個 if 判斷,決定到底是走 syscall 還是 ?int 2Eh,很顯然不管走哪條路都可以進入到 內核態,接下來逐一聊一下。

3. int 2Eh 入關走法

相信在調試界沒有人不知道 int 是干嘛的,畢竟也看過無數次的 int 3,本質上來說,在內核層維護著一張 中斷向量表,每一個數字都映射著一段函數代碼,當你打開電腦電源而后被 windows 接管同樣借助了 中斷向量表 ,好了,接下來簡單看看如何尋找 3 對應的函數代碼。

windbg 中有一個 !idt 命令就是用來尋找數字對應的函數代碼。

lkd>?!idt?3Dumping?IDT:?fffff804347e100003:?fffff80438000f00?nt!KiBreakpointTrap

可以看到,它對應的內核層面的 nt!KiBreakpointTrap 函數,同樣的道理我們看下 2E

lkd>?!idt?2EDumping?IDT:?fffff804347e10002e:?fffff804380065c0?nt!KiSystemService

現在終于搞清楚了,進入內核態的第一個方法就是 KiSystemService,從名字看,它是一個類似的通用方法,接下來就是怎么進去到內核態相關的 讀取文件 方法中呢?

要想找到這個答案,可以回頭看下剛才的匯編代碼 mov eax,6 ,這里的 6 就是內核態需要路由到的方法編號,哈哈,那它對應著哪一個方法呢?由于 windows 的閉源,我們無法知道,幸好在 github 上有人列了一個清單:https://j00ru.vexillium.org/syscalls/nt/64/ ?,對應著我的機器上就是。

c1c377ad60456cc3a724fbe0e4abd18e.png

從圖中可以看到其實就是 ?nt!NtReadFile ,到這里我想應該真相大白了,接下來我們聊下 syscall

4. syscall 的走法

syscall 是 CPU 特別提供的一個功能,叫做 系統快速調用,言外之意,它借助了一組 MSR寄存器 幫助代碼快速從 用戶態 切到 內核態, 效率遠比走 中斷路由表 要快得多,這也就是為什么代碼會有 if 判斷,其實就是判斷 cpu 是否支持這個功能。

剛才說到它借助了 MSR寄存器,其中一個寄存器 MSR_LSTAR 存放的是內核態入口函數地址,我們可以用 rdmsr c0000082 來看一下。

lkd>?rdmsr?c0000082
msr[c0000082]?=?fffff804`38006cc0lkd>?uf?fffff804`38006cc0
nt!KiSystemCall64:
fffff804`38006cc0?0f01f8??????????swapgs
fffff804`38006cc3?654889242510000000?mov???qword?ptr?gs:[10h],rsp
fffff804`38006ccc?65488b2425a8010000?mov???rsp,qword?ptr?gs:[1A8h]
...

從代碼中可以看到,它進入的是 nt!KiSystemCall64 函數,然后再執行后續的 6 對應的 nt!NtReadFile 完成業務邏輯,最終也由 nt!KiSystemCall64 完成 內核態 到 用戶態 的切換。

知道了這兩種方式,接下來可以把圖稍微修補一下,增加 syscallint xxx 兩種入關途徑。

9a623895c9f6e80d4dbd3bdbc8e0bcc4.png

三:總結

通過匯編代碼分析,我們終于知道了 用戶態內核態 的切換原理,原來有兩種途徑,一個是 int 2e,一個是 syscall ,加深了我們對 C# 讀取文件 的更深層理解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/285634.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285634.shtml
英文地址,請注明出處:http://en.pswp.cn/news/285634.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言九十四之請編寫函數fun(char *str, int n),其功能是:使字符串str的前導*號不能多余n個,若多于n個,則刪除多余的*號,若少于或等于n個,則不做處理。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 規定輸入的…

【土地評價與土地管理】案例:某地區土地農業利用潛力評價

文章目錄 一、確定評價單元二、擬定潛力評價系統表、確定指標權重三、指標評價四、評定潛力等級五、得出潛力評價結果一、確定評價單元 土地潛力評價單元采用地塊作為評價單元,此地塊是建立在土地利用現狀的基礎上, 綜合土地的自然屬性來確定,評價單元界線與土地現有界線基本…

WIKIOI 1519 過路費

1519 過路費 1519 過路費 時間限制: 1 s 空間限制: 256000 KB 題目等級 : 大師 Master 題解 題目描述 Description 在某個遙遠的國家里,有 n個城市。編號為 1,2,3,…,n。這個國家的政府修建了m 條雙向道路,每條道路連接著兩個城市。政府規定從城市…

code point,code unit

2019獨角獸企業重金招聘Python工程師標準>>> 從一段API描述談起: 在String的length的API中描述是這樣的! lengthpublic int length() Returns the length of this string. The length is equal to the number of 16-bit Unicode characters i…

Android之解決JsonObject里面的JsonArray數據會有斜杠問題

1、問題 本地保存了多個json格式的字符串 {"event":"sdk_ad_request_status","timestamp":1640180549231,"ad_app_id":"10104","pool_test":0,"ad_type":0,"ad_request_time":0,"requ…

【土地評價與土地管理】案例:蘭州市榆中縣農用地分等

文章目錄 一、資料收集二、確定標準耕作制度、基準作物、指定作物、光溫(氣候生產潛力)三、劃分指標區,確定分等因素及權重四、編制“指定作物-分等因素-自然質量分”記分規則表五、繪制分等因素分值圖,劃分分等單元六、計算農用地自然質量分七、計算自然質量等指數八、計算…

.NET7之MiniAPI(特別篇) :Preview5優化了JWT驗證(下)

Preview5對策略驗證的方式沒有改變,只不過內置了Token的生成,和《.NET6之MiniAPI(十):基于策略的身份驗證和授權》的驗證方式基本相同,都是生成和驗證使用的驗證參數要一致,用繼承AuthorizationHandler的子類來作每次請…

業務多變的公司上云后蒸蒸日上

一、云服務器與傳統服務器的對比 1)、傳統服務器 傳統服務器是一個獨立的硬件設備,可以理解成是一臺放在機房的高配置電腦,可根據需求安裝各種操作系統以及配置各種環境,性能也比較強大。 2)、云服務器 云服務器是構建在硬件服務器集群之上,…

2016福州大學軟件工程第四次團隊作業-系統設計成績匯總

第四次團隊作業——系統設計打分統計結果如下: 學號組別團隊分數貢獻比例個人分數031401433606notconnected141613.83031402606606notconnected141413.33031402618606notconnected141814.34031402629606notconnected141413.33031402631606notconnected141914.590314…

[轉]在C#中像Python一樣編寫TensorFlow機器學習代碼

機器學習是一個令人激動人心的領域,一直有新的技術突破。研究人員不斷推動機器智能的提升,教機器如何聽說讀寫——這些曾經是我們人類專屬的技能。機器學習的首選語言是Python,最受歡迎的庫是Google的TensorFlow。幾乎所有的代碼示例都是用Py…

【土地評價與土地管理】教案 第一章:土地評價要素的選擇

文章目錄 1.1 土地構成要素與其農業利用1、光能條件2、熱量條件3、降水條件1.1 土地構成要素與其農業利用 1、光能條件 ? 光能是綠色植物進行光合作用和生物運動發展的主要能源 ? 太陽輻射、日照時數 ? 太陽輻射量隨地域和季節變化較大,導致了土地利用的多樣性和土地資源…

Blazor University (33)表單 —— EditContext、FieldIdentifiers

原文鏈接:https://blazor-university.com/forms/editcontext-fieldidentifiers-and-fieldstate/EditContext、FieldIdentifiers 和 FieldState請注意,對于那些希望了解 Blazor 如何“在后臺”工作的人來說,這是一個高級主題。無需了解此信息即…

Flutter之Container的寬度如何設置為手機屏幕寬度

1、問題 Container的寬度如何設置為手機屏幕寬度 2、解決辦法 width: MediaQuery.of(context).size.width,Row(children: [Container(height: 40,width: MediaQuery.of(context).size.width,// width: double.infinity,color: Colors.red,child: Row(children: [Containe…

團隊項目開發篇章8

例會時間:2016.11.3 整理:姬索肇 例會照片 每個人的工作 任務分配 我們今天與王鹿鳴學長和李云濤學長針對團隊開發過程中遇到的問題進行了討論,非常感謝學長們的熱心幫助,同時我們也被他們強大的編程能力所折服~ 在這里為學長們點…

MongoDB常用命令

啟動MongoDB$mongod --fork --logpath/data/log/r3.log--fork 允許mongod后臺運行,但是必須指定日志記錄文件路徑(Enables a daemon mode that runs the mongos process in the background.)--logpath 指定日志記錄文件路徑 導出Collections$…

【地理信息系統GIS】教案(七章全)第一章:地理信息系統概述

文章目錄 第一節 GIS基本概念第二節 GIS的組成第三節 GIS的功能第四節 GIS的發展第一節 GIS基本概念 1.1 GIS基本概念 1、信息 是用文字、數字、符號、語言、圖象、圖形等介質來表達事件、事物或現象等的內容、數量和特征,從而向人們(或系統)提供關于現實世界新的事實和知…

C# 讀寫ini文件 保存信息

/// <summary> /// 獲取本地信息 /// </summary> /// <returns></returns> private List<MHistoryKewWord> GetLocalHistoryKeyWords(){List<MHistoryKewWord> list new List<MHistoryKewWord>();var fs new FileStream("dat…

表達式的動態解析和計算,Flee用起來真香

前言在很多項目中經常會出現需要動態解析表達式和計算的場景&#xff0c;比如一些自動審核規則&#xff0c;或者是一些變量的值通過維護的公式在運行過程中動態算出&#xff1b;由于場景需求&#xff0c;都需要比較靈活的配置對應的表達式&#xff0c;然后希望在需要的時候能根…

C語言九十五之實現經典的反轉數組(通過指針或數組下標操作)

?作者簡介&#xff1a;大家好我是碼瑪莎拉蒂&#xff0c;CSDN博客專家&#x1f947;&#x1f947;&#x1f947; &#x1f4c3;個人主頁&#xff1a;個人主頁 &#x1f525;系列專欄&#xff1a;C語言試題200例 &#x1f4ac;推薦一款模擬面試、刷題神器&#x1f449; 點擊跳轉…

Linux下使用shell實現上傳linux下某個目錄下所有文件到ftp

首先我們需要搞清楚單個文件怎么上傳&#xff0c;把這個單文件上傳到ftp上的實現命名為一個:upload_to_ftp_command.sh 之后&#xff0c;需要弄清楚怎么實現遍歷一個目錄下的所有文件的&#xff0c;把這個遍歷某個目錄下的文件實現命名為&#xff1a;foeach_directory_and_uplo…