Windows驱动开发学习笔记(七)—— 多核同步内核重载
Windows驅動開發學習筆記(七)—— 多核同步
- 基礎知識
- 并發與同步
- 分析 InterlockedIncrement
- 原子操作相關API
- 內核文件
- 多核同步
- 臨界區
- 示例一:錯誤的臨界區
- 示例二:正確的臨界區
- 自旋鎖
- 分析 KeAcquireSpinLockAtDpcLevel
- 思考
- 內核重載
- 練習
基礎知識
并發與同步
并發:指多個線程在同時執行
- 單核:各個線程分時執行,不是真正意義上的同時
- 多核:在某一時刻,會同時有多個線程在執行
同步:保證在并發執行的環境中各個線程可以有序的執行
示例:
DWORD dwVal = 0; //全局變量某線程中的代碼:
dwVal++; //只有一行,安全嗎對應的匯編代碼:
mov eax, [0x12345678] add eax, 1 /*若當一個線程執行完這行代碼時,發生了線程切換*另一個線程在它的時間片中執行了這三行代碼*此時,0x12345678中存儲的是4*當再次發生線程切換,回到原線程,執行第三行代碼后*0x12345678鐘存儲的理應是5*然而由于在第一次發生線程切換時,eax中存儲的是4*因此在回到原線程,執行第三行代碼后,0x12345678中存儲的仍然是4*/ mov [0x12345678], eax解決方案:LOCK指令
將
add eax, 1
改為
LOCK add eax, 1
參考:kernel32.InterlockedIncrement
分析 InterlockedIncrement
原子操作相關API
InterlockedIncrement InterlockedExchangeAdd InterlockedDecrement InterlockedFlushSList InterlockedExchange InterlockedPopEntrySList InterlockedCompareExchange InterlockedPushEntrySList ...思考:如何實現多行代碼的原子操作?
關鍵代碼A //N行代碼要求原子操作 關鍵代碼B //單獨加LOCK可以嗎? 關鍵代碼C ...內核文件
描述:在同一個操作系統中,單核模式和多核模式的內核文件(ntoskrnl.exe)會有一點小區別
多核同步
臨界區
描述:一次只允許一個線程進入直到離開
示例一:錯誤的臨界區
//實現臨界區的方式就是加鎖 //鎖:全局變量,進去加一,出去減一 DWORD dwFlag = 0;if( dwFlag == 0) //進入臨界區 { ↑↓dwFlag = 1; //進入臨界區...dwFalg = 0; //離開臨界區 }思考:以上代碼哪里存在問題?
答案:當第一個線程進入if中,但還未執行dwFlag=1時,若發生線程切換,第二個線程仍然能夠進入if中
示例二:正確的臨界區
全局變量:
Flag = 0;進入臨界區:
Lab:mov eax,1//多核情況下必須加locklock xadd [Flag],eaxcmp eax,0jz endLabdec [Flag]//線程等待Sleep..jmp Lab endLab:ret離開臨界區:
lock dec [Flag]自旋鎖
描述:
參考:KeAcquireSpinLockAtDpcLevel
分析 KeAcquireSpinLockAtDpcLevel
思考
如何HOOK高并發的內核函數?
描述:在hook的時候如果使用memcpy等函數寫入長跳轉指令(五個字節),那么在函數內部實現中是逐個字節對內存進行修改的,若在修改的過程中有線程運行到這行指令,必然會引發錯誤,甚至藍屏
答案:
若HOOK時需要覆蓋多行指令(例如5個push指令),如何保證此時沒有線程正在執行這幾行指令而引發錯誤
答案:
使用臨界區或者自旋鎖是否可以實現多核HOOK?
答案:不能,因為使用鎖的前提是其它線程也在使用這把鎖,否則鎖是沒有意義的
內核重載
描述:
步驟:
練習
描述:通過代碼實現內核重載
答案:略(待補充)
總結
以上是生活随笔為你收集整理的Windows驱动开发学习笔记(七)—— 多核同步内核重载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows驱动开发学习笔记(六)——
- 下一篇: pwn学习总结(四)—— 堆基础知识(持