當前位置:
首頁 > 最新 > java開發系統內核:應用程序與系統內核的內存隔離

java開發系統內核:應用程序與系統內核的內存隔離

當前,我們可以開發運行在系統上的應用程序了,接下來的問題是如何保護系統內核免受惡意應用程序的危害。惡意程序要想侵犯系統,主要路徑有兩條,一是讓內核執行它的代碼,而是修改內核數據,通過修改數據改變內核的行為。我們看看,如何預防惡意程序侵入到系統內核的數據區域中。

無論是內核還是應用程序,他們的內存都分兩種,一種叫代碼段,也就是有一塊專門的內存用來存儲程序的指令,另一種叫數據段,也就是有一塊專門的內存來存儲程序的數據。

前面提到過一種數據結構叫全局描述符,這種數據結構就是用來描述一段內存的作用的,該結構包含以下信息:

1, 內存段的起始地址

2, 內存段的長度

3, 內存段的屬性

假設CPU將指向以下的數據讀寫語句:

也就是代碼想在內存地址為0x100處寫入一個字元』a』, 問題在於0x1000並不是內存的絕對地址,它只是相對於數據段的偏移。假設當前用於描述數據段的全局描述符如下:

0:

1 :

2:

當程序執行前面的內存讀寫指令時,具體寫入的地址要看DS段寄存器指向哪個描述符,如果DS的值是0,那麼數據段的起始地址是0x1000,那麼程序實際寫入的內存地址就是0x1100 = 0x1000 + 0x100, 如果DS寄存器的值是1,那意味著數據段的起始地址是0x2000, 於是實際的寫入地址就是 0x2100 = 0x2000 + 0x100.

這麼看來,要想實現應用程序和內核的內存隔離,就必須使得應用程序運行時,DS寄存器指向的描述符與內核代碼運行是DS寄存器指向的描述符不一樣,這樣一來應用程序在讀寫數據時就不會污染內核的數據。

基於這個思想,內核在運行應用程序時,只要專門分配一塊與內核內存相互隔離的內存作為應用程序的數據段,這樣的話就能有效的實現程序與內核的內存隔離,進而能包含內核不受應用程序的入侵。我們先看一段將要運行在內核上的C語言代碼開發的應用程序(app.c):

這段程序的目的是把』app』這幾個字元寫入到地址為0x100的內存中,根據前面的分析,0x100所對應的內存取決於DS寄存器指向的描述符。為了防止應用程序把數據寫入到內核內存進而污染內核的數據,我們需要在內核執行上面的程序前,為其指定專門的代碼段,因此我們代碼改動如下,在write_vga_desktop.c中做如下代碼改動:

當我們啟動內核,在控制台輸入hlt命令後,上面的代碼會被執行,它把一個叫abc.exe的程序代碼從磁碟上載入到內存,abc.exe對應的就是前面C語言編譯成二進位後的指令數據。

在啟動程序前,也就是執行app.c的代碼前,內核先分配一塊64k大小的內存,然後用下標為12的全局描述符指向這塊內存,然後調用start_app 函數啟動應用程序,由於分配的內存塊起始地址為q, 因此app.c中對內存地址為0x100處進行讀寫,根據前面的分析,由於應用程序的內存段起始地址是q,所以應用程序實際寫入的內存地址為q + 0x100, 如果我們的理論正確的話,應用程序執行後,在內存q+0x100處對應的數據就是』app』,0。

所以內核在執行完應用程序後,把內存為q+0x100出開始的數據通過showString顯示到桌面上,如果我們的理論正確,那麼字元串app就會出現在系統的桌面上。

我們再看start_app函數的實現,它的實現在kernel.asm中,代碼如下:

start_app的作用是設置應用程序的內存段,它會把DS寄存器指向內核為應用程序分配的內存,一旦DS寄存器的值變了後,內核的代碼就不能被執行了,因為當前內存段是應用程序的,不是內核的內存段,所以我們需要指令cli把中斷關閉,避免時鐘中斷髮生。

