Skip to content

内核漏洞学习分析及记录 #97

Description

@xinali
作者: xina1i
更新: 2025.12.12
创建: 2025.06.30

----------------------------------------------------------------
目录:
    ☆ 测试环境
    ☆ 开启内核/host调试
    ☆ hevd服务操作
    ☆ 内核相关函数    
        1) ProbeForRead
    ☆ 内核相关概念    
        1) Irp和IrpSp的区别
        2) 中断描述符表及其作用
        3) 页表项(PTE)
        4) PAGE和NONPAGE
        5) 驱动对象和设备对象
        6) EPROCESS/ETHREAD/KTHREAD
    ☆ 相关调试指令    
    ☆ 参考阅读  
----------------------------------------------------------------

内核漏洞学习分析过程中遇到的问题及相关内容记录

☆ 测试环境

----------------------------------------------------------------
host os: windows 10
guest os: windows 10 22h2 19045.2006
host ip: 192.168.10.101
----------------------------------------------------------------


☆ 开启内核/host调试

使用管理员权限执行

----------------------------------------------------------------
bcdedit /debug on
bcdedit /dbgsettings net hostip:192.168.10.101 port:50000
----------------------------------------------------------------

获取key,并将key复制到windbg中,连接方式选择net
重启guest os,正常情况下成功附加到guest os中

☆ hevd服务操作

具体操作

----------------------------------------------------------------
C:\Windows\system32>sc create HEVD binPath=c:\tmp\hevd\driver\vulnerable\x64\HEVD.sys type=kernel
[SC] CreateService 成功

C:\Windows\system32>sc start HEVD

SERVICE_NAME: HEVD
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :

----------------------------------------------------------------

☆ 开启调试输出信息

----------------------------------------------------------------
3: kd> ed nt!Kd_IHVDRIVER_Mask 8
3: kd> g

// 如下为重启hevd的信息
[-] HackSys Extreme Vulnerable Driver Unloaded
                                        
 ##     ## ######## ##     ## ########  
 ##     ## ##       ##     ## ##     ## 
 ##     ## ##       ##     ## ##     ## 
 ######### ######   ##     ## ##     ## 
 ##     ## ##        ##   ##  ##     ## 
 ##     ## ##         ## ##   ##     ## 
 ##     ## ########    ###    ########  
   HackSys Extreme Vulnerable Driver    
             Version: 3.00              
[+] HackSys Extreme Vulnerable Driver Loaded

----------------------------------------------------------------


☆ 内核相关函数

1) ProbeForRead

地址范围检查:
   首先,它会检查 UserBuffer 这个地址是否低于 MmUserProbeAddress。MmUserProbeAddress 是一个系统变量,定义了用户空间地址的上限。
   任何高于或等于此地址的都被认为是内核地址。如果 UserBuffer 指向内核空间,函数会立即失败。

遍历页表:
   接下来,它会遍历从 UserBuffer 开始,跨越 sizeof(KernelBuffer) 长度所涉及到的所有内存页面。
   对于每一个页面,它会查找对应的页表项(Page Table Entry, PTE)。

检查PTE标志位:在PTE中,它主要检查两个关键的标志位:

   Present Bit:确认该页是否在物理内存中。如果不在,访问会触发页错误。
   User/Supervisor (U/S) Bit:这是最重要的安全检查。该位决定了页面是否允许在用户模式下访问。
   ProbeForRead 会确保该位置位为 User。如果该位为 Supervisor,意味着这是一个内核页面,探测就会失败。

异常处理:
   ProbeForRead 的设计哲学是“快速失败”。如果上述任何检查失败(地址越界、页面不存在、页面是内核页面等),它不会返回一个错误码,
   而是直接引发一个异常(STATUS_ACCESS_VIOLATION)。
----------------------------------------------------------------


☆ 内核相关概念

1) Irp和IrpSp的区别

目前查询到的资料,不足以明确的说明两者的区别
Irp全局: 具体是什么 
IrpSP:局部,具体怎么做

!需要后期多理解然后不断更新该部分的内容


2) 中断描述符表及其作用

中断描述符表(IDT)是x86/x64架构处理器中一个至关重要的系统级数据结构。
它的核心功能是建立一个从中断向量(一个0到255之间的数字)到中断处理程序(Interrupt Service Routine, ISR)
或异常处理程序(Exception Handler)入口地址的映射关系。

在windbg中查看idt信息

----------------------------------------------------------------
; idt表在内存中的位置
0: kd>  r idtr
idtr=fffff8016e897000

; idt表具体的信息
0: kd> !idt

Dumping IDT: fffff8016e897000

00:	fffff80169a03a00 nt!KiDivideErrorFault
01:	fffff80169a03d40 nt!KiDebugTrapOrFault	Stack = 0xFFFFF8016E8D5000
02:	fffff80169a04240 nt!KiNmiInterrupt	Stack = 0xFFFFF8016E8C7000
03:	fffff80169a04700 nt!KiBreakpointTrap
04:	fffff80169a04a40 nt!KiOverflowTrap
05:	fffff80169a04d80 nt!KiBoundFault
06:	fffff80169a052c0 nt!KiInvalidOpcodeFault
07:	fffff80169a057c0 nt!KiNpxNotAvailableFault
08:	fffff80169a05ac0 nt!KiDoubleFaultAbort	Stack = 0xFFFFF8016E8C0000
09:	fffff80169a05dc0 nt!KiNpxSegmentOverrunAbort
0a:	fffff80169a060c0 nt!KiInvalidTssFault
0b:	fffff80169a063c0 nt!KiSegmentNotPresentFault
0c:	fffff80169a06780 nt!KiStackFault
0d:	fffff80169a06ac0 nt!KiGeneralProtectionFault
0e:	fffff80169a06e00 nt!KiPageFault
...
e1:	fffff801699ff6d0 nt!KiIpiInterrupt
e2:	fffff801699fbe70 nt!HalpInterruptLocalErrorService (KINTERRUPT fffff8016a2f3560)
e3:	fffff801699fbe78 nt!HalpInterruptDeferredRecoveryService (KINTERRUPT fffff8016a2f30e0)
fd:	fffff801699fbf48 nt!HalpTimerProfileInterrupt (KINTERRUPT fffff8016a2f3b00)
fe:	fffff801699fbf50 nt!HalpPerfInterrupt (KINTERRUPT fffff8016a2f37a0)
----------------------------------------------------------------


3) 页表项(PTE)

页表项(PTE)是操作系统用来告知CPU如何翻译一个虚拟内存地址到物理内存地址,并规定该内存访问权限的最小数据单元

CPU内部有一个专门的硬件单元,称为内存管理单元(Memory Management Unit, MMU)。
MMU就像一个翻译官,它的工作就是查询一张“翻译地图”来完成地址转换。
这张“地图”就是页表(Page Table),而地图上的每一条记录,就是页表项(PTE)

现代操作系统(如Windows, Linux)和处理器架构(如x86-64, AArch64)为了节省内存,并不会使用一张巨大的、包含所有地址映射的页表。它们采用的是多级页表结构。

以最常见的 x86-64架构 为例,地址翻译通常经过四级页表:

    页映射表等级4 (Page Map Level 4, PML4)
    页目录指针表 (Page Directory Pointer Table, PDPT)
    页目录表 (Page Directory Table, PDT)
    页表 (Page Table, PT)

一个64位的虚拟地址会被拆分成几部分,每一部分作为索引,用于在对应级别的页表中查找下一级页表的物理地址。这个过程就像这样:

CR3寄存器 -> PML4基地址 -> (用PML4索引) -> PDPT基地址 -> (用PDPT索引) -> PDT基地址 -> (用PDT索引) -> PT基地址 -> (用PT索引) -> 找到最终的PTE

这个最终找到的PTE,包含了目标物理页面的基地址和一系列重要的属性位。

在64位系统中,一个PTE通常是64位(8字节)大小,其内部并非只有一个地址,而是由物理页帧地址和一系列标志位(Flags)组成的位域结构。
这些标志位是PTE作用的核心。

比如有如下标志位

位(Bit)	 名称	                   描述
0	     P (Present)	          存在位。如果为1,表示该页在物理内存中,PTE中的地址有效。如果为0,表示页不在内存中(可能在磁盘上),访问它会触发页错误(Page Fault)异常,交由OS处理。
1	     R/W (Read/Write)	      读/写位。如果为1,该页可读可写。如果为0,该页只读。任何对只读页的写操作都会触发Page Fault。这是实现内存保护的基础。
2	     U/S (User/Supervisor)    用户/超级用户位。如果为1,用户模式(Ring 3)和内核模式(Ring 0)都可以访问。如果为0,只有内核模式可以访问。这是隔离内核空间和用户空间的关键。
3	     PWT (Page Write-Through) 控制页级别缓存策略。
4	     PCD (Page Cache Disable) 控制页级别缓存策略。
5	     A (Accessed)	          访问位。当CPU访问该页(读或写)时,硬件会自动将此位置1。OS可以定期清零此位,用于判断哪些页是“冷”数据,以决定是否将其换出到磁盘。
6	     D (Dirty)	              脏位。当CPU对该页进行写操作时,硬件会自动将此位置1。OS在换出页面时,检查此位。若为1,说明页面内容已被修改,必须先写回磁盘;若为0,则可直接丢弃。


