[Windows] 在 Driver 中使用 KeSetPriorityThread 設定執行緒的優先權
今天在上一堂 Windows driver 的課,聽這種 Windows internals 的東西,
對平常都只是寫應用程式的我來說,真的是難度很高,
不過聽一聽也是挺有意思的,至少看起來 driver 的神秘面紗是有減少一些些~
像今天的一個 lab 練習,是要在 driver 中,在 driver 有資料被寫進來時,
把呼叫 driver 的那根 thread 的執行優先權 (priority) 提高 +5~
要寫出一個 driver 的基本外框我是還不會,不過要改老師提供的範例程式還可以玩玩看…
先看一下範例中,Read 函式的實作~
基本上這個 Read() 函式沒做太多事情,就只是將讀取的次數加 1,
接著就將目前處理中的 IRP (I/O request packet) 設定成處理完畢了:
NTSTATUS NothingRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION ioStackLocation; PNOTHING_DEVICE_EXT devExt; ioStackLocation = IoGetCurrentIrpStackLocation(Irp); #if DBG DbgPrint("NothingRead: Starting\n"); #endif devExt = (PNOTHING_DEVICE_EXT)DeviceObject->DeviceExtension; // // Increment the number of reads processed for this device // InterlockedIncrement(&devExt->ReadsProcessed); // // Complete the IRP with success. Note that we have transferred // no data back to the user. // Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); #if DBG DbgPrint("NothingRead: Leaving\n"); #endif return(STATUS_SUCCESS); }
我做的修改,就是在 #if DBG 那邊加幾行程式~
首先用 KeGetCurrentThread() 取得目前執行中的 thread (PKTHREAD),
接著就可以用 KeQueryPriorityThread() 來查詢這根 thread 的優先權,
最後將優先權加 5 之後,用 KeSetPriorityThread() 來調整優先權:
#if DBG DbgPrint("NothingRead: Starting\n"); // DbgBreakPoint(); PKTHREAD pThread = KeGetCurrentThread(); DbgPrint("pThread=%p\n", pThread); KPRIORITY pri = KeQueryPriorityThread(pThread); KeSetPriorityThread(pThread, pri+5); #endif
用 Windbg 來單步執行看看效果…
首先印出目前的 pThread 的值是 85421030:
kd> p pThread=85421030 Nothing!NothingRead+0x6e: 9dde821e 6a1f push 1Fh
用 !thread 指令看一下這根 thread,目前的優先權 (Priority) 是 11:
kd> !thread 85421030 THREAD 85421030 Cid 022c.0478 Teb: 7ffdf000 Win32Thread: 00000000 RUNNING on processor 0 IRP List: 85503688: (0006,0094) Flags: 00060970 Mdl: 00000000 Not impersonating DeviceMap 8c1dac30 Owning Process 84ca27d0 Image: NothingTest.exe Attached Process N/A Image: N/A Wait Start TickCount 170453 Ticks: 0 Context Switch Count 31 IdealProcessor: 0 UserTime 00:00:00.015 KernelTime 00:00:00.202 Win32 Start Address 0x00d81911 Stack Init 9ea83ed0 Current 9ea83358 Base 9ea84000 Limit 9ea81000 Call 0 Priority 11 BasePriority 8 UnusualBoost 0 ForegroundBoost 2 IoPriority 2 PagePriority 5
繼續單步執行,等執行過 KeSetPriorityThread() 後,再查詢一次這根 thread,
果真優先權已經從 11 被提昇到 11+5 = 16 了:
kd> !thread 85421030 THREAD 85421030 Cid 022c.0478 Teb: 7ffdf000 Win32Thread: 00000000 RUNNING on processor 0 IRP List: 85503688: (0006,0094) Flags: 00060970 Mdl: 00000000 Not impersonating DeviceMap 8c1dac30 Owning Process 84ca27d0 Image: NothingTest.exe Attached Process N/A Image: N/A Wait Start TickCount 170457 Ticks: 0 Context Switch Count 34 IdealProcessor: 0 UserTime 00:00:00.015 KernelTime 00:00:00.265 Win32 Start Address 0x00d81911 Stack Init 9ea83ed0 Current 9ea83a5c Base 9ea84000 Limit 9ea81000 Call 0 Priority 16 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
不過雖然只有短短的幾行程式修改,對我來說就已經挺困難的了,
因為我連那些 PKTHREAD 的結構、或是 KeXXX() 會傳回或輸入什麼東西,都非常不熟…
真的是完全不同的領域呀~不過也勾起我的學習興趣了說 ^^/