KPCR


Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html

KPCR

 1. IRQL

2. nt!KeNumberProcessors與nt!KiProcessorBlock

3. KPCR+0x34 KdVersionBlock

4. KeSetSystemAffinityThread() KeRevertToUserAffinityThread() 修改親核性

5. DPC - 主要用於看門狗

6. MiProcessLoaderEntry

7.幾個比較重要的知識點

 

1. IRQL

  在32位存儲在KPCR+0x24中,但在64位存儲在CR8寄存器中,這個要明確。

  IRQL 表示代碼運行到什么級別,之后我們會詳細說明的。

 

2. nt!KeNumberProcessors與nt!KiProcessorBlock

  KeNumberProcessors 顯示存在幾核CPU,要查看可以通過這個查看。

  

   KiProcessorBlock 顯示其對應的KPCRB結構體的地址,注意 KPCR+0x120其指向KPCRB,因此獲取KPCR要x-0x120。

  

  其中KeNumberProcessors是導出變量,直接導出使用即可。

  但是KiProcessorBlock需要手動尋找,其搜索路徑如下,之后在代碼中我們會在多核環境下遍歷該KPCR數組。

  注意:該結構僅在0號CPU中運行,因此如果查找該結構,必須通過KeSetSystemAffinityThread()切換CPU到0號,然后再來查找有關CPU。

  

 

3. KPCR+0x34 KdVersionBlock

  該成員指向一個_DBGKD_GET_VERSION64結構體(其也存在*32后綴的結構體,但是在XP以后都為_DBGKD_GET_VERSION64,其與操作系統位數無關)。

  其存在兩個重要的成員:ntoskrl.exe模塊基址,模塊加載鏈表。 我們之前講到過使用NtQuerySystem和特征碼搜索,現在又多了一種方法,這個是要明確的。

  

 

 

4. KeSetSystemAffinityThread() KeRevertToUserAffinityThread() 修改親核性

  KeSetSystemAffinityThread 當前代碼跑到幾號核CPU上,設置為多少就跑到多少核上。

  KeRevertToUserAffinityThread 恢復到原來正在跑的線程。

 

5. DPC - 主要用於看門狗

  模擬鍵盤時,1分鍾可以插入1000次,DPC級別,其DPC級別太高,則會讓線程一直來處理DPC。

  Windows操作系統設置了DPC看門狗,當運行DPC超過多少時間,就會造成藍屏。

  因此在寫模擬鍵盤鼠標時,不要插入太多,同時也不要寫延遲,這個要明確。

 

6. MiProcessLoaderEntry

  我們在驅動隱藏時看到這個函數,將驅動從鏈表中卸載,也同樣可以卸載進程和線程,注意其傳入的是一個鏈表,這個我們在之后的實驗中會看到。

 

7.幾個比較重要的知識點
  1)調用MiProcessLoaderEntry可以實現進程斷鏈,之前我們實現驅動斷鏈隱藏,但是同樣的,在這里也可以實現進程斷鏈。

    

  2)通過在2中講到的nt!KiProcessorBlock,可以在多線程下遍歷全部KPCR的數據,其代碼如下:

// 遍歷全部核的KPCR
NTSTATUS TraversProcessors() {

    // 先設置為0號CPU
    KeSetSystemAffinityThread(0);

    // 找到KiProcessorBlock,其kpcrb的數組
    PDBGKD_GET_VERSION64 pVersion;
    _asm {
        mov eax, dword ptr  fs: [0x34] ;
        mov pVersion, eax;
    }
    PULONG pDataList = (ULONG)pVersion->DebuggerDataList;
    PULONG kpcrb = (PULONG)*(PULONG)((PUCHAR)*(pDataList)+0x218);
    
    // 開始遍歷各個kpcrb中的元素找到對應的數據
    for (int i = 0; i < KeNumberProcessors; i++) {
        PULONG CurrentKPCRB = kpcrb[i];
        DbgPrint("kpcrb:%x %p\r\n", kpcrb[i],kpcrb);
        DbgPrint("第%x號CPU的IDT表地址為:%x,GDT表地址為:%x\r\n",i, MACRO_GETIDTBYKPCR(kpcrb[i]),MACRO_GETGDTBYKPCR(kpcrb[i]));
    }

    // 恢復原來的核號
    KeRevertToUserAffinityThread();
    return STATUS_SUCCESS;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM