X64 内核结构体详解

本文整理 Windows x64 系统中最重要的内核结构体定义、偏移量和使用场景,涵盖 EPROCESS/ETHREAD/KPROCESS/KTHREAD(内核态)和 TEB/PEB(用户态)。

概述

Windows 内核通过一组层次化的结构体来管理进程、线程和系统资源。这些结构体分布在内核态和用户态两个层面:

  • 内核态结构体_EPROCESS(执行体进程对象)、_KPROCESS(内核进程控制块)、_ETHREAD(执行体线程对象)、_KTHREAD(内核线程控制块)、_HANDLE_TABLE(句柄表)等。它们位于系统地址空间中,只能被内核代码访问。
  • 用户态结构体_PEB(进程环境块)、_TEB(线程环境块)等。它们位于进程的用户地址空间中,可以被用户态代码直接访问。

层次关系:

txt
EPROCESS (内核态)
├── Pcb: KPROCESS (内嵌)
├── Peb → PEB (指针,指向用户态)
├── ObjectTable → HANDLE_TABLE (指针)
├── ThreadListHead → ETHREAD.ThreadListEntry (链表)
└── Vm: MMSUPPORT (内嵌)
 
ETHREAD (内核态)
├── Tcb: KTHREAD (内嵌)
└── Tcb.Teb → TEB (指针,指向用户态)
 
TEB (用户态)
├── NtTib: NT_TIB (内嵌)
└── ProcessEnvironmentBlock → PEB (指针)

1. _EPROCESS — 执行体进程对象

_EPROCESS 是 Windows 内核中描述进程的核心结构体。每个进程都有一个对应的 _EPROCESS 对象,其中包含了进程的标识信息、内存管理数据、安全描述、线程列表等。

WinDbg dt 输出

⚠️ 版本说明:以下偏移基于 Windows 10 22H2(Build 19045),仅供对照参考。不同 Windows 版本(1507→22H2、Win11 21H2→24H2)的内核结构体偏移均不相同。实际调试时请以目标系统的 WinDbg dt _EPROCESS 输出为准。

plain
1: kd> dt _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x2D0 ProcessLock      : _EX_PUSH_LOCK
   +0x2D8 CreateTime       : _LARGE_INTEGER
   +0x2E0 ExitTime         : _LARGE_INTEGER
   +0x2E8 RundownProtect   : _EX_RUNDOWN_REF
   +0x2F0 UniqueProcessId  : Ptr64 Void
   +0x2F8 ActiveProcessLinks : _LIST_ENTRY
   +0x308 ProcessQuotaUsage : [2] Uint4B
   +0x310 ProcessQuotaPeak : [2] Uint4B
   +0x318 CommitCharge     : Uint8B
   +0x320 PeakVirtualSize  : Size_T
   +0x328 VirtualSize      : Size_T
   +0x330 SessionProcessLinks : _LIST_ENTRY
   +0x340 DebugPort        : Ptr64 Void
   +0x348 ExceptionPortData : Ptr64 Void
   +0x350 ObjectTable      : Ptr64 _HANDLE_TABLE
   +0x358 Token            : _EX_FAST_REF
   +0x360 WorkingSetPage   : Uint8B
   +0x368 AddressCreationLock : _EX_PUSH_LOCK
   +0x370 PageTableCommit  : _EX_PUSH_LOCK
   +0x378 FileObjectLock   : _EX_PUSH_LOCK
   +0x380 ImageFilePointer : Ptr64 _FILE_OBJECT
   +0x388 ImageFileName    : [15] UChar
   +0x397 PriorityClass    : UChar
   +0x398 VadRoot          : _RTL_AVL_TREE
   +0x3A0 VadHint          : Ptr64 Void
   +0x3A8 CloneRoot        : Ptr64 Void
   +0x3B0 NumberOfPrivatePages : Uint8B
   +0x3B8 NumberOfLockedPages : Uint8B
   +0x3C0 Win32Process     : Ptr64 Void
   +0x3C8 Job              : Ptr64 _EJOB
   +0x3D0 SectionObject    : Ptr64 Void
   +0x3D8 SectionBaseAddress : Ptr64 Void
   +0x3E0 Cookie           : Uint4B
   +0x3E8 WorkingSetWatch  : Ptr64 _PAGEFAULT_HISTORY
   +0x3F0 Win32WindowStation : Ptr64 Void
   +0x3F8 InheritedFromUniqueProcessId : Ptr64 Void
   +0x400 LdtInformation   : Ptr64 Void
   +0x408 VdmObjects       : Ptr64 Void
   +0x410 ConsoleHostProcess : Uint8B
   +0x418 DeviceMap        : Ptr64 Void
   +0x420 EtwDataSource    : Ptr64 Void
   +0x428 FreeTebHint      : Ptr64 Void
   +0x430 FreeTlsHint      : Ptr64 Void
   +0x438 MinimumFreeCommit : Uint4B
   +0x440 ProcessIssuerCfg : Ptr64 Void
   +0x448 Peb              : Ptr64 _PEB
   +0x450 GlowInformation  : Ptr64 Void
   +0x458 CommitChargeLimit : Uint8B
   +0x460 CommitChargePeak : Uint8B
   +0x468 AweInfo          : Ptr64 Void
   +0x470 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x478 Vm               : _MMSUPPORT
   +0x498 MmProcessLinks   : _LIST_ENTRY
   +0x4A8 ModifiedPageCount : Uint4B
   +0x4AC ExitStatus       : Int4B
   +0x4B0 VadRoot          : Ptr64 _MM_AVL_TABLE
   +0x4B8 AlpcContext      : _ALPC_PROCESS_CONTEXT
   +0x4C8 DurableObject    : Ptr64 Void
   +0x4D0 ThreadListHead   : _LIST_ENTRY
   +0x4E0 ActiveThreads    : Uint4B
   +0x4E8 ImagePathHash    : Uint4B
   +0x4F0 ActiveProcessLinks2 : _LIST_ENTRY
   +0x500 ThreadListLock   : _EX_PUSH_LOCK
   +0x508 SetupTask        : Ptr64 Void
   +0x510 StrainedCpuCount : Int4B
   +0x518 ThreadListHead   : _LIST_ENTRY
   +0x528 MmHotPatchContext : Ptr64 Void
   +0x530 Flags            : Uint4B
   +0x534 ActiveThreads    : Uint4B
   +0x538 Peb              : Ptr64 _PEB

