搭建驅動開發環境 sdk10 wdk10
win7平臺 降低警告級別
8086CPU 16位匯編
1982年 intel退出80286處理器,第一次提出保護模式
在保護模式下,段寄存器存儲的段基址,而是段選擇子
X86體系CPU支持三種模式
實模式:兼容16位CPU的模式
保護模式:操作系統所在模式
虛擬8086模式:可以模擬多個8086執行多任務
8086處理器的段寄存器是16位,共四個:
CS,DS,ES,SS
32位處理器內,增加兩個 FS,GS
6個寄存器分為可見部分和不可見部分
不可見部分存放段的基地址,范圍和段屬性,處理器內部使用
段寄存器可見部分存儲的值稱為段選擇子
13位:描述符表索引 1位:TI 2位:RPL
TI=0 全局描述符表GDT TI=1 局部描述符表LDT(windows系統并沒有使用)
88位描述符高速緩存寄存器
描述符表中存放的是段描述符
描述符有效為P位
段限長Limit
粒度G位 0 limit字節 1 limit4KB
基地址字段base
s與TYPE s=0 系統段 1代碼段或數據段
TYPE:
0EWA 數據段 擴展方向 是否可寫 訪問位
1CRA 代碼段 一致性 可讀 訪問位
當前執行指令位置 cs eip決定
普通跨段跳轉
非一致性
cpl==dpl rpl< =dpl
一致性
cpl>=dpl
s = 0,type=110 調用門
中斷門 type=14
陷阱門 15
任務門 5
r gdtr
dp 地址
jmp far 跳轉到同級非一致代碼段
IDT 中斷門描述符 陷阱門描述符 任務門描述符
存放中斷處理函數地址 異常處理函數地址
DPL:描述符特權(Descriptor Privilege Level)
存儲在描述符中的權限位,用于描述代碼的所屬的特權等級,也就是代碼本身真正的特權級。一個程序可以使用多個段(Data,Code,Stack)也可以只用一個code段等。正常的情況下,當程序的環境建立好后,段描述符都不需要改變——當然DPL也不需要改變,因此每個段的DPL值是固定。
RPL:請求特權級RPL(Request Privilege Level)
RPL保存在選擇子的最低兩位。 RPL說明的是進程對段訪問的請求權限,意思是當前進程想要的請求權限。RPL的值由程序員自己來自由的設置,并不一定RPL>=CPL,但是當RPL<CPL時,實際起作用的就是CPL了,因為訪問時的特權檢查是判斷:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次訪問時的附加限制,RPL=0時附加限制最小,RPL=3時附加限制最大。所以你不要想通過來隨便設置一個rpl來訪問一個比cpl更內層的段。
CPL:當前任務特權(Current Privilege Level)
表示當前正在執行的代碼所處的特權級。CPL保存在CS中的最低兩位,是針對CS而言的。當選擇子成功裝入CS寄存器后,相應的選擇子中的RPL就變成了CPL。因為它的位置變了,已經被裝入到CS寄存器中了,所表達的意思也發生了變——原來的要求等級已經得到了滿足,就是當前自己的等級。
分頁機制
windows是通過頁目錄,頁表(page table)與頁表項(page table entry,pte)這種二級表的結構將虛擬地址轉譯成物理地址
頁目錄表PDT 頁目錄項PDE 頁表PTT 頁表索引PTE
頁目錄索引 頁表索引 字節索引
10 10 12
虛擬頁號
實驗 虛擬地址轉物理地址
查看記事本程序notepad.exe的進程信息
!process 0 0 notepad.exe
利用記事本的進程結構的起始地址,將windbg的當前進程切換到notepad.exe
.process 884ead40
搜索
s -u 0x00000000 L0x01000000 "hello 15pb"
查看位于本進程虛擬地址處的字符串
du 0x007c0bd4
查看一下notepad.exe進程頁目錄0x32303000
!dd 0x32303000
PTE位于0x32103000+0x3c04
!dd 0x32103000+0x3c04
X86映射表分兩級
第一級:頁目錄表
第二級:頁表
PTE與物理頁
PTE可以沒有物理頁
PTE與物理頁是多對一的關系
PDE與PTE都是4字節的數據,結構有相似性
P位 存在
R/W位 R/W = 0 只讀 R/W = 1可讀可寫
U/S:0特權用戶才能訪問 1 普通用戶,特權用戶都能訪問
P/S:只對PDE有意義
PS=1的時候 PDE直接指向物理頁無PTE,低22位是頁內偏移,所謂的大頁,一頁4MB
PS=0時,指向下一級頁表
A位:只要被訪問過一個字節,會被置為一
D位:是否被寫過,寫過就置1
PAE 物理擴展模式
PAE模式相比較傳統模式多了一個PDPTE,PAE模式下的PDE與PTE都變成了8字節
驅動編程
進程空間分為用戶空間與內核空間
驅動開發分為三類
NT WDM WDF
nt式驅動程序
1包含ntddk.h文件
2編寫一個DriverEntry入口函數
3編寫一個驅動卸載函數
NTSTATUS DriverEntry(
PDDRIVER_OBJECT driver,//驅動對象
PUNICODE_STRING path//路徑
)
卸載函數
VOID DriverUnload(PDRIEVER_OBJECT driver){}
內核編程基礎
驅動對象 設備對象 IRP io請求包(如同windows應用程序中的MSG)
程序 窗口 消息
設備對象
重要字段
DiverObject 指出設備對象屬于哪個驅動對象
NextDevice 下一個設備對象
AttachedDevice 指向下一層驅動程序的設備對象
CurrentIrp 用來決策當前IRP完成還是掛起等
DeviceExtension 指向LDR鏈指針
設備對象 發送接收 IRP
驅動對象 處理 IRP
指定自己編寫的函數所占內存的屬性
pragma alloc_text(類型,函數名)
類型
INIT 調用完即可釋放
PAGE 位于分頁內存
NONE_PAGE 位于非分頁內存
中斷請求級別 Interrupt Request Level IRQL
dispatch apc passive
字符串表達方式
RTL_CONSTANT_STRING 初始化操作
內核api前綴
IoXX
ExXX
RtlXX
ReXX
ZwXX
NtXX
內存操作
申請內存ExAllocatePool
拷貝內存RtlCopyeMemory
填充內存RtlFillMemory
釋放內存ExFreePool