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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

windows

Windows驱动开发学习笔记(七)—— 多核同步内核重载

發(fā)布時(shí)間:2025/3/21 windows 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows驱动开发学习笔记(七)—— 多核同步内核重载 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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]

自旋鎖

描述

  • 自旋鎖只對(duì)多核有意義
  • 自旋鎖與臨界區(qū)、事件、互斥體一樣,都是一種同步機(jī)制, 都可以讓當(dāng)前線程處于等待狀態(tài),區(qū)別在于自旋鎖不用切換線程
  • 參考: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)屏
    答案

  • 先在附近未使用的內(nèi)存空間構(gòu)造一個(gè)長(zhǎng)跳轉(zhuǎn)(五個(gè)字節(jié)),再在要hook的地方構(gòu)造一個(gè)短跳轉(zhuǎn)(一次性寫入兩個(gè)字節(jié))指向長(zhǎng)跳轉(zhuǎn)位置
  • 使用 cmpxchg8b 指令最多可一次性寫入八個(gè)字節(jié)
  • 若HOOK時(shí)需要覆蓋多行指令(例如5個(gè)push指令),如何保證此時(shí)沒有線程正在執(zhí)行這幾行指令而引發(fā)錯(cuò)誤
    答案

  • 依然是短跳轉(zhuǎn)
  • 盡量避免在這些地方進(jìn)行hook
  • 使用臨界區(qū)或者自旋鎖是否可以實(shí)現(xiàn)多核HOOK?
    答案:不能,因?yàn)槭褂面i的前提是其它線程也在使用這把鎖,否則鎖是沒有意義的

  • 內(nèi)核重載

    描述

  • 內(nèi)核中的很多函數(shù)被層層HOOK,重載一份內(nèi)核可以繞過(guò)這些HOOK
  • 內(nèi)核重載與映射PE文件的方法無(wú)異,本質(zhì)上沒有區(qū)別
  • 內(nèi)核重載就是重新加載一份內(nèi)核文件(ntkrnlpa.exe
  • 步驟

  • 申請(qǐng)內(nèi)存,按內(nèi)存對(duì)齊展開
  • 根據(jù)重定位表修復(fù)全局變量
  • 修復(fù)IAT表(修復(fù)導(dǎo)入表的說(shuō)法不準(zhǔn)確)
  • 山寨系統(tǒng)服務(wù)表
  • 貍貓換太子(Hook KiFastCallEntry)
  • 練習(xí)

    描述:通過(guò)代碼實(shí)現(xiàn)內(nèi)核重載
    答案:略(待補(bǔ)充)

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的Windows驱动开发学习笔记(七)—— 多核同步内核重载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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