C 结构体定义

C++cpp
typedef struct _EPROCESS
{
    KPROCESS Pcb;
    EX_PUSH_LOCK ProcessLock;
    LARGE_INTEGER CreateTime;
    LARGE_INTEGER ExitTime;
    EX_RUNDOWN_REF RundownProtect;
    HANDLE UniqueProcessId;
    LIST_ENTRY ActiveProcessLinks;
    SIZE_T QuotaUsage[PsQuotaTypes];
    SIZE_T QuotaPeak[PsQuotaTypes];
    SIZE_T CommitCharge;
    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;
    LIST_ENTRY SessionProcessLinks;
    PVOID DebugPort;
    PVOID ExceptionPort;
    PHANDLE_TABLE ObjectTable;
    EX_FAST_REF Token;
    PFN_NUMBER WorkingSetPage;
    KGUARDED_MUTEX AddressCreationLock;
    KSPIN_LOCK HyperSpaceLock;
    struct _ETHREAD *ForkInProgress;
    ULONG_PTR HardwareTrigger;
    PMM_AVL_TABLE PhysicalVadRoot;
    PVOID CloneRoot;
    PFN_NUMBER NumberOfPrivatePages;
    PFN_NUMBER NumberOfLockedPages;
    PVOID Win32Process;
    struct _EJOB *Job;
    PVOID SectionObject;
    PVOID SectionBaseAddress;
    PEPROCESS_QUOTA_BLOCK QuotaBlock;
    PPAGEFAULT_HISTORY WorkingSetWatch;
    HANDLE Win32WindowStation;
    HANDLE InheritedFromUniqueProcessId;
    PVOID LdtInformation;
    PVOID VadFreeHint;
    PVOID VdmObjects;
    PVOID DeviceMap;
    PVOID Spare0[3];
    union {
        HARDWARE_PTE PageDirectoryPte;
        ULONGLONG Filler;
    };
    PVOID Session;
    UCHAR ImageFileName[16];
    LIST_ENTRY JobLinks;
    PVOID LockedPagesList;
    LIST_ENTRY ThreadListHead;
    PVOID SecurityPort;
    PVOID PaeTop;
    ULONG ActiveThreads;
    ACCESS_MASK GrantedAccess;
    ULONG DefaultHardErrorProcessing;
    NTSTATUS LastThreadExitStatus;
    PPEB Peb;
    EX_FAST_REF PrefetchTrace;
    LARGE_INTEGER ReadOperationCount;
    LARGE_INTEGER WriteOperationCount;
    LARGE_INTEGER OtherOperationCount;
    LARGE_INTEGER ReadTransferCount;
    LARGE_INTEGER WriteTransferCount;
    LARGE_INTEGER OtherTransferCount;
    SIZE_T CommitChargeLimit;
    SIZE_T CommitChargePeak;
    PVOID AweInfo;
    SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;
    MMSUPPORT Vm;
    LIST_ENTRY MmProcessLinks;
    ULONG ModifiedPageCount;
    ULONG JobStatus;
    union {
        ULONG Flags;
        struct {
            ULONG CreateReported            : 1;
            ULONG NoDebugInherit            : 1;
            ULONG ProcessExiting            : 1;
            ULONG ProcessDelete             : 1;
            ULONG Wow64SplitPages           : 1;
            ULONG VmDeleted                 : 1;
            ULONG OutswapEnabled            : 1;
            ULONG Outswapped                : 1;
            ULONG ForkFailed                : 1;
            ULONG Wow64VaSpace4Gb           : 1;
            ULONG AddressSpaceInitialized   : 2;
            ULONG SetTimerResolution        : 1;
            ULONG BreakOnTermination        : 1;
            ULONG SessionCreationUnderway   : 1;
            ULONG WriteWatch                : 1;
            ULONG ProcessInSession          : 1;
            ULONG OverrideAddressSpace      : 1;
            ULONG HasAddressSpace           : 1;
            ULONG LaunchPrefetched          : 1;
            ULONG InjectInpageErrors        : 1;
            ULONG VmTopDown                 : 1;
            ULONG ImageNotifyDone           : 1;
            ULONG PdeUpdateNeeded           : 1;
            ULONG VdmAllowed                : 1;
            ULONG SmapAllowed               : 1;
            ULONG CreateFailed              : 1;
            ULONG DefaultIoPriority         : 3;
            ULONG Spare1                    : 1;
            ULONG Spare2                    : 1;
        };
    };
    NTSTATUS ExitStatus;
    USHORT NextPageColor;
    union {
        struct {
            UCHAR SubSystemMinorVersion;
            UCHAR SubSystemMajorVersion;
        };
        USHORT SubSystemVersion;
    };
    UCHAR PriorityClass;
    MM_AVL_TABLE VadRoot;
    ULONG Cookie;
} EPROCESS, *PEPROCESS;