4) PAGE和NONPAGE

(1). 非分页内存(Non-paged Pool)
   这部分内存永远不会被交换到磁盘上,它必须时刻驻留在物理RAM中。
   它是一种非常宝贵且有限的系统资源。
   必须使用非分页内存的场景:当代码需要在较高的中断请求级别(IRQL)下运行时(例如 DISPATCH_LEVEL 或更高)。
   在这些级别上,系统无法处理页错误。如果一个高IRQL的例程试图访问被分页出去的内存,系统会立刻蓝屏死机(Bug Check),
   通常是 IRQL_NOT_LESS_OR_EQUAL。
(2). 分页内存(Paged Pool)
   这部分内存可以在系统需要时被交换到磁盘的页面文件中。
   它是一种相对充裕的资源。
   使用分页内存的约束:访问分页内存的代码必须在 PASSIVE_LEVEL 的IRQL下运行。在这个级别,系统可以安全地处理和等待页错误完成。

比如

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, TriggerBufferOverflowStack)
#pragma alloc_text(PAGE, BufferOverflowStackIoctlHandler)
#endif // ALLOC_PRAGMA

将两个函数设置为PAGE


5) 驱动对象和设备对象

----------------------------------------------------------------

// 查看驱动对象
0: kd>  !drvobj HEVD
Driver object (ffffd50ee59c9e50) is for:
 \Driver\HEVD

Driver Extension List: (id , addr)

Device Object list:
ffffd50ee5586300  

// 查看对象具体信息
0: kd> !devobj ffffd50ee5586300
Device object (ffffd50ee5586300) is for:
 HackSysExtremeVulnerableDriver \Driver\HEVD DriverObject ffffd50ee59c9e50
Current Irp 00000000 RefCount 0 Type 00000022 Flags 00000050
SecurityDescriptor ffff9a8d03f36a60 DevExt 00000000 DevObjExt ffffd50ee5586450 
ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
Characteristics (0x00000100)  FILE_DEVICE_SECURE_OPEN
Device queue is not busy.
----------------------------------------------------------------

系统在加载过程中,驱动对象和设备对象的载入流程

系统加载 mydriver.sys 
   -> 系统创建 DRIVER_OBJECT 
      -> 系统调用 DriverEntry(pDriverObject, ...) 
         -> 在 DriverEntry 或 AddDevice 中,驱动调用 IoCreateDevice(pDriverObject, ...) 
            创建一个或多个 DEVICE_OBJECT,并把它们链接到 pDriverObject->DeviceObject 链表上


6) EPROCESS/KPROCESS/ETHREAD/KTHREAD

一个进程(EPROCESS)包含一个或多个线程 (ETHREAD)。每一个ETHREAD结构都包含一个KTHREAD结构。
EPROCESS是进程的容器,ETHREAD是线程的容器,而 KTHREAD则是线程最核心的执行单元。

EPROCESS核心关键成员
进程身份与关系:
    UniqueProcessId: 进程ID (PID)。进程最直接的标识。
    InheritedFromUniqueProcessId: 父进程ID (PPID)。用于追踪进程创建链。
    ImageFileName: 进程的映像文件名(如svchost.exe)。用于快速识别进程身份。
    ActiveProcessLinks: _LIST_ENTRY结构,将系统所有活动进程的EPROCESS链接成一个双向链表。
安全上下文:
    Token: _EX_FAST_REF结构,指向该进程的安全访问令牌Access Token)。这是权限提升漏洞利用的最终目标。
           修改这个字段就是"Token Stealing"的核心操作。
资源管理:
    ObjectTable: 指向该进程的句柄表(Handle Table),管理着进程打开的所有内核对象(文件、注册表键、事件等)。
    Vm: _MMSUPPORT结构,描述了进程的整个虚拟地址空间。分析内存相关的漏洞时至关重要。
内核与执行体组件:
    Pcb: _KPROCESS (内核进程) 结构。EPROCESS是执行体层面的结构,
        它内嵌了内核层面的_KPROCESS结构,Pcb是Process Control Block的缩写。

