ms文档上说明:
KeSetSystemAffinityThread routine
The KeSetSystemAffinityThread routine sets the system affinity of the current thread.
Syntax
C++
VOID KeSetSystemAffinityThread(
_In_ KAFFINITY Affinity
);
Parameters
Affinity [in]
A KAFFINITY-typed variable that specifies the new system affinity of the current thread.
KeSetSystemAffinityThread例程设置当前线程的 system affinity(系统关联性)
参数是一个KAFFINITY 即是unsigned long类型变量
说白了就是指定当前线程运行在哪个cpu核心上
让我们来看看这个函数做了什么?【32 xp,ntoskrnl.exe 文件中 】
.text:0042DC7E _KeSetSystemAffinityThread@4 db 8Bh ;
.text:0042DC7E ; CODE XREF: PopSetPerfFlagAndUpdateThrottle(x,x,x)+1Dp
.text:0042DC7E ; KeConnectInterrupt(x)+3Fp ...
.text:0042DC7F ; ---------------------------------------------------------------------------
.text:0042DC7F call dword ptr [ebp-75h]
.text:0042DC82 in al, dx
.text:0042DC83 push ebx
.text:0042DC84 push esi
.text:0042DC85 push edi
.text:0042DC86 mov eax, large fs:124h ; 内核中fs:[0]指向了 当前cpu核心 的 KPCR 结构体
.text:0042DC8C mov esi, eax ; fs:[124]表示的是当前cpu核心上运行着的线程kthread结构体
.text:0042DC8E call ds:__imp__KeRaiseIrqlToDpcLevel@0 ; KeRaiseIrqlToDpcLevel()
.text:0042DC94 mov bl, al
.text:0042DC96 mov eax, [ebp+8]
.text:0042DC99 lea ecx, [esi+124h] ; 获取当前线程的kthread. Affinity 的地址
.text:0042DC9F mov [ecx], eax ; 用传入的参数设置kthread. Affinity
.text:0042DCA1 mov byte ptr [esi+0DCh], 1 ; 并设置当前线程的kthread.SystemAffinityActive 1,表示启用
.text:0042DCA1 ; SystemAffinityActive
.text:0042DCA8 db 3Eh
.text:0042DCA8 mov eax, ds:0FFDFF020h ; 0XFFDF F000表示的是 cpu0 的 KPCR
.text:0042DCA8 ; nt!_KPCR
.text:0042DCA8 ; +0x000 NtTib : _NT_TIB
.text:0042DCA8 ; +0x01c SelfPcr : Ptr32 _KPCR
.text:0042DCA8 ; +0x020 Prcb : Ptr32 _KPRCB
.text:0042DCA8 ; +0x024 Irql : UChar
.text:0042DCA8 ; +0x028 IRR : Uint4B
.text:0042DCA8 ; +0x02c IrrActive : Uint4B
.text:0042DCA8 ; +0x030 IDR : Uint4B
.text:0042DCA8 ; +0x034 KdVersionBlock : Ptr32 Void
.text:0042DCA8 ; +0x038 IDT : Ptr32 _KIDTENTRY
.text:0042DCA8 ; +0x03c GDT : Ptr32 _KGDTENTRY
.text:0042DCA8 ; +0x040 TSS : Ptr32 _KTSS
.text:0042DCA8 ; +0x044 MajorVersion : Uint2B
.text:0042DCA8 ; +0x046 MinorVersion : Uint2B
.text:0042DCA8 ; +0x048 SetMember : Uint4B
.text:0042DCA8 ; +0x04c StallScaleFactor : Uint4B
.text:0042DCA8 ; +0x050 DebugActive : UChar
.text:0042DCA8 ; +0x051 Number : UChar
.text:0042DCA8 ; +0x052 Spare0 : UChar
.text:0042DCA8 ; +0x053 SecondLevelCacheAssociativity : UChar
.text:0042DCA8 ; +0x054 VdmAlert : Uint4B
.text:0042DCA8 ; +0x058 KernelReserved : [14] Uint4B
.text:0042DCA8 ; +0x090 SecondLevelCacheSize : Uint4B
.text:0042DCA8 ; +0x094 HalReserved : [16] Uint4B
.text:0042DCA8 ; +0x0d4 InterruptMode : Uint4B
.text:0042DCA8 ; +0x0d8 Spare1 : UChar
.text:0042DCA8 ; +0x0dc KernelRe
.text:0042DCAE mov edi, eax ; edi指向此KPCR的 KPRCB结构体
.text:0042DCB0 mov eax, [edi+14h]
.text:0042DCB3 test [ecx], eax ; 用传入的AFFINITY参数去比较 KPRCB.SetMember
.text:0042DCB5 jz loc_44646D
.text:0042DCBB
.text:0042DCBB loc_42DCBB: ; CODE XREF: .text:00446471j
.text:0042DCBB ; .text:0044648Aj
.text:0042DCBB mov cl, bl
.text:0042DCBD call @KiUnlockDispatcherDatabase@4 ; KiUnlockDispatcherDatabase(x)
.text:0042DCC2 pop edi
.text:0042DCC3 pop esi
.text:0042DCC4 pop ebx
.text:0042DCC5 pop ebp
.text:0042DCC6 retn 4
.text:0044646D loc_44646D: ; CODE XREF: .text:0042DCB5j
.text:0044646D cmp dword ptr [edi+8], 0 ; 检查KPRCB.NextThread 是否为空
.text:00446471 jnz loc_42DCBB
.text:00446477 movzx ecx, byte ptr [esi+12Bh] ; 为空的话,就去看看当前线程的kthread.NextProcessor
.text:0044647E call @KiSelectNextThread@4 ; KiSelectNextThread(x)
.text:00446483 mov byte ptr [eax+2Dh], 3 ; 看名字是,为当前没有下一个运行线程的cpu 选择出一个线程,
.text:00446483 ; 并设置线程kthread.State 为3
.text:00446487 mov [edi+8], eax ; 设置 cpu0 的 KPRCB.NextThread为刚才
.text:00446487 ; 选出的kthread
.text:0044648A jmp loc_42DCBB
看着这个函数仅仅 获取当前线程的kthread结构体,然后设置相关affinity相关字段,然后跑去弄别的 cpu0 KPCR?
在用Windbg上看 dd KiProcessorBlock L1 查看
第一个就是 KPRCB 就 就是 ffdff120
减去 0X120就是 CPU0 对应的 KPCR结构体,为什么?我也不知道。。。。