关键成员详解

进程标识

  • UniqueProcessId (+0x2F0):进程的唯一编号(PID),在进程创建时设定。任务管理器中显示的 PID 就来自此字段。
  • ImageFileName (+0x388):进程映像文件名,仅包含路径中最后一个分隔符后的字符串,不超过 16 字节。
  • InheritedFromUniqueProcessId (+0x3F8):父进程的标识符,用于追溯进程的创建来源。
  • ActiveProcessLinks (+0x2F8):双链表节点,系统中所有活动进程通过此域链接在一起。表头是全局变量 PsActiveProcessHead。PID=4 的 System 进程的 ActiveProcessLinks 即为 PsActiveProcessHead。枚举所有进程时,可通过 PsGetCurrentProcess() 获取当前 EPROCESS,再沿 Flink/Blink 遍历链表。

内存管理

  • VadRoot (+0x398):指向进程的虚拟地址空间描述符(VAD)平衡二叉树的根,管理进程的虚拟地址空间分配。
  • VadFreeHint (+0x3A0):指向一个提示 VAD 节点,用于加速 VAD 树中的查找操作。
  • VirtualSize (+0x328) / PeakVirtualSize (+0x320):进程虚拟内存大小及其峰值。
  • CommitCharge (+0x318):进程已提交的虚拟内存页面数量。
  • NumberOfPrivatePages (+0x3B0) / NumberOfLockedPages (+0x3B8):进程私有页面数量和锁定页面数量。
  • Vm (+0x478):_MMSUPPORT 类型,包含工作集管理、页面错误计数等虚拟内存管理数据。
  • SectionObject (+0x3D0) / SectionBaseAddress (+0x3D8):进程的内存区对象及其基地址。

配额管理

  • ProcessQuotaUsage (+0x308) / ProcessQuotaPeak (+0x310):进程内存配额使用量和峰值。数组元素:[0] 非换页内存池、[1] 换页内存池、[2] 交换文件中的内存使用。
  • QuotaBlock(新版结构已移除该独立字段):指向 _EPROCESS_QUOTA_BLOCK 配额块。多个进程可共享同一配额块,通过引用计数管理。配额块双链表表头为 PspQuotaBlockList,默认配额块为 PspDefaultQuotaBlock

安全

  • Token (+0x358):_EX_FAST_REF 类型,指向进程的访问令牌,用于安全访问检查。可通过 OpenProcessToken API 获取。
  • ObjectTable (+0x350):指向 _HANDLE_TABLE 句柄表。句柄是进程范围内的对象引用,本质上是一个索引,指向句柄表中的一个表项。句柄表是多层结构,最多可容纳 2^24 个句柄。

线程管理

  • ThreadListHead (+0x4D0):双链表头节点,链接进程中的所有线程。链表中的节点是各 ETHREAD 的 ThreadListEntry 成员(而非 ETHREAD 基址),遍历时需注意偏移计算。
  • ActiveThreads (+0x534):当前活动线程数。当此值减为 0 时,进程退出。
  • LastThreadExitStatus (+0x4AC):最后一个线程的退出状态码。

调试与异常

  • DebugPort (+0x340):调试端口,指向调试器。当进程被调试时,线程发生异常将向此端口发送消息。这也是探测调试器存在的技术之一。
  • ExceptionPort (+0x348):异常端口,指向 Windows 子系统(csrss.exe)。异常处理顺序:
    1. 判断异常是否发送给调试器(若进程正在被调试)
    2. 查找线程相关的 SEH 异常处理例程
    3. 再次通知调试器
    4. 调用 SetUnhandledExceptionFilter 安装的最后异常处理例程
    5. 调用默认系统处理程序(显示错误对话框)
    6. 调用 ExitProcess 终结程序

会话与作业

  • Session(新版结构未直接暴露该字段):指向 _MM_SESSION_SPACE,表示进程所属的系统会话。
  • SessionProcessLinks (+0x330):会话进程链表节点。
  • Job (+0x3C8):指向 _EJOB 对象,仅当进程属于一个 Job 时才有效。
  • JobLinks(新版结构已移除该独立字段):Job 进程链表节点,通过此节点将同一 Job 中的所有进程链接起来。

用户态接口

  • Peb (+0x538):指向用户态的 _PEB(进程环境块),位于进程地址空间中。PEB 包含堆信息、系统模块列表(Ldr)、进程参数等,可被用户态代码直接访问和修改。

IO 统计

  • ReadOperationCount(新版结构已移除) / WriteOperationCount(已移除) / OtherOperationCount(已移除):此组字段在新版 EPROCESS 中已移除,原用于记录 NtReadFileNtWriteFile 和其他 IO 服务的调用次数。
  • ReadTransferCount(新版结构已移除) / WriteTransferCount(已移除) / OtherTransferCount(已移除):此组字段在新版 EPROCESS 中已移除,原用于记录 IO 读写操作的完成次数。

进程锁与同步

  • ProcessLock (+0x2D0):_EX_PUSH_LOCK 推锁,保护 EPROCESS 中的数据成员,强制串行化并行事件。
  • RundownProtect (+0x2E8):停止保护锁,进程销毁时需等待所有其他进程和线程释放此锁。
  • AddressCreationLock (+0x368):守护互斥体锁,保护虚拟地址空间操作。
  • HyperSpaceLock(新版结构已移除该独立字段):自旋锁,保护进程超空间。