--------------------------------------------------------------------
0: kd> dt _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x438 ProcessLock      : _EX_PUSH_LOCK
   +0x440 UniqueProcessId  : Ptr64 Void
   +0x448 ActiveProcessLinks : _LIST_ENTRY
   +0x458 RundownProtect   : _EX_RUNDOWN_REF
   +0x460 Flags2           : Uint4B
   +0x460 JobNotReallyActive : Pos 0, 1 Bit
   +0x460 AccountingFolded : Pos 1, 1 Bit
   +0x460 NewProcessReported : Pos 2, 1 Bit
   +0x460 ExitProcessReported : Pos 3, 1 Bit
   +0x460 ReportCommitChanges : Pos 4, 1 Bit
   +0x460 LastReportMemory : Pos 5, 1 Bit
   +0x460 ForceWakeCharge  : Pos 6, 1 Bit
   +0x460 CrossSessionCreate : Pos 7, 1 Bit
   +0x460 NeedsHandleRundown : Pos 8, 1 Bit
   +0x460 RefTraceEnabled  : Pos 9, 1 Bit
   +0x460 PicoCreated      : Pos 10, 1 Bit
   +0x460 EmptyJobEvaluated : Pos 11, 1 Bit
   +0x460 DefaultPagePriority : Pos 12, 3 Bits
   +0x460 PrimaryTokenFrozen : Pos 15, 1 Bit
   +0x460 ProcessVerifierTarget : Pos 16, 1 Bit
   +0x460 RestrictSetThreadContext : Pos 17, 1 Bit
   +0x460 AffinityPermanent : Pos 18, 1 Bit
   +0x460 AffinityUpdateEnable : Pos 19, 1 Bit
   +0x460 PropagateNode    : Pos 20, 1 Bit
   +0x460 ExplicitAffinity : Pos 21, 1 Bit
   +0x460 ProcessExecutionState : Pos 22, 2 Bits
   +0x460 EnableReadVmLogging : Pos 24, 1 Bit
   +0x460 EnableWriteVmLogging : Pos 25, 1 Bit
   +0x460 FatalAccessTerminationRequested : Pos 26, 1 Bit
   +0x460 DisableSystemAllowedCpuSet : Pos 27, 1 Bit
   +0x460 ProcessStateChangeRequest : Pos 28, 2 Bits
   +0x460 ProcessStateChangeInProgress : Pos 30, 1 Bit
   +0x460 InPrivate        : Pos 31, 1 Bit
   +0x464 Flags            : Uint4B
   +0x464 CreateReported   : Pos 0, 1 Bit
   +0x464 NoDebugInherit   : Pos 1, 1 Bit
   +0x464 ProcessExiting   : Pos 2, 1 Bit
   +0x464 ProcessDelete    : Pos 3, 1 Bit
   +0x464 ManageExecutableMemoryWrites : Pos 4, 1 Bit
   +0x464 VmDeleted        : Pos 5, 1 Bit
   +0x464 OutswapEnabled   : Pos 6, 1 Bit
   +0x464 Outswapped       : Pos 7, 1 Bit
   +0x464 FailFastOnCommitFail : Pos 8, 1 Bit
   +0x464 Wow64VaSpace4Gb  : Pos 9, 1 Bit
   +0x464 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x464 SetTimerResolution : Pos 12, 1 Bit
   +0x464 BreakOnTermination : Pos 13, 1 Bit
   +0x464 DeprioritizeViews : Pos 14, 1 Bit
   +0x464 WriteWatch       : Pos 15, 1 Bit
   +0x464 ProcessInSession : Pos 16, 1 Bit
   +0x464 OverrideAddressSpace : Pos 17, 1 Bit
   +0x464 HasAddressSpace  : Pos 18, 1 Bit
   +0x464 LaunchPrefetched : Pos 19, 1 Bit
   +0x464 Background       : Pos 20, 1 Bit
   +0x464 VmTopDown        : Pos 21, 1 Bit
   +0x464 ImageNotifyDone  : Pos 22, 1 Bit
   +0x464 PdeUpdateNeeded  : Pos 23, 1 Bit
   +0x464 VdmAllowed       : Pos 24, 1 Bit
   +0x464 ProcessRundown   : Pos 25, 1 Bit
   +0x464 ProcessInserted  : Pos 26, 1 Bit
   +0x464 DefaultIoPriority : Pos 27, 3 Bits
   +0x464 ProcessSelfDelete : Pos 30, 1 Bit
   +0x464 SetTimerResolutionLink : Pos 31, 1 Bit
   +0x468 CreateTime       : _LARGE_INTEGER
   +0x470 ProcessQuotaUsage : [2] Uint8B
   +0x480 ProcessQuotaPeak : [2] Uint8B
   +0x490 PeakVirtualSize  : Uint8B
   +0x498 VirtualSize      : Uint8B
   +0x4a0 SessionProcessLinks : _LIST_ENTRY
   +0x4b0 ExceptionPortData : Ptr64 Void
   +0x4b0 ExceptionPortValue : Uint8B
   +0x4b0 ExceptionPortState : Pos 0, 3 Bits
   +0x4b8 Token            : _EX_FAST_REF
   +0x4c0 MmReserved       : Uint8B
   +0x4c8 AddressCreationLock : _EX_PUSH_LOCK
   +0x4d0 PageTableCommitmentLock : _EX_PUSH_LOCK
   +0x4d8 RotateInProgress : Ptr64 _ETHREAD
   +0x4e0 ForkInProgress   : Ptr64 _ETHREAD
   +0x4e8 CommitChargeJob  : Ptr64 _EJOB
   +0x4f0 CloneRoot        : _RTL_AVL_TREE
   +0x4f8 NumberOfPrivatePages : Uint8B
   +0x500 NumberOfLockedPages : Uint8B
   +0x508 Win32Process     : Ptr64 Void
   +0x510 Job              : Ptr64 _EJOB
   +0x518 SectionObject    : Ptr64 Void
   +0x520 SectionBaseAddress : Ptr64 Void
   +0x528 Cookie           : Uint4B
   +0x530 WorkingSetWatch  : Ptr64 _PAGEFAULT_HISTORY
   +0x538 Win32WindowStation : Ptr64 Void
   +0x540 InheritedFromUniqueProcessId : Ptr64 Void
   +0x548 OwnerProcessId   : Uint8B
   +0x550 Peb              : Ptr64 _PEB
   +0x558 Session          : Ptr64 _MM_SESSION_SPACE
   +0x560 Spare1           : Ptr64 Void
   +0x568 QuotaBlock       : Ptr64 _EPROCESS_QUOTA_BLOCK
   +0x570 ObjectTable      : Ptr64 _HANDLE_TABLE
   +0x578 DebugPort        : Ptr64 Void
   +0x580 WoW64Process     : Ptr64 _EWOW64PROCESS
   +0x588 DeviceMap        : Ptr64 Void
   +0x590 EtwDataSource    : Ptr64 Void
   +0x598 PageDirectoryPte : Uint8B
   +0x5a0 ImageFilePointer : Ptr64 _FILE_OBJECT
   +0x5a8 ImageFileName    : [15] UChar
   +0x5b7 PriorityClass    : UChar
   +0x5b8 SecurityPort     : Ptr64 Void
   +0x5c0 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x5c8 JobLinks         : _LIST_ENTRY
   +0x5d8 HighestUserAddress : Ptr64 Void
   +0x5e0 ThreadListHead   : _LIST_ENTRY
   +0x5f0 ActiveThreads    : Uint4B
   +0x5f4 ImagePathHash    : Uint4B
   +0x5f8 DefaultHardErrorProcessing : Uint4B
   +0x5fc LastThreadExitStatus : Int4B
   +0x600 PrefetchTrace    : _EX_FAST_REF
   +0x608 LockedPagesList  : Ptr64 Void
   +0x610 ReadOperationCount : _LARGE_INTEGER
   +0x618 WriteOperationCount : _LARGE_INTEGER
   +0x620 OtherOperationCount : _LARGE_INTEGER
   +0x628 ReadTransferCount : _LARGE_INTEGER
   +0x630 WriteTransferCount : _LARGE_INTEGER
   +0x638 OtherTransferCount : _LARGE_INTEGER
   +0x640 CommitChargeLimit : Uint8B
   +0x648 CommitCharge     : Uint8B
   +0x650 CommitChargePeak : Uint8B
   +0x680 Vm               : _MMSUPPORT_FULL
   +0x7c0 MmProcessLinks   : _LIST_ENTRY
   +0x7d0 ModifiedPageCount : Uint4B
   +0x7d4 ExitStatus       : Int4B
   +0x7d8 VadRoot          : _RTL_AVL_TREE
   +0x7e0 VadHint          : Ptr64 Void
   +0x7e8 VadCount         : Uint8B
   +0x7f0 VadPhysicalPages : Uint8B
   +0x7f8 VadPhysicalPagesLimit : Uint8B
   +0x800 AlpcContext      : _ALPC_PROCESS_CONTEXT
   +0x820 TimerResolutionLink : _LIST_ENTRY
   +0x830 TimerResolutionStackRecord : Ptr64 _PO_DIAG_STACK_RECORD
   +0x838 RequestedTimerResolution : Uint4B
   +0x83c SmallestTimerResolution : Uint4B
   +0x840 ExitTime         : _LARGE_INTEGER
   +0x848 InvertedFunctionTable : Ptr64 _INVERTED_FUNCTION_TABLE
   +0x850 InvertedFunctionTableLock : _EX_PUSH_LOCK
   +0x858 ActiveThreadsHighWatermark : Uint4B
   +0x85c LargePrivateVadCount : Uint4B
   +0x860 ThreadListLock   : _EX_PUSH_LOCK
   +0x868 WnfContext       : Ptr64 Void
   +0x870 ServerSilo       : Ptr64 _EJOB
   +0x878 SignatureLevel   : UChar
   +0x879 SectionSignatureLevel : UChar
   +0x87a Protection       : _PS_PROTECTION
   +0x87b HangCount        : Pos 0, 3 Bits
   +0x87b GhostCount       : Pos 3, 3 Bits
   +0x87b PrefilterException : Pos 6, 1 Bit
   +0x87c Flags3           : Uint4B
   +0x87c Minimal          : Pos 0, 1 Bit
   +0x87c ReplacingPageRoot : Pos 1, 1 Bit
   +0x87c Crashed          : Pos 2, 1 Bit
   +0x87c JobVadsAreTracked : Pos 3, 1 Bit
   +0x87c VadTrackingDisabled : Pos 4, 1 Bit
   +0x87c AuxiliaryProcess : Pos 5, 1 Bit
   +0x87c SubsystemProcess : Pos 6, 1 Bit
   +0x87c IndirectCpuSets  : Pos 7, 1 Bit
   +0x87c RelinquishedCommit : Pos 8, 1 Bit
   +0x87c HighGraphicsPriority : Pos 9, 1 Bit
   +0x87c CommitFailLogged : Pos 10, 1 Bit
   +0x87c ReserveFailLogged : Pos 11, 1 Bit
   +0x87c SystemProcess    : Pos 12, 1 Bit
   +0x87c HideImageBaseAddresses : Pos 13, 1 Bit
   +0x87c AddressPolicyFrozen : Pos 14, 1 Bit
   +0x87c ProcessFirstResume : Pos 15, 1 Bit
   +0x87c ForegroundExternal : Pos 16, 1 Bit
   +0x87c ForegroundSystem : Pos 17, 1 Bit
   +0x87c HighMemoryPriority : Pos 18, 1 Bit
   +0x87c EnableProcessSuspendResumeLogging : Pos 19, 1 Bit
   +0x87c EnableThreadSuspendResumeLogging : Pos 20, 1 Bit
   +0x87c SecurityDomainChanged : Pos 21, 1 Bit
   +0x87c SecurityFreezeComplete : Pos 22, 1 Bit
   +0x87c VmProcessorHost  : Pos 23, 1 Bit
   +0x87c VmProcessorHostTransition : Pos 24, 1 Bit
   +0x87c AltSyscall       : Pos 25, 1 Bit
   +0x87c TimerResolutionIgnore : Pos 26, 1 Bit
   +0x87c DisallowUserTerminate : Pos 27, 1 Bit
   +0x880 DeviceAsid       : Int4B
   +0x888 SvmData          : Ptr64 Void
   +0x890 SvmProcessLock   : _EX_PUSH_LOCK
   +0x898 SvmLock          : Uint8B
   +0x8a0 SvmProcessDeviceListHead : _LIST_ENTRY
   +0x8b0 LastFreezeInterruptTime : Uint8B
   +0x8b8 DiskCounters     : Ptr64 _PROCESS_DISK_COUNTERS
   +0x8c0 PicoContext      : Ptr64 Void
   +0x8c8 EnclaveTable     : Ptr64 Void
   +0x8d0 EnclaveNumber    : Uint8B
   +0x8d8 EnclaveLock      : _EX_PUSH_LOCK
   +0x8e0 HighPriorityFaultsAllowed : Uint4B
   +0x8e8 EnergyContext    : Ptr64 _PO_PROCESS_ENERGY_CONTEXT
   +0x8f0 VmContext        : Ptr64 Void
   +0x8f8 SequenceNumber   : Uint8B
   +0x900 CreateInterruptTime : Uint8B
   +0x908 CreateUnbiasedInterruptTime : Uint8B
   +0x910 TotalUnbiasedFrozenTime : Uint8B
   +0x918 LastAppStateUpdateTime : Uint8B
   +0x920 LastAppStateUptime : Pos 0, 61 Bits
   +0x920 LastAppState     : Pos 61, 3 Bits
   +0x928 SharedCommitCharge : Uint8B
   +0x930 SharedCommitLock : _EX_PUSH_LOCK
   +0x938 SharedCommitLinks : _LIST_ENTRY
   +0x948 AllowedCpuSets   : Uint8B
   +0x950 DefaultCpuSets   : Uint8B
   +0x948 AllowedCpuSetsIndirect : Ptr64 Uint8B
   +0x950 DefaultCpuSetsIndirect : Ptr64 Uint8B
   +0x958 DiskIoAttribution : Ptr64 Void
   +0x960 DxgProcess       : Ptr64 Void
   +0x968 Win32KFilterSet  : Uint4B
   +0x970 ProcessTimerDelay : _PS_INTERLOCKED_TIMER_DELAY_VALUES
   +0x978 KTimerSets       : Uint4B
   +0x97c KTimer2Sets      : Uint4B
   +0x980 ThreadTimerSets  : Uint4B
   +0x988 VirtualTimerListLock : Uint8B
   +0x990 VirtualTimerListHead : _LIST_ENTRY
   +0x9a0 WakeChannel      : _WNF_STATE_NAME
   +0x9a0 WakeInfo         : _PS_PROCESS_WAKE_INFORMATION
   +0x9d0 MitigationFlags  : Uint4B
   +0x9d0 MitigationFlagsValues : <anonymous-tag>
   +0x9d4 MitigationFlags2 : Uint4B
   +0x9d4 MitigationFlags2Values : <anonymous-tag>
   +0x9d8 PartitionObject  : Ptr64 Void
   +0x9e0 SecurityDomain   : Uint8B
   +0x9e8 ParentSecurityDomain : Uint8B
   +0x9f0 CoverageSamplerContext : Ptr64 Void
   +0x9f8 MmHotPatchContext : Ptr64 Void
   +0xa00 DynamicEHContinuationTargetsTree : _RTL_AVL_TREE
   +0xa08 DynamicEHContinuationTargetsLock : _EX_PUSH_LOCK
   +0xa10 DynamicEnforcedCetCompatibleRanges : _PS_DYNAMIC_ENFORCED_ADDRESS_RANGES
   +0xa20 DisabledComponentFlags : Uint4B
   +0xa28 PathRedirectionHashes : Ptr64 Uint4B