接著我們需要把輸入參數放入到幾個寄存器,第一個參數對應的是應用程序在代碼段的起始地址,用於我們需要從應用程序的第一條語句開始執行,所以它的起始地址為0,第二個參數對應應用程序代碼段的描述符下標,第三個參數是應用程序的堆棧指針,這裡需要提一下,程序運行是所使用的內存中,有專門一塊用作程序的棧,程序的輸入參數和局部變數都需要存儲在棧上,由此前面內核分配的64k內存使用情況如下:

esp-> end_address(q + 64k)————-

esp寄存器的作用是棧指針,它指嚮應用程序的可用內存底部,它由高向低增長,假設有4位元組數據要存入堆棧時,數據會寫入到esp指向的內存,然後esp的值減去4。

原來esp指向的是內核的堆棧,當應用程序運行時,它必須指嚮應用程序的堆棧,所以在改變esp的值之前,需要把它原來的值保存起來,為了方便,我們先把他保存在內存地址為0xfe4的地方,根據我們前面分析,這個地址也是相對地址,絕對地址還得加上內核數據段的起始地址,由於內核數據段的起始地址是0,因此我們實際上是把寄存器esp的值直接存放到了絕對內存地址為0xfe4的地方,接著把ds,ss兩個寄存器的值改成內核新分配內存所對應的描述符下標,ss寄存器對於的是堆棧段,這裡我們把內存和堆棧都指向同一塊內存,當讀寫數據時,我們從64k內存的低地址向高地址寫入,當把數據壓入堆棧時,從64k內存的高地址向低地址寫入。

由於應用程序代碼段描述符和要運行的第一條指令的地址已經存儲到ecx,和eax中,把這兩個寄存器壓入堆棧,然後運行指令call far [esp], 這條指令會把esp指向的內存中,先取出4位元組作為代碼段描述符下標,再取出4位元組數據作為代碼段的偏移,也就是把esp指向的內存的4位元組數據賦值給寄存器ip, 然後再把接下來的4位元組作賦值給寄存器cs,這樣CPU就跳轉到了應用程序的第一句指令開始執行。

當應用程序執行完後,返回到call語句的下一條語句,這時start_app把內核代碼運行時寄存器對應的值給恢復,特別是把內核運行時的堆棧指針重新從內存0xfe4處讀回來,於是CPU的控制器就重新歸還給內核。

上面的代碼運行後,結果如下:

我們看到,應用程序在0x100處寫入的數據成功的被內核讀到並列印在桌面上,由此證明,我們成功的實現了應用程序內存和內核內存的隔離,這麼一來,內核就可以免受應用程序的在內存方面的入侵了。

更詳細的講解和調試演示過程,請參看視頻。

更多技術信息,包括操作系統,編譯器,面試演算法,機器學習,人工智慧,請關照我的公眾號:

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Coding迪斯尼 的精彩文章:

jvm的return指令以及局部變數的操作

TAG:Coding迪斯尼 |

您可能感興趣

強制關閉你的系統的內核模塊
Imagination 推出可滿足汽車儀錶板、HUD 和信息娛樂系統需求的硬體虛擬化 GPU 內核
Imagination推出可滿足汽車儀錶板、HUD和信息娛樂系統需求的硬體虛擬化 GPU 內核
Raft和Paxos在分散式存儲系統中的應用差異
關於VR虛擬現實系統的應用與開發
運行新版內核的 Linux 系統受「熔斷」漏洞補丁的影響不大
知曉電腦:win7系統關閉媒體中心,節省內存,加快運行速度
選擇Zephyr操作系統,為IoT開發找到正確的入口
HashCache:低內存緩存存儲系統
Facebook開發專用於炎熱乾旱氣候的新型數據中心冷卻系統
Google發布其物聯網操作系統開發者預覽版
ASEva主動安全開放道路評估及場景採集系統
黑莓徹底放棄BlackBerry系統 開始關閉計劃
Win7系統打開程序時彈出"windows防火牆安全警報"的解決方法
傳微軟正在開發全新輕量級操作系統Polaris
揭秘Airbnb的內部營銷系統
谷歌開始在Android P系統中測試手勢操作
如何在Keras中開發神經機器翻譯系統?
Windows 系統重裝前的文檔、驅動和聊天信息備份
說說操作系統內核