标志位与优先级

  • Flags (+0x530):进程标志位组合,包括 CreateReportedProcessExitingProcessDeleteVmDeletedOutswapEnabledProcessInSession 等。
  • PriorityClass (+0x397):进程优先级类。Windows 支持 6 个优先级类:idlebelow normalnormalabove normalhighreal-time

其他

  • CreateTime (+0x2D8) / ExitTime (+0x2E0):进程创建时间和退出时间。
  • Cookie (+0x3E0):代表进程的随机值,首次通过 NtQueryInformationProcess 获取时生成。
  • SeAuditProcessCreationInfo (+0x470):创建进程时指定的映像全路径名,ImageFileName 域从此提取。
  • Win32Process (+0x3C0):指向 Windows 子系统管理的进程区域,非 NULL 表示 GUI 进程。
  • Win32WindowStation (+0x3F0):进程所属窗口站的句柄。

关键偏移速查

⚠️ 以下速查值与上方 dt 输出一致,基于 Win10 22H2。不同版本偏移可能不同。

偏移成员类型说明
+0x000Pcb_KPROCESS内核进程控制块
+0x2D0ProcessLock_EX_PUSH_LOCK进程推锁
+0x2D8CreateTime_LARGE_INTEGER创建时间
+0x2F0UniqueProcessIdHANDLE进程 PID
+0x2F8ActiveProcessLinks_LIST_ENTRY活动进程链表
+0x318CommitChargeSIZE_T已提交页面数
+0x328VirtualSizeSIZE_T虚拟内存大小
+0x340DebugPortPVOID调试端口
+0x350ObjectTablePHANDLE_TABLE句柄表
+0x358Token_EX_FAST_REF访问令牌
+0x3C0Win32ProcessPVOIDWin32 进程对象
+0x3C8Job_EJOB*作业对象
+0x3F8InheritedFromUniqueProcessIdHANDLE父进程 PID
+0x388ImageFileNameUCHAR[15]映像文件名
+0x4D0ThreadListHead_LIST_ENTRY线程链表头
+0x534ActiveThreadsULONG活动线程数
+0x538PebPPEB进程环境块指针
+0x478Vm_MMSUPPORT内存管理支持
+0x530FlagsULONG标志位
+0x397PriorityClassUCHAR优先级类
+0x3E0CookieULONG随机 Cookie

2. _KPROCESS — 内核进程控制块

_KPROCESS 是内核级别的进程控制块,作为 _EPROCESS.Pcb 嵌入在 EPROCESS 中。它包含了进程调度所需的核心信息,如 CPU 亲和性、线程列表、页表基地址等。

WinDbg dt 输出

plain
1: kd> dt _KPROCESS
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x018 ProfileListHead  : _LIST_ENTRY
   +0x028 DirectoryTableBase : Uint8B
   +0x030 ThreadListHead   : _LIST_ENTRY
   +0x038 ProcessLock      : Uint4B
   +0x03c ProcessTimerDelay : Uint4B
   +0x040 DeepFreezeStartTime : Uint8B
   +0x048 Affinity         : _KAFFINITY_EX
   +0x058 ReadyListHead    : _LIST_ENTRY
   +0x068 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x070 ActiveProcessors : _KAFFINITY_EX
   +0x080 ProcessFlags     : Uint4B
   +0x084 ActiveGroupsMask : Uint4B
   +0x088 BasePriority     : Char
   +0x089 QuantumReset     : Char
   +0x08a Visited          : Char
   +0x08b Flags            : _KEXECUTE_OPTIONS
   +0x08c ThreadSeed       : [1] Uint2B
   +0x08e IdealProcessor   : [1] Uint2B
   +0x090 IdealNode        : [1] Uint2B
   +0x092 IdealGlobalNode  : Uint2B
   +0x094 Spare1           : Uint2B
   +0x096 StackCount       : _KSTACK_COUNT
   +0x098 ProcessListEntry : _LIST_ENTRY
   +0x0a8 CycleTime        : Uint8B
   +0x0b0 ContextSwitches  : Uint8B
   +0x0b8 SchedulingGroup  : Ptr64 _KSCHEDULING_GROUP
   +0x0c0 FreezeCount      : Uint4B
   +0x0c4 KernelTime       : Uint4B
   +0x0c8 UserTime         : Uint4B
   +0x0cc ReadyTime        : Uint4B
   +0x0d0 UserDirectoryTableBase : Uint8B
   +0x0d8 AddressPolicy    : UChar
   +0x0d9 Spare2          : [71] UChar
   +0x120 InstrumentationCallback : Ptr64 Void
   +0x128 SecureState      : _SECURE_PROCESS_STATE
   +0x130 KernelWaitTime   : Uint8B
   +0x138 UserWaitTime     : Uint8B
   +0x140 EndPadding       : [8] Uint8B

C 结构体定义