0: kd> dt _KPROCESS
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x018 ProfileListHead  : _LIST_ENTRY
   +0x028 DirectoryTableBase : Uint8B
   +0x030 ThreadListHead   : _LIST_ENTRY
   +0x040 ProcessLock      : Uint4B
   +0x044 ProcessTimerDelay : Uint4B
   +0x048 DeepFreezeStartTime : Uint8B
   +0x050 Affinity         : _KAFFINITY_EX
   +0x0f8 AffinityPadding  : [12] Uint8B
   +0x158 ReadyListHead    : _LIST_ENTRY
   +0x168 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x170 ActiveProcessors : _KAFFINITY_EX
   +0x218 ActiveProcessorsPadding : [12] Uint8B
   +0x278 AutoAlignment    : Pos 0, 1 Bit
   +0x278 DisableBoost     : Pos 1, 1 Bit
   +0x278 DisableQuantum   : Pos 2, 1 Bit
   +0x278 DeepFreeze       : Pos 3, 1 Bit
   +0x278 TimerVirtualization : Pos 4, 1 Bit
   +0x278 CheckStackExtents : Pos 5, 1 Bit
   +0x278 CacheIsolationEnabled : Pos 6, 1 Bit
   +0x278 PpmPolicy        : Pos 7, 3 Bits
   +0x278 VaSpaceDeleted   : Pos 10, 1 Bit
   +0x278 ReservedFlags    : Pos 11, 21 Bits
   +0x278 ProcessFlags     : Int4B
   +0x27c ActiveGroupsMask : Uint4B
   +0x280 BasePriority     : Char
   +0x281 QuantumReset     : Char
   +0x282 Visited          : Char
   +0x283 Flags            : _KEXECUTE_OPTIONS
   +0x284 ThreadSeed       : [20] Uint2B
   +0x2ac ThreadSeedPadding : [12] Uint2B
   +0x2c4 IdealProcessor   : [20] Uint2B
   +0x2ec IdealProcessorPadding : [12] Uint2B
   +0x304 IdealNode        : [20] Uint2B
   +0x32c IdealNodePadding : [12] Uint2B
   +0x344 IdealGlobalNode  : Uint2B
   +0x346 Spare1           : Uint2B
   +0x348 StackCount       : _KSTACK_COUNT
   +0x350 ProcessListEntry : _LIST_ENTRY
   +0x360 CycleTime        : Uint8B
   +0x368 ContextSwitches  : Uint8B
   +0x370 SchedulingGroup  : Ptr64 _KSCHEDULING_GROUP
   +0x378 FreezeCount      : Uint4B
   +0x37c KernelTime       : Uint4B
   +0x380 UserTime         : Uint4B
   +0x384 ReadyTime        : Uint4B
   +0x388 UserDirectoryTableBase : Uint8B
   +0x390 AddressPolicy    : UChar
   +0x391 Spare2           : [71] UChar
   +0x3d8 InstrumentationCallback : Ptr64 Void
   +0x3e0 SecureState      : <anonymous-tag>
   +0x3e8 KernelWaitTime   : Uint8B
   +0x3f0 UserWaitTime     : Uint8B
   +0x3f8 EndPadding       : [8] Uint8
