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

歡迎訪問 生活随笔!

生活随笔

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

windows

Windows内核实验004 API调用

發(fā)布時(shí)間:2025/3/21 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows内核实验004 API调用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 完善代碼
    • 內(nèi)核API調(diào)用
    • 修復(fù)一個(gè)潛在問題
      • 復(fù)現(xiàn)問題
    • 完整代碼

前面幾次實(shí)驗(yàn)我們已經(jīng)完成了一個(gè)三環(huán)的程序調(diào)用零環(huán)API的必要條件。

  • 提升到零環(huán)權(quán)限
  • 使fs指向KPCR

完善代碼

這次我們?nèi)サ糁暗乃姥h(huán)代碼,并且將函數(shù)地址寫入到IDT表項(xiàng),在虛擬機(jī)中運(yùn)行一下程序,看看會有什么結(jié)果。

這里他拋出了一個(gè)內(nèi)存訪問異常。原因在于我們修改了fs寄存器之后,在iretd指令返回三環(huán)的時(shí)候,系統(tǒng)不會自動幫我們將FS寄存器還原。

所以我們在返回三環(huán)之前還需要將fs還原回去。代碼如下:

__asm{push 0x30;pop fs;sti;push 0x3B;pop fs;iretd;}

再次運(yùn)行我們的程序,

此時(shí)程序完全正常運(yùn)行。

內(nèi)核API調(diào)用

接下來我們在自己的代碼中調(diào)用一個(gè)內(nèi)核的API函數(shù)ExAllocatePool來分配一塊內(nèi)存。

首先在PC Hunter中將ntkrnlpa.exe拷貝出來,然后用IDA分析,接著設(shè)置基址和驅(qū)動模塊的基地址一致。

在IDA中找到ExAllocatePool這個(gè)函數(shù),并且記錄下函數(shù)地址。

然后按Y鍵可以復(fù)制出函數(shù)原型,然后定義函數(shù)指針,并且將函數(shù)地址賦值給函數(shù)指針變量

typedef DWORD (__stdcall *EX_ALLOCATE)(DWORD PoolType, DWORD NumberOfBytes); EX_ALLOCATE ExAllocatePool= (EX_ALLOCATE)0x83E51976;

接著編寫調(diào)用代碼如下:

void __declspec(naked) IdtEntry() {__asm{push 0x30;pop fs;sti;}g_pool=ExAllocatePool(0, 4096);__asm{push 0x3B;pop fs;iretd;} }

運(yùn)行程序

看到這里將我們申請的內(nèi)存首地址打印出來了,而且是一個(gè)內(nèi)核的地址,符合我們的預(yù)期

然后我們可以嘗試調(diào)用一下DbgPrint,同樣的方法找到函數(shù)地址和原型進(jìn)行調(diào)用

typedef DWORD ( __cdecl *DBGPRINT)(char* Format, ...); DBGPRINT MyDbgPrint=(DBGPRINT)0x83E5541F; char str[] = "Hello GuiShou!";void __declspec(naked) IdtEntry() {__asm{push 0x30;pop fs;sti;}//g_pool=ExAllocatePool(0, 4096);MyDbgPrint(str);__asm{push 0x3B;pop fs;iretd;} }

運(yùn)行程序以后

在windbg窗口打印出了我們設(shè)置好的字符串,說明API調(diào)用成功

修復(fù)一個(gè)潛在問題

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

仔細(xì)觀察我們寫的這幾句還原FS段選擇子返回三環(huán)的代碼,實(shí)際上是有問題的。

在pop fs這句代碼執(zhí)行完成之后,iretd執(zhí)行之前;依然是開啟中斷的狀態(tài),那么意味著這兩行匯編指令之間CPU有可能收到時(shí)鐘中斷,造成線程切換。

而線程切換需要用的FS寄存器的值,然而FS這個(gè)時(shí)候是一個(gè)三環(huán)的段選擇子,而我們現(xiàn)在卻處在一個(gè)零環(huán)的環(huán)境下,FS需要指向KPCR,但是卻沒有指向那個(gè)位置。

就是說如果在指向這兩句代碼之間發(fā)生了線程切換,就會發(fā)生藍(lán)屏。盡管產(chǎn)生這個(gè)問題的幾率很小,但是依然不能忽視。

復(fù)現(xiàn)問題

接下來我們稍微修改一下代碼,就能復(fù)現(xiàn)這個(gè)問題:

void go() {while(1)__asm int 0x20; }

我們在int 0x20指令加上一條死循環(huán)。當(dāng)CPU產(chǎn)生int 20異常時(shí),會進(jìn)入到我們設(shè)置好的IdtEntry函數(shù)提權(quán)到零環(huán),然后IdtEntry函數(shù)會重新返回到三環(huán)。接著由于int 0x20這條指令是在死循環(huán)里面。所以這個(gè)程序就會一直在三環(huán)和零環(huán)之前往返。這就會大大增加在push 0x2B;pop fs這兩句代碼之間發(fā)生線程切換的幾率。

運(yùn)行程序,在不連接調(diào)試器的情況下會直接藍(lán)屏,如果連接上調(diào)試器則虛擬機(jī)會出現(xiàn)卡死現(xiàn)象。

解決的方法很簡單,就是讓CPU在執(zhí)行這兩句代碼時(shí)不接收硬件中斷

在恢復(fù)FS寄存器之前關(guān)閉中斷,即可解決問題,事實(shí)上KiFastCallEntry也是這么做的

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

再次運(yùn)行程序,此時(shí)依然是死循環(huán),但是因?yàn)橐呀?jīng)關(guān)閉了中斷,所以循環(huán)往返三環(huán)和零環(huán)都是安全的,不會發(fā)生藍(lán)屏和卡死的現(xiàn)象。

完整代碼

最后附上完整的實(shí)驗(yàn)代碼

#include "pch.h" #include <iostream> #include <stdio.h> #include <stdlib.h> #include <windows.h>typedef DWORD (__stdcall *EX_ALLOCATE)(DWORD PoolType, DWORD NumberOfBytes); EX_ALLOCATE ExAllocatePool= (EX_ALLOCATE)0x83E51976; DWORD g_pool;typedef DWORD ( __cdecl *DBGPRINT)(char* Format, ...); DBGPRINT MyDbgPrint=(DBGPRINT)0x83E5541F; char str[] = "Hello GuiShou!";void __declspec(naked) IdtEntry() {__asm{push 0x30;pop fs;sti;}//g_pool=ExAllocatePool(0, 4096);//MyDbgPrint(str);__asm cli;__asm{push 0x3B;pop fs;iretd;} } void go() {while(1)__asm int 0x20; }//eq 80b95500 0040ee00`00081040 int main() {if ((DWORD)IdtEntry != 0x401040){printf("wrong addr:%p", IdtEntry);exit(-1);}go();//printf("%p\n", g_pool);system("pause"); } 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

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

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