C++cpp
typedef struct _KPROCESS
{
    struct _DISPATCHER_HEADER Header;
    struct _LIST_ENTRY ProfileListHead;
    VOID* DirectoryTableBase;
    struct _LIST_ENTRY ThreadListHead;
    UINT32 ProcessLock;
    UINT32 ProcessTimerDelay;
    UINT64 DeepFreezeStartTime;
    struct _KAFFINITY_EX Affinity;
    struct _LIST_ENTRY ReadyListHead;
    struct _SINGLE_LIST_ENTRY SwapListEntry;
    volatile struct _KAFFINITY_EX ActiveProcessors;
    union {
        struct {
            UINT32 AutoAlignment : 1;
            UINT32 DisableBoost : 1;
            UINT32 DisableQuantum : 1;
            UINT32 DeepFreeze : 1;
            UINT32 TimerVirtualization : 1;
            UINT32 CheckStackExtents : 1;
            UINT32 CacheIsolationEnabled : 1;
            UINT32 PpmPolicy : 3;
            UINT32 VaSpaceDeleted : 1;
            UINT32 ReservedFlags : 21;
        };
        volatile INT32 ProcessFlags;
    };
    UINT32 ActiveGroupsMask;
    CHAR BasePriority;
    CHAR QuantumReset;
    CHAR Visited;
    union _KEXECUTE_OPTIONS Flags;
    UINT16 ThreadSeed[NumberOfProcessor];
    UINT16 IdealProcessor[NumberOfProcessor];
    UINT16 IdealNode[NumberOfProcessor];
    UINT16 IdealGlobalNode;
    UINT16 Spare1;
    volatile union _KSTACK_COUNT StackCount;
    struct _LIST_ENTRY ProcessListEntry;
    UINT64 CycleTime;
    UINT64 ContextSwitches;
    struct _KSCHEDULING_GROUP* SchedulingGroup;
    UINT32 FreezeCount;
    UINT32 KernelTime;
    UINT32 UserTime;
    UINT32 ReadyTime;
    UINT64 UserDirectoryTableBase;
    UINT8 AddressPolicy;
    UINT8 Spare2[71];
    VOID* InstrumentationCallback;
    union {
        union {
            UINT64 SecureHandle;
            struct {
                UINT64 SecureProcess : 1;
                UINT64 Unused : 1;
            } Flags;
        };
    } SecureState;
    UINT64 KernelWaitTime;
    UINT64 UserWaitTime;
    SIZE_T EndPadding[8];
} KPROCESS, *PKPROCESS;

关键成员说明

  • DirectoryTableBase:页表基地址(CR3 的值),是进程地址空间切换的关键。
  • ThreadListHead:内核级线程链表头,链接进程中的所有 KTHREAD。
  • Affinity:CPU 亲和性掩码,指定进程中的线程可以在哪些处理器上运行。
  • BasePriority:进程基础优先级,线程优先级在此基础上调整。
  • StackCount:进程内核栈引用计数。
  • CycleTime / ContextSwitches:进程的 CPU 周期时间和上下文切换次数。
  • KernelTime / UserTime:进程在内核态和用户态的运行时间。

3. _ETHREAD — 执行体线程对象

_ETHREAD 是描述线程的执行体结构体。每个线程都有一个对应的 _ETHREAD,其中包含了线程的创建/退出时间、线程 ID、IRP 列表、安全上下文等信息。

WinDbg dt 输出

plain
1: kd> dt _ETHREAD
nt!_ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x430 CreateTime       : _LARGE_INTEGER
   +0x438 ExitTime         : _LARGE_INTEGER
   +0x438 KeyedWaitChain   : _LIST_ENTRY
   +0x448 PostBlockList    : _LIST_ENTRY
   +0x450 StartAddress     : Ptr64 Void
   +0x458 TerminationPort  : Ptr64 _TERMINATION_PORT
   +0x458 ReaperLink       : Ptr64 _ETHREAD
   +0x458 KeyedWaitValue   : Ptr64 Void
   +0x460 ActiveTimerListLock : Uint8B
   +0x468 ActiveTimerListHead : _LIST_ENTRY
   +0x478 Cid              : _CLIENT_ID
   +0x488 KeyedWaitSemaphore : _KSEMAPHORE
   +0x488 AlpcWaitSemaphore : _KSEMAPHORE
   +0x4a8 ClientSecurity   : _PS_CLIENT_SECURITY_CONTEXT
   +0x4b0 IrpList          : _LIST_ENTRY
   +0x4c0 TopLevelIrp      : Uint8B
   +0x4c8 DeviceToVerify   : Ptr64 _DEVICE_OBJECT
   +0x4d0 Win32StartAddress : Ptr64 Void
   +0x4d8 ChargeOnlySession : Ptr64 Void
   +0x4e0 LegacyPowerObject : Ptr64 Void
   +0x4e8 ThreadListEntry  : _LIST_ENTRY
   +0x4f8 RundownProtect   : _EX_RUNDOWN_REF
   +0x500 ThreadLock       : _EX_PUSH_LOCK
   +0x508 ReadClusterSize  : Uint4B
   +0x50c MmLockOrdering   : Int4B
   +0x510 CrossThreadFlags : Uint4B
   +0x510 Terminated       : Pos 0, 1 Bit
   +0x510 HideFromDebugger : Pos 2, 1 Bit
   +0x510 BreakOnTermination : Pos 5, 1 Bit
   +0x514 SameThreadPassiveFlags : Uint4B
   +0x514 ActiveExWorker   : Pos 0, 1 Bit
   +0x514 KeyedEventInUse  : Pos 5, 1 Bit
   +0x514 SelfTerminate    : Pos 6, 1 Bit
   +0x518 SameThreadApcFlags : Uint4B
   +0x51c CacheManagerActive : UChar
   +0x51d DisablePageFaultClustering : UChar
   +0x51e ActiveFaultCount : UChar
   +0x528 AlpcMessageId    : Uint8B
   +0x530 AlpcMessage      : Ptr64 Void
   +0x538 AlpcWaitListEntry : _LIST_ENTRY
   +0x548 ExitStatus       : Int4B
   +0x550 IoBoostCount     : Uint4B
   +0x55c KernelStackReference : Uint4B
   +0x560 BoostList        : _LIST_ENTRY
   +0x570 DeboostList      : _LIST_ENTRY
   +0x580 BoostListLock    : Uint8B
   +0x588 IrpListLock      : Uint8B
   +0x598 CmCallbackListHead : _SINGLE_LIST_ENTRY
   +0x5a0 ActivityId       : Ptr64 _GUID
   +0x5b0 VerifierContext  : Ptr64 Void
   +0x5b8 AdjustedClientToken : Ptr64 Void
   +0x5c0 WorkOnBehalfThread : Ptr64 Void
   +0x5c8 PropertySet      : _PS_PROPERTY_SET
   +0x5e0 PicoContext      : Ptr64 Void
   +0x5e8 UserFsBase       : Uint8B
   +0x5f0 UserGsBase       : Uint8B
   +0x5f8 EnergyValues     : Ptr64 _THREAD_ENERGY_VALUES
   +0x600 SelectedCpuSets  : Uint8B
   +0x608 Silo             : Ptr64 _EJOB
   +0x610 ThreadName       : Ptr64 _UNICODE_STRING
   +0x618 SetContextState  : Ptr64 _CONTEXT
   +0x620 LastExpectedRunTime : Uint4B
   +0x624 HeapData         : Uint4B
   +0x628 OwnerEntryListHead : _LIST_ENTRY
   +0x638 DisownedOwnerEntryListLock : Uint8B
   +0x640 DisownedOwnerEntryListHead : _LIST_ENTRY
   +0x650 LockEntries      : [6] _KLOCK_ENTRY
   +0x890 CmDbgInfo        : Ptr64 Void