--------------------------------------------------------------------

ETHREAD核心关键成员
封装与链接:
    Tcb: _KTHREAD结构。ETHREAD的第一个成员就是Tcb (Thread Control Block),即KTHREAD本身。
        这意味着ETHREAD的地址和其包含的KTHREAD的地址是完全相同的。
        这个设计允许内核代码通过简单的类型转换在两者之间无缝切换。
    ThreadsProcess: 指向其所属进程的EPROCESS结构的指针。这是从一个线程对象反向查找其父进程的途径。
    ThreadListEntry: _LIST_ENTRY结构,将隶属于同一个EPROCESS的所有ETHREAD链接起来。
身份标识:
    Cid: _CLIENT_ID结构,包含了UniqueProcess (PID) 和 UniqueThread (TID)。
安全:
    ImpersonationInfo: 如果线程正在模拟其他用户,相关信息会在这里。


KTHREAD核心关键成员
调度与执行:
    State: 线程状态(Running, Waiting, Ready, Terminated等)。调试时检查线程为何没有运行时非常有用。
    Priority: 线程的调度优先级。
    Affinity: 线程可以运行在哪些CPU核心上。
执行上下文:
    TrapFrame: 指向_KTRAP_FRAME的指针。当线程从用户模式切换到内核模式(例如通过系统调用或中断)时,
               其用户模式的寄存器状态会保存在这里。这是分析漏洞利用中ROP链构建、参数传递的关键。
    InitialStack, StackLimit, StackBase: 定义了线程的内核栈范围。内核栈溢出漏洞直接与此相关。
