多CPU下安全inline hook
2012-11-22 13:51
225 查看
去師父神牛的空間里看了下關於内核安全inline hook的討論,感覺受益匪淺,查閲資料后,得知了一種CPU中較爲安全的安裝鈎子的方法。
該代碼來自《Rootkits:Subverting the Windows Kernel》一書,原理是通過向所有非當前的CPU插入DPC,並且在DPC例程中實現忙等待,這是一種比較可愛的方法(PS:雖然我還是糾結于,如果其他CPU當前就已經在執行DPC那不是情況會非常複雜嗎。。。)
Windows使用軟件中斷優先級,稱爲IRQL(Interrupt Request Level,中斷請求級別),Windows定義IRQL的範圍是0~31,數字越大,優先級越高。處理器執行時,擁有一個當前的IRQL,當發生中斷時,如果中斷的IRQL大於當前IRQL,當前執行會被打斷,處理器轉向執行中斷代碼,然後再根據需要繼續執行。IRQL最低是PASSIVE_LEVEL(0),也就是被動級別,普通的綫程都運行于這個級別,正因為這個級別最低,所以可以被所有更高的IRQL的例程打斷。比PASSIVE_LEVEL高的是APC_LEVEL(1),通常是APC(Asynchronous
Procedure Call,異步過程調用)的等級。然後是DISPATCH_LEVEL(2),,通常被用於DPC(Deferred Procedure Call,延遲過程調用)或者綫程的調度。3~26是設備IRQL,27-31是一些硬件的中斷。DPC一般用於處理一些需要高優先級,但是又不是非常緊急的事務,而APC一般適用於綫程異步通知。
下面是來自書上的代碼以及我寫的一些:
該代碼來自《Rootkits:Subverting the Windows Kernel》一書,原理是通過向所有非當前的CPU插入DPC,並且在DPC例程中實現忙等待,這是一種比較可愛的方法(PS:雖然我還是糾結于,如果其他CPU當前就已經在執行DPC那不是情況會非常複雜嗎。。。)
Windows使用軟件中斷優先級,稱爲IRQL(Interrupt Request Level,中斷請求級別),Windows定義IRQL的範圍是0~31,數字越大,優先級越高。處理器執行時,擁有一個當前的IRQL,當發生中斷時,如果中斷的IRQL大於當前IRQL,當前執行會被打斷,處理器轉向執行中斷代碼,然後再根據需要繼續執行。IRQL最低是PASSIVE_LEVEL(0),也就是被動級別,普通的綫程都運行于這個級別,正因為這個級別最低,所以可以被所有更高的IRQL的例程打斷。比PASSIVE_LEVEL高的是APC_LEVEL(1),通常是APC(Asynchronous
Procedure Call,異步過程調用)的等級。然後是DISPATCH_LEVEL(2),,通常被用於DPC(Deferred Procedure Call,延遲過程調用)或者綫程的調度。3~26是設備IRQL,27-31是一些硬件的中斷。DPC一般用於處理一些需要高優先級,但是又不是非常緊急的事務,而APC一般適用於綫程異步通知。
下面是來自書上的代碼以及我寫的一些:
//Source code from <Rootkits:Subverting the Windows Kernel>, Chapter 7 PKDPC GainExclusivity() { NTSTATUS ns; ULONG u_currentCPU; CCHAR i; PKDPC pkdpc, temp_pkdpc; if (KeGetCurrentIrql() != DISPATCH_LEVEL) return NULL; InterlockedAnd(&AllCPURaised, 0); //AllCPURaised = 0 InterlockedAnd(&NumberOfRaisedCPU, 0); //NumberOfRaisedCPU = 0 temp_pkdpc = (PKDPC) ExAllocatePool(NonPagedPool, KeNumberProcessors * sizeof(KDPC)); //分配處理器對應數量的 if (temp_pkdpc == NULL) return NULL; u_currentCPU = KeGetCurrentProcessorNumber(); //獲取當前CPU號 pkdpc = temp_pkdpc; for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++) { if (i != u_currentCPU) { KeInitializeDpc(temp_pkdpc, RaiseCPUIrqlAndWait, NULL); KeSetTargetProcessorDpc(temp_pkdpc, i); KeInsertQueueDpc(temp_pkdpc, NULL, NULL); //對所有非當前CPU插入一個dpc } } while (InterlockedCompareExchange(&NumberOfRaisedCPU, KeNumberProcessors - 1, KeNumberProcessors - 1) != KeNumberProcessors - 1) //所有CPU都在忙等待 { __asm nop; } return pkdpc;//返回分配的内存等待釋放 } //DPC例程 VOID RaiseCPUIrqlAndWait(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { InterlockedIncrement(&NumberOfRaisedCPU); //宣佈挂起 while (!InterlockedCompareExchange(&AllCPURaised, 1, 1)) { __asm nop; } InterlockedDecrement(&NumberOfRaisedCPU); //宣佈釋放 } NTSTATUS ReleaseExclusivity(PVOID pkdpc) { InterlockedIncrement(&AllCPURaised); //釋放所有CPU while (InterlockedCompareExchange(&NumberOfRaisedCPU, 0, 0)) //等待所有CPU都被釋放 { __asm nop; } if (pkdpc != NULL) { ExFreePool(pkdpc); //釋放内存 pkdpc = NULL; } return STATUS_SUCCESS; } NTSTATUS InstallHook(PVOID pTarget,PVOID pSource,LONG nSize) { PKDPC pkdpc; if(pkdpc = GainExclusivity()) { //關閉寫保護 __asm { cli mov eax,cr0 push eax xor eax,0x10000 mov cr0,eax } RtlCopyMemory(pTarget,pSource,nSize); //開啓寫保護 __asm { pop eax mov cr0,eax sti } ReleaseExclusivity(pkdpc); } return STATUS_SUCCESS; }
相关文章推荐
- inline hook 多核安全相关问题随记。。。
- 多核发dpc安全inline hook
- 多核发dpc安全inline hook
- Hook :HOOK API 原理深入剖析3 - Inline(监视任意函数)
- Inline Hook检测模块到驱动
- 再谈360内核inline Hook
- 学习windows 应用层 inline hook 原理总结
- 实现Android ARM64平台下Inline Hook框架
- Ring3下Inline Hook API
- .NET 内链钩子技术(inline-hook)
- Intel CPU IME安全漏洞
- 单例的Double check问题和CPU动态调度共存时的线程安全问题。
- InlineHookSwapContext
- 检测内核已加载模块的所有导出函数是否被inlinehook
- 11.2.0.3.7打安全补丁CPUAPR2014,Patch 18139695
- 基于VC++开发InlineHook网络数据发送接收函数
- SSDT Hook的妙用-对抗ring0 inline hook
- 如何安全的Hook一个函数
- EasyHook应用层inline hook实例
- inline hook in user mode ---single thread safe ( test passed in window7 )