C 结构体定义

C++cpp
typedef struct _ETHREAD
{
    KTHREAD Tcb;
    LARGE_INTEGER CreateTime;
    union {
        LARGE_INTEGER ExitTime;
        LIST_ENTRY LpcReplyChain;
        LIST_ENTRY KeyedWaitChain;
    };
    union {
        NTSTATUS ExitStatus;
        PVOID OfsChain;
    };
    LIST_ENTRY PostBlockList;
    union {
        PTERMINATION_PORT TerminationPort;
        struct _ETHREAD *ReaperLink;
        PVOID KeyedWaitValue;
    };
    KSPIN_LOCK ActiveTimerListLock;
    LIST_ENTRY ActiveTimerListHead;
    CLIENT_ID Cid;
    union {
        KSEMAPHORE LpcReplySemaphore;
        KSEMAPHORE KeyedWaitSemaphore;
    };
    union {
        PVOID LpcReplyMessage;
        PVOID LpcWaitingOnPort;
    };
    PPS_IMPERSONATION_INFORMATION ImpersonationInfo;
    LIST_ENTRY IrpList;
    ULONG_PTR TopLevelIrp;
    struct _DEVICE_OBJECT *DeviceToVerify;
    PEPROCESS ThreadsProcess;
    PVOID StartAddress;
    union {
        PVOID Win32StartAddress;
        ULONG LpcReceivedMessageId;
    };
    LIST_ENTRY ThreadListEntry;
    EX_RUNDOWN_REF RundownProtect;
    EX_PUSH_LOCK ThreadLock;
    ULONG LpcReplyMessageId;
    ULONG ReadClusterSize;
    ACCESS_MASK GrantedAccess;
    union {
        ULONG CrossThreadFlags;
        struct {
            ULONG Terminated              : 1;
            ULONG DeadThread              : 1;
            ULONG HideFromDebugger        : 1;
            ULONG ActiveImpersonationInfo : 1;
            ULONG SystemThread            : 1;
            ULONG HardErrorsAreDisabled   : 1;
            ULONG BreakOnTermination      : 1;
            ULONG SkipCreationMsg         : 1;
            ULONG SkipTerminationMsg      : 1;
        };
    };
    union {
        ULONG SameThreadPassiveFlags;
        struct {
            ULONG ActiveExWorker : 1;
            ULONG ExWorkerCanWaitUser : 1;
            ULONG MemoryMaker : 1;
            ULONG KeyedEventInUse : 1;
        };
    };
    union {
        ULONG SameThreadApcFlags;
        struct {
            BOOLEAN LpcReceivedMsgIdValid : 1;
            BOOLEAN LpcExitThreadCalled   : 1;
            BOOLEAN AddressSpaceOwner     : 1;
            BOOLEAN OwnsProcessWorkingSetExclusive  : 1;
            BOOLEAN OwnsProcessWorkingSetShared     : 1;
            BOOLEAN OwnsSystemWorkingSetExclusive   : 1;
            BOOLEAN OwnsSystemWorkingSetShared      : 1;
            BOOLEAN OwnsSessionWorkingSetExclusive  : 1;
            BOOLEAN OwnsSessionWorkingSetShared     : 1;
            BOOLEAN ApcNeeded                       : 1;
        };
    };
    BOOLEAN ForwardClusterOnly;
    BOOLEAN DisablePageFaultClustering;
    UCHAR ActiveFaultCount;
} ETHREAD, *PETHREAD;

关键成员说明

  • Tcb (+0x000):内嵌的 _KTHREAD,占据 ETHREAD 的前 0x430 字节,包含调度相关信息。
  • CreateTime (+0x430) / ExitTime (+0x438):线程创建和退出时间。
  • Cid (+0x478):_CLIENT_ID,包含进程 ID 和线程 ID(UniqueProcess / UniqueThread)。
  • StartAddress (+0x450):线程的起始地址(内核态记录)。
  • Win32StartAddress (+0x4d0):用户态线程入口地址。
  • ThreadListEntry (+0x4e8):链接到 EPROCESS.ThreadListHead 的链表节点。
  • IrpList (+0x4b0):线程的 IRP 请求包链表。
  • TerminationPort (+0x458):终止端口,线程退出时通知。
  • CrossThreadFlags (+0x510):跨线程标志位,包含 TerminatedHideFromDebuggerBreakOnTermination 等。
  • RundownProtect (+0x4f8):线程停止保护锁。

4. _KTHREAD — 内核线程控制块

_KTHREAD 是内核级线程控制块,作为 _ETHREAD.Tcb 嵌入在 ETHREAD 中。它包含了线程调度、等待、APC、定时器等内核级信息。

WinDbg dt 输出

plain
1: kd> dt _KTHREAD
nt!_KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x018 SListFaultAddress : Ptr64 Void
   +0x020 QuantumTarget    : Uint8B
   +0x028 InitialStack     : Ptr64 Void
   +0x030 StackLimit       : Ptr64 Void
   +0x038 StackBase        : Ptr64 Void
   +0x040 ThreadLock       : Uint8B
   +0x048 CycleTime        : Uint8B
   +0x050 CurrentRunTime   : Uint4B
   +0x054 ExpectedRunTime  : Uint4B
   +0x058 KernelStack      : Ptr64 Void
   +0x060 StateSaveArea    : Ptr64 _XSAVE_FORMAT
   +0x068 SchedulingGroup  : Ptr64 _KSCHEDULING_GROUP
   +0x070 WaitRegister     : _KWAIT_STATUS_REGISTER
   +0x071 RunningStatus    : UChar
   +0x072 Alerted          : [2] UChar
   +0x074 MiscFlags        : Uint4B
   +0x078 ApcState         : _KAPC_STATE
   +0x0f0 Teb              : Ptr64 Void
   +0x0f8 Timer            : _KTIMER
   +0x138 WaitBlockList    : Ptr64 _KWAIT_BLOCK
   +0x140 WaitListEntry    : _LIST_ENTRY
   +0x150 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x158 Queue            : Ptr64 _DISPATCHER_HEADER
   +0x160 TebMappedLowVa   : Uint8B
   +0x168 KernelStackResident : Pos 0, 1 Bit
   +0x168 ReadyTransition  : Pos 1, 1 Bit
   +0x168 ProcessReadyQueue : Pos 2, 1 Bit
   +0x168 UserStackWalkActive : Pos 3, 1 Bit
   +0x168 ApcQueueable     : Pos 4, 1 Bit
   +0x168 Pageable         : Pos 5, 1 Bit
   +0x168 HeterogeneousCpuPolicy : Pos 6, 1 Bit
   +0x168 SchedGroup      : Pos 7, 1 Bit
   +0x168 FreezeCount      : Int4B
   +0x16c SuspendCount     : Pos 0, 8 Bits
   +0x16c HeaderType       : Pos 8, 8 Bits
   +0x16c SignalState      : Pos 16, 8 Bits
   +0x16c Size             : Pos 24, 8 Bits
   +0x170 SpecialApcDisable : Int2B
   +0x172 KernelApcDisable : Int2B
   +0x174 CombinedApcDisable : Uint4B
   +0x178 TrapFrame        : Ptr64 _KTRAP_FRAME
   +0x180 Win32Thread      : Ptr64 Void
   +0x188 Ucb              : Ptr64 _KUMS_CONTEXT_HEADER
   +0x190 ThreadFlags      : Uint4B
   +0x194 Spare0           : Uint4B
   +0x198 WaitStatus       : Int8B
   +0x1a0 Scheduler        : Ptr64 _KTHREAD_SCHEDULER
   +0x1a8 SListFaultCount  : Uint4B
   +0x1ac QueryDepth       : Uint4B
   +0x1b0 SchedulerInit   : Ptr64 Void
   +0x1b8 HeterogeneousCpuPolicy : Uint4B
   +0x1bc Win32StartAddress : Uint4B
   +0x1c0 KKernelStackBase : Uint8B
   +0x1c8 KStackLimit      : Uint8B
   +0x1d0 PreviousMode     : Char
   +0x1d1 NpxState         : Char
   +0x1d2 LdtIndex         : Uint2B
   +0x1d4 WaitTime         : Uint4B
   +0x1d8 Priority         : Char
   +0x1d9 ForceDeferSchedule : UChar
   +0x1da CaptureBaseline  : UChar
   +0x1db DeferAllocate    : UChar
   +0x1dc QueuedWaitListEntry : _LIST_ENTRY
   +0x1ec QueueListEntry   : _LIST_ENTRY
   +0x1f8 NextProcessor    : Uint4B
   +0x1fc DeferredProcessor : Uint4B
   +0x200 Process          : Ptr64 _KPROCESS
   +0x208 Affinity         : _GROUP_AFFINITY
   +0x218 UserAffinity     : _GROUP_AFFINITY
   +0x228 StartAddress     : Ptr64 Void
   +0x230 Win32StartAddress : Ptr64 Void
   +0x238 TebMappedLowVa   : Uint8B
   +0x240 Cookie           : Uint4B
   +0x244 IdealProcessor   : Uint4B
   +0x248 ThreadListEntry  : _LIST_ENTRY
   +0x258 Scheduler        : Ptr64 _KTHREAD_SCHEDULER
   +0x260 SListFaultAddress2 : Ptr64 Void
   +0x268 Scheduler        : Ptr64 Void
   +0x270 ThreadName       : Ptr64 _UNICODE_STRING
   +0x278 HeterogeneousCpuPolicy : Uint4B

C 结构体定义

