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