关联进程:
    Process: 指向所属进程的_KPROCESS结构的指针。


结构         层面                 核心角色                关键信息                                      调试入口
EPROCESS    执行体 (Executive)    进程的代表,资源所有者    PID, 映像名, Token, 句柄表, 内存空间, 进程列表   !process
ETHREAD     执行体 (Executive)    线程的代表,进程的成员    TID, 所属进程指针, 内嵌KTHREAD                 !thread
KTHREAD     内核 (Kernel)        调度的单元,执行的核心    寄存器状态 (TrapFrame), 内核栈, 调度状态/优先级   !thread, dt nt!_KTHREAD


☆ 相关调试指令

当前进程信息: !process 0 0
查看指定进程信息: !process <PID> 7 或 !process <EPROCESS_ADDRESS> 7 (参数7会显示详细信息,包括其所有线程)

获取某个结构里面的某个信息

--------------------------------------------------------------------
3: kd>  dt nt!_EPROCESS ffffcc099bc62040 Token
   +0x4b8 Token : _EX_FAST_REF
3: kd> dx -id 0,0,ffffcc099bc62040 -r1 (*((ntkrnlmp!_EX_FAST_REF *)0xffffcc099bc624f8))
(*((ntkrnlmp!_EX_FAST_REF *)0xffffcc099bc624f8))                 [Type: _EX_FAST_REF]
    [+0x000] Object           : 0xffffb90945625729 [Type: void *]
    [+0x000 ( 3: 0)] RefCnt           : 0x9 [Type: unsigned __int64]
    [+0x000] Value            : 0xffffb90945625729 [Type: unsigned __int64]
--------------------------------------------------------------------
    

☆ 参考阅读 

https://media.blackhat.com/bh-us-12/Briefings/Cerrudo/BH_US_12_Cerrudo_Windows_Kernal_Slides.pdf

https://www.blackhat.com/docs/us-14/materials/us-14-Tarakanov-Data-Only-Pwning-Microsoft-Windows-Kernel-Exploitation-Of-Kernel-Pool-Overflows-On-Microsoft-Windows-8.1.pdf

https://www.blackhat.com/docs/us-17/wednesday/us-17-Schenk-Taking-Windows-10-Kernel-Exploitation-To-The-Next-Level%E2%80%93Leveraging-Write-What-Where-Vulnerabilities-In-Creators-Update.pdf

https://www.blackhat.com/docs/us-14/materials/us-14-Tarakanov-Data-Only-Pwning-Microsoft-Windows-Kernel-Exploitation-Of-Kernel-Pool-Overflows-On-Microsoft-Windows-8.1.pdf

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions