日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows内核实验003 再次回到中断

發(fā)布時間:2025/3/21 windows 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows内核实验003 再次回到中断 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 兩個實驗
      • 死循環(huán)
      • 開啟中斷后的死循環(huán)
    • KiFastCallEntry
      • 調(diào)用零環(huán)API的兩個條件
      • 分析KiFastCallEntry
      • 什么是KPCR
    • 完善代碼
    • 完整代碼

之前的實驗我們已經(jīng)實現(xiàn)了從三環(huán)到零環(huán)的提權(quán),但是提權(quán)不代表能正常調(diào)用內(nèi)核函數(shù)。接下來我們要實現(xiàn)的一個事情就是在我們的代碼里正常調(diào)用內(nèi)核的函數(shù)。

還是接著用上次的代碼,這一次我們先來做兩個實驗。

兩個實驗

死循環(huán)

首先用windbg連上虛擬機

在我們的內(nèi)核提權(quán)函數(shù)IdtEntry中寫上一個死循環(huán),接著用下面這條命令將當(dāng)前函數(shù)地址寫入到IDT表中

eq 80b95500 0040ee00`00081040

然后運行程序

會發(fā)現(xiàn)整個虛擬機直接卡死,連windbg也無法接管控制權(quán)。這是因為單核的CPU禁止中斷時,系統(tǒng)無法中斷內(nèi)核代碼的任何操作,導(dǎo)致函數(shù)中的死循環(huán)一直在運行,進(jìn)而導(dǎo)致虛擬機卡死現(xiàn)象。

開啟中斷后的死循環(huán)

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PGPIOwjt-1573888072291)(assets/1573879516464.png)]

接著我們在代碼中加入一條sti指令來開啟中斷,再次運行程序

我們發(fā)現(xiàn)此時虛擬機直接藍(lán)屏。原因在于開啟中斷以后產(chǎn)生了時鐘的硬件中斷,受線程切換的影響產(chǎn)生藍(lán)屏。

KiFastCallEntry

在XP系統(tǒng)中,系統(tǒng)服務(wù)在內(nèi)核的入口是KiFastCallEntry。我們來大概分析一下這個函數(shù)和我們縮寫的內(nèi)核代碼有什么區(qū)別。

首先在XP虛擬機中打開PC Hunter

接著打開驅(qū)動模塊,找到第一個ntkrnlpa.exe,右鍵定位到驅(qū)動模塊,找到exe文件,并用IDA分析,記得IDA分析的時候下載符號文件。

在IDA中搜索KiFastCallEntry這個函數(shù)

接著我們觀察到這個函數(shù)中間也有一條sti指令,也做了一個開中斷的操作。開啟中斷以后后面的代碼也會受到線程調(diào)度的影響。

那么問題來了,為什么KiFastCallEntry開啟中斷以后沒有藍(lán)屏,我們自己寫的代碼反而藍(lán)屏了呢?

這就說明這個函數(shù)在一開始到開啟中斷之間建立了一個安全的線程調(diào)度環(huán)境,那如果在我們的代碼里建立一個安全的線程調(diào)度環(huán)境,那么我們開中斷也是安全的。開啟中斷以后我們就可以在我們的代碼里通過系統(tǒng)調(diào)用號來調(diào)用零環(huán)的API函數(shù)了。

調(diào)用零環(huán)API的兩個條件

  • 有內(nèi)核權(quán)限
  • 有安全的線程調(diào)度環(huán)境
  • 分析KiFastCallEntry

    第一個條件我們已經(jīng)完成了,接下來我們通過分析KiFastCallEntry這個函數(shù)來達(dá)到第二個條件。

    在KiFastCallEntry中,比較重要的代碼是上面兩句。這兩句含義是將0x30賦值給了fs段選擇子。

    接下來拆解一下0x30這個段選擇子所代表的含義

    • 0x30=0000000000110 0 00?
    • 0000000000110代表查GDT表下標(biāo)為6的項
    • 0代表查GDT表
    • 00代表0環(huán)權(quán)限

    接下來在windbg中查看GDT表

    第六項也就是80b95030的這個位置,這個位置是一個叫KPCR的結(jié)構(gòu)

    什么是KPCR

    KPCR即Kernel Processor Control Region,處理器控制區(qū)域。因為Windows是需要支持多個CPU的,所以為每一個CPU在內(nèi)核空間安排一個KPCR的結(jié)構(gòu)。用來保存與線程切換相關(guān)的全局信息,里面有我們之前說過的TSS。

    ring3下,fs寄存器的指向TEB,ring0下,fs寄存器指向KPCR

    也就是說push 0x30;pop fs這兩條指令的目的是為了讓FS寄存器指向KPCR,使線程切換相關(guān)的操作能夠正常執(zhí)行。

    完善代碼

    我們之前寫的代碼開啟了中斷,接著藍(lán)屏的原因是因為沒有對fs進(jìn)行正確的設(shè)置。我們在開中斷之前只需要做一個和KiFastCall一樣的操作就能建立了安全的線程調(diào)度環(huán)境。

    代碼修改如下:

    void __declspec(naked) IdtEntry() {__asm{push 0x30;pop fs;sti; L: jmp L;iretd;} }

    修改完成以后編譯運行,

    可以看到現(xiàn)在的情況是程序可以正常運行,虛擬機沒有卡死也沒有藍(lán)屏,和之前的結(jié)果完全不一樣。在開啟任務(wù)管理器,觀察我們這個進(jìn)程

    現(xiàn)在這個程序只是一個占用了幾乎百分之百的CPU的一個進(jìn)程,其他的程序還有機會得到執(zhí)行,因為已經(jīng)設(shè)置好了線程調(diào)度環(huán)境,允許其他線程訪問計算機資源。

    而且現(xiàn)在這個進(jìn)程不管怎么樣都結(jié)束不掉。原因在于操作系統(tǒng)結(jié)束進(jìn)程的時機是在0環(huán)返回3環(huán)的瞬間,而我們的程序現(xiàn)在在0環(huán)死循環(huán)了,沒有機會返回到3環(huán),自然也就無法結(jié)束了。

    完整代碼

    最后附上完整代碼

    #include "pch.h" #include <iostream> #include <stdio.h> #include <stdlib.h> #include <windows.h>DWORD g_tmp;void __declspec(naked) IdtEntry() {__asm{push 0x30;pop fs;sti; L: jmp L;iretd;} } void go() {__asm int 0x20; }//eq 80b95500 0040ee00`00081040 int main() {if ((DWORD)IdtEntry != 0x401040){printf("wrong addr:%p", IdtEntry);exit(-1);}go();printf("%p", g_tmp);system("pause"); }

    總結(jié)

    以上是生活随笔為你收集整理的Windows内核实验003 再次回到中断的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。