|
今天在測(cè)試socket的內(nèi)核緩沖區(qū)大小的時(shí)候,初步了解了內(nèi)核態(tài)與用戶態(tài)的切換過程。 我的測(cè)試是這樣的:首先建立c/s模型,建立socket連接,然后讓服務(wù)器端不斷的發(fā)送消息,每次發(fā)送1024個(gè)字節(jié),而客戶端不接收數(shù)據(jù)。這樣當(dāng)服務(wù)器端發(fā)送了24K左右以后,就會(huì)阻塞在send處,無法再發(fā)送數(shù)據(jù)了。 同理,客戶端發(fā)送消息的時(shí)候也是一樣的。測(cè)試結(jié)果顯示緩沖區(qū)大小也是25K左右。 這樣我們就初步證明了內(nèi)核緩沖區(qū)的存在性。 也就是說,如果我們只是發(fā)送數(shù)據(jù)而沒有接收數(shù)據(jù)的話,那么我們使用send函數(shù)發(fā)送數(shù)據(jù)的時(shí)候,最終會(huì)調(diào)用內(nèi)核態(tài)ring0級(jí)的send函數(shù)(究竟是哪個(gè)內(nèi)核API自己現(xiàn)在還不是很清楚)。在內(nèi)核態(tài)應(yīng)該有一塊緩沖區(qū)專門用來存放發(fā)送的數(shù)據(jù),而且類似管道機(jī)制,如果數(shù)據(jù)沒有存滿,那么允許一直存放,直到到達(dá)緩沖區(qū)最大容許存放的大小。 從應(yīng)用層轉(zhuǎn)換到內(nèi)核層這整個(gè)過程是很繁瑣的,中間會(huì)調(diào)用很多API。 關(guān)于應(yīng)用層到內(nèi)核層的切換問題,下面這個(gè)鏈接舉了一個(gè)最常見的fork函數(shù)的例子。以及在哪些情況下會(huì)使操作系統(tǒng)運(yùn)行在ring0級(jí)別上。 http://rf./article/09-12/1628861261320722.html?sort=899_939_950_0 用戶態(tài)切換到內(nèi)核態(tài)的3種方式 a. 系統(tǒng)調(diào)用 b. 異常 c. 外圍設(shè)備的中斷 這3種方式是系統(tǒng)在運(yùn)行時(shí)由用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài)的最主要方式,其中系統(tǒng)調(diào)用可以認(rèn)為是用戶進(jìn)程主動(dòng)發(fā)起的,異常和外圍設(shè)備中斷則是被動(dòng)的。 那么看了上面的概念之后,自然而然就產(chǎn)生了這樣一個(gè)疑惑:我們?cè)趺礃涌梢灾鲃?dòng)進(jìn)入到ring0呢?
今天初步看了《寒江獨(dú)釣 windows內(nèi)核安全編程》這本書,自己只是想把基礎(chǔ)概念了解一下。 簡(jiǎn)單的說,我們自己寫一個(gè)內(nèi)核模塊,或者說是驅(qū)動(dòng)程序,當(dāng)然不是說我們真正開發(fā)驅(qū)動(dòng),而是我們通過這種方法可以進(jìn)入ring0層??梢匀我庑薷膬?nèi)核。 我們知道,用戶空間是各個(gè)進(jìn)程隔離的,但是內(nèi)核空間是共享的。編寫的內(nèi)核模塊運(yùn)行在內(nèi)核空間,成為操作系統(tǒng)的一個(gè)模塊,最終被所有需要該模塊提供功能的應(yīng)用程序調(diào)用。 那么這個(gè)內(nèi)核模塊是被哪個(gè)進(jìn)程擁有的呢?實(shí)際上,內(nèi)核模塊位于任何一個(gè)進(jìn)程空間中。這取決于請(qǐng)求的來源、處理的過程等。 還有幾個(gè)基本概念需要我們了解的: http://blog.csdn.net/vangoals/article/details/4359612 http://blog.csdn.net/yangbostar/article/details/5774774 驅(qū)動(dòng)對(duì)象 設(shè)備對(duì)象 請(qǐng)求(IRP) 分發(fā)函數(shù) 首先,談?wù)勻?qū)動(dòng)對(duì)象(DRIVER_OBJECT),可以說驅(qū)動(dòng)對(duì)象代表的是一個(gè)驅(qū)動(dòng)程序(或者叫內(nèi)核模塊)。在寫內(nèi)核程序時(shí),必須要填寫這樣一種結(jié)構(gòu),來告訴Windows程序提供的功能。內(nèi)核程序并不生成進(jìn)程,它們有系統(tǒng)的System進(jìn)程加載,可以存在于任何的進(jìn)程。 設(shè)備對(duì)象(DEVICE_OBJECT)可以是一個(gè)具體的物理設(shè)備,如:鍵盤、硬盤等;也可以是一個(gè)虛擬的“設(shè)備”,如:用于進(jìn)程間通信的管道。設(shè)備對(duì)象由驅(qū)動(dòng)對(duì)象創(chuàng)建,一個(gè)驅(qū)動(dòng)對(duì)象可以創(chuàng)建很多個(gè)設(shè)備對(duì)象。這些設(shè)備對(duì)象儲(chǔ)存在一個(gè)設(shè)備棧中,這些設(shè)備對(duì)象是用鏈表連接在一起的,當(dāng)新的設(shè)備對(duì)象產(chǎn)生時(shí)應(yīng)該是用的尾插入(和人理解)。 對(duì)于請(qǐng)求,我們可以理解為Windows SDK程序設(shè)計(jì)里的消息。一般都是以IRP方式傳遞的。而設(shè)備對(duì)象是唯一可以接受請(qǐng)求的實(shí)體。然而一個(gè)驅(qū)動(dòng)對(duì)象中可能會(huì)有很多個(gè)設(shè)備對(duì)象,那么是由哪一個(gè)設(shè)備對(duì)象來處理呢? 我的理解是:就像MFC中的消息傳遞機(jī)制一樣,會(huì)有一個(gè)消息的接收順序;IRP請(qǐng)求也是這樣,它先發(fā)送到設(shè)備棧中最上面的一個(gè)設(shè)備(最新加入),沒有被處理就繼續(xù)向下發(fā)送,如果到最后都還是沒有被處理,我認(rèn)為會(huì)有一個(gè)默認(rèn)的處理。 請(qǐng)求是有各種各樣的類型,有的要求讀,有的要求寫,那么它們就要被分類后,分發(fā)到對(duì)應(yīng)的自己編寫的處理函數(shù),這些函數(shù)叫做“分發(fā)函數(shù)”,也有翻譯為“派遣函數(shù)”
以上內(nèi)容只是自己初步學(xué)習(xí)的筆跡總結(jié),可能有很多錯(cuò)誤的地方,還請(qǐng)大家指正。謝謝 |
|
|