C++cpp
typedef struct _KTHREAD
{
    DISPATCHER_HEADER Header;
    PVOID SListFaultAddress;
    ULONGLONG QuantumTarget;
    PVOID InitialStack;
    PVOID StackLimit;
    PVOID StackBase;
    ULONG_PTR ThreadLock;
    ULONGLONG CycleTime;
    ULONG CurrentRunTime;
    ULONG ExpectedRunTime;
    PVOID KernelStack;
    XSAVE_FORMAT* StateSaveArea;
    KSCHEDULING_GROUP* SchedulingGroup;
    KWAIT_STATUS_REGISTER WaitRegister;
    UCHAR RunningStatus;
    UCHAR Alerted[2];
    ULONG MiscFlags;
    KAPC_STATE ApcState;
    PVOID Teb;
    KTIMER Timer;
    KWAIT_BLOCK* WaitBlockList;
    LIST_ENTRY WaitListEntry;
    SINGLE_LIST_ENTRY SwapListEntry;
    DISPATCHER_HEADER* Queue;
    ULONGLONG TebMappedLowVa;
    union {
        ULONG KernelStackResident : 1;
        ULONG ReadyTransition : 1;
        ULONG ProcessReadyQueue : 1;
        ULONG UserStackWalkActive : 1;
        ULONG ApcQueueable : 1;
        ULONG Pageable : 1;
        ULONG HeterogeneousCpuPolicy : 1;
        ULONG SchedGroup : 1;
        LONG FreezeCount;
        struct {
            SHORT SuspendCount : 8;
            SHORT HeaderType : 8;
            SHORT SignalState : 8;
            SHORT Size : 8;
        };
    };
    SHORT SpecialApcDisable;
    SHORT KernelApcDisable;
    ULONG CombinedApcDisable;
    KTRAP_FRAME* TrapFrame;
    PVOID Win32Thread;
    KUMS_CONTEXT_HEADER* Ucb;
    ULONG ThreadFlags;
    ULONG Spare0;
    LONGLONG WaitStatus;
    KTHREAD_SCHEDULER* Scheduler;
    ULONG SListFaultCount;
    ULONG QueryDepth;
    PVOID SchedulerInit;
    ULONG HeterogeneousCpuPolicy;
    ULONG Win32StartAddress;
    ULONGLONG KKernelStackBase;
    ULONGLONG KStackLimit;
    CHAR PreviousMode;
    CHAR NpxState;
    USHORT LdtIndex;
    ULONG WaitTime;
    CHAR Priority;
    UCHAR ForceDeferSchedule;
    UCHAR CaptureBaseline;
    UCHAR DeferAllocate;
    LIST_ENTRY QueuedWaitListEntry;
    LIST_ENTRY QueueListEntry;
    ULONG NextProcessor;
    ULONG DeferredProcessor;
    KPROCESS* Process;
    GROUP_AFFINITY Affinity;
    GROUP_AFFINITY UserAffinity;
    PVOID StartAddress;
    PVOID Win32StartAddress;
    ULONGLONG TebMappedLowVa;
    ULONG Cookie;
    ULONG IdealProcessor;
    LIST_ENTRY ThreadListEntry;
    KTHREAD_SCHEDULER* Scheduler;
    PVOID SListFaultAddress2;
    PVOID Scheduler;
    UNICODE_STRING* ThreadName;
    ULONG HeterogeneousCpuPolicy;
} KTHREAD, *PKTHREAD;

关键成员说明

  • Header (+0x000):调度器对象头,用于线程的等待/调度。
  • InitialStack (+0x028):内核栈底地址。
  • StackLimit (+0x030):内核栈顶地址。
  • KernelStack (+0x058):当前内核栈指针。
  • TrapFrame (+0x178):指向 _KTRAP_FRAME,保存用户态上下文(寄存器、断点等)。
  • ApcState (+0x078):APC(异步过程调用)状态,包含 APC 队列。
  • Teb (+0x0F0):指向用户态 TEB。
  • Process (+0x200):指向所属进程的 _KPROCESS
  • State (+0x1D8 附近):线程状态(0=Init, 1=Ready, 2=Running, 3=Standby, 4=Terminated, 5=Waiting, 6=Transition)。
  • ThreadListEntry (+0x248):链接到 KPROCESS.ThreadListHead 的链表节点。
  • Priority (+0x1D8):线程当前优先级。
  • PreviousMode (+0x1D0):先前执行模式(用户态/内核态),系统调用来源判断。

总结

Windows x64 内核结构体之间存在清晰的层级引用关系:

txt
KPCR → KPRCB → CurrentThread (ETHREAD)
                  ├── Tcb (KTHREAD)
                  │   ├── Process → KPROCESS
                  │   ├── TrapFrame → KTRAP_FRAME
                  │   └── Teb → TEB (用户态)
                  └── Cid {PID, TID}
        
EPROCESS
  ├── Pcb (KPROCESS)
  │   ├── DirectoryTableBase = CR3
  │   └── ThreadListHead → ETHREAD
  ├── Peb → PEB (用户态)
  ├── ActiveProcessLinks → 进程链表
  ├── DebugPort (反调试)
  └── ObjectTable (句柄表)

用户态访问路径GS:[0x30]→TEB→PEB→Ldr→模块链表

内核态访问路径GS:[0x188]→ETHREAD→KTHREAD→KPROCESS→EPROCESS

攻防关键偏移(x64):

技术结构体偏移说明
进程隐藏EPROCESS+0x2F8ActiveProcessLinks 断链
反调试EPROCESS+0x340DebugPort 清零
反调试PEB+0x02BeingDebugged
反调试PEB+0x60NtGlobalFlag
线程隐藏ETHREAD+0x510HideFromDebugger
模块基址PEB_LDR_DATA+0x020InMemoryOrderModuleList
页表切换KPROCESS+0x028DirectoryTableBase = CR3