进程线程001 进程线程结构体和KPCR

前言

进程线程的知识点很多,如果我们想了解问题的本质,就要从一些关键的结构体学起,先来介绍一个与进程密切相关的结构体

EPROCESS

每个进程在零环都有一个对应的结构体:EPROCESS,这个结构体包含了进程的所有重要信息。

这个结构体我们可以在windbg里面看到

kd> dt _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x098 ProcessLock      : _EX_PUSH_LOCK
   +0x0a0 CreateTime       : _LARGE_INTEGER
   +0x0a8 ExitTime         : _LARGE_INTEGER
   +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
   +0x0b4 UniqueProcessId  : Ptr32 Void
   +0x0b8 ActiveProcessLinks : _LIST_ENTRY
   +0x0c0 ProcessQuotaUsage : [2] Uint4B
   +0x0c8 ProcessQuotaPeak : [2] Uint4B
   +0x0d0 CommitCharge     : Uint4B
   +0x0d4 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
   +0x0d8 CpuQuotaBlock    : Ptr32 _PS_CPU_QUOTA_BLOCK
   +0x0dc PeakVirtualSize  : Uint4B
   +0x0e0 VirtualSize      : Uint4B
   +0x0e4 SessionProcessLinks : _LIST_ENTRY
   +0x0ec DebugPort        : Ptr32 Void
   +0x0f0 ExceptionPortData : Ptr32 Void
   +0x0f0 ExceptionPortValue : Uint4B
   +0x0f0 ExceptionPortState : Pos 0, 3 Bits
   +0x0f4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0f8 Token            : _EX_FAST_REF
   +0x0fc WorkingSetPage   : Uint4B
   +0x100 AddressCreationLock : _EX_PUSH_LOCK
   +0x104 RotateInProgress : Ptr32 _ETHREAD
   +0x108 ForkInProgress   : Ptr32 _ETHREAD
   +0x10c HardwareTrigger  : Uint4B
   +0x110 PhysicalVadRoot  : Ptr32 _MM_AVL_TABLE
   +0x114 CloneRoot        : Ptr32 Void
   +0x118 NumberOfPrivatePages : Uint4B
   +0x11c NumberOfLockedPages : Uint4B
   +0x120 Win32Process     : Ptr32 Void
   +0x124 Job              : Ptr32 _EJOB
   +0x128 SectionObject    : Ptr32 Void
   +0x12c SectionBaseAddress : Ptr32 Void
   +0x130 Cookie           : Uint4B
   +0x134 Spare8           : Uint4B
   +0x138 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
   +0x13c Win32WindowStation : Ptr32 Void
   +0x140 InheritedFromUniqueProcessId : Ptr32 Void
   +0x144 LdtInformation   : Ptr32 Void
   +0x148 VdmObjects       : Ptr32 Void
   +0x14c ConsoleHostProcess : Uint4B
   +0x150 DeviceMap        : Ptr32 Void
   +0x154 EtwDataSource    : Ptr32 Void
   +0x158 FreeTebHint      : Ptr32 Void
   +0x160 PageDirectoryPte : _HARDWARE_PTE
   +0x160 Filler           : Uint8B
   +0x168 Session          : Ptr32 Void
   +0x16c ImageFileName    : [15] UChar
   +0x17b PriorityClass    : UChar
   +0x17c JobLinks         : _LIST_ENTRY
   +0x184 LockedPagesList  : Ptr32 Void
   +0x188 ThreadListHead   : _LIST_ENTRY
   +0x190 SecurityPort     : Ptr32 Void
   +0x194 PaeTop           : Ptr32 Void
   +0x198 ActiveThreads    : Uint4B
   +0x19c ImagePathHash    : Uint4B
   +0x1a0 DefaultHardErrorProcessing : Uint4B
   +0x1a4 LastThreadExitStatus : Int4B
   +0x1a8 Peb              : Ptr32 _PEB
   +0x1ac PrefetchTrace    : _EX_FAST_REF
   +0x1b0 ReadOperationCount : _LARGE_INTEGER
   +0x1b8 WriteOperationCount : _LARGE_INTEGER
   +0x1c0 OtherOperationCount : _LARGE_INTEGER
   +0x1c8 ReadTransferCount : _LARGE_INTEGER
   +0x1d0 WriteTransferCount : _LARGE_INTEGER
   +0x1d8 OtherTransferCount : _LARGE_INTEGER
   +0x1e0 CommitChargeLimit : Uint4B
   +0x1e4 CommitChargePeak : Uint4B
   +0x1e8 AweInfo          : Ptr32 Void
   +0x1ec SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1f0 Vm               : _MMSUPPORT
   +0x25c MmProcessLinks   : _LIST_ENTRY
   +0x264 HighestUserAddress : Ptr32 Void
   +0x268 ModifiedPageCount : Uint4B
   +0x26c Flags2           : Uint4B
   +0x26c JobNotReallyActive : Pos 0, 1 Bit
   +0x26c AccountingFolded : Pos 1, 1 Bit
   +0x26c NewProcessReported : Pos 2, 1 Bit
   +0x26c ExitProcessReported : Pos 3, 1 Bit
   +0x26c ReportCommitChanges : Pos 4, 1 Bit
   +0x26c LastReportMemory : Pos 5, 1 Bit
   +0x26c ReportPhysicalPageChanges : Pos 6, 1 Bit
   +0x26c HandleTableRundown : Pos 7, 1 Bit
   +0x26c NeedsHandleRundown : Pos 8, 1 Bit
   +0x26c RefTraceEnabled  : Pos 9, 1 Bit
   +0x26c NumaAware        : Pos 10, 1 Bit
   +0x26c ProtectedProcess : Pos 11, 1 Bit
   +0x26c DefaultPagePriority : Pos 12, 3 Bits
   +0x26c PrimaryTokenFrozen : Pos 15, 1 Bit
   +0x26c ProcessVerifierTarget : Pos 16, 1 Bit
   +0x26c StackRandomizationDisabled : Pos 17, 1 Bit
   +0x26c AffinityPermanent : Pos 18, 1 Bit
   +0x26c AffinityUpdateEnable : Pos 19, 1 Bit
   +0x26c PropagateNode    : Pos 20, 1 Bit
   +0x26c ExplicitAffinity : Pos 21, 1 Bit
   +0x270 Flags            : Uint4B
   +0x270 CreateReported   : Pos 0, 1 Bit
   +0x270 NoDebugInherit   : Pos 1, 1 Bit
   +0x270 ProcessExiting   : Pos 2, 1 Bit
   +0x270 ProcessDelete    : Pos 3, 1 Bit
   +0x270 Wow64SplitPages  : Pos 4, 1 Bit
   +0x270 VmDeleted        : Pos 5, 1 Bit
   +0x270 OutswapEnabled   : Pos 6, 1 Bit
   +0x270 Outswapped       : Pos 7, 1 Bit
   +0x270 ForkFailed       : Pos 8, 1 Bit
   +0x270 Wow64VaSpace4Gb  : Pos 9, 1 Bit
   +0x270 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x270 SetTimerResolution : Pos 12, 1 Bit
   +0x270 BreakOnTermination : Pos 13, 1 Bit
   +0x270 DeprioritizeViews : Pos 14, 1 Bit
   +0x270 WriteWatch       : Pos 15, 1 Bit
   +0x270 ProcessInSession : Pos 16, 1 Bit
   +0x270 OverrideAddressSpace : Pos 17, 1 Bit
   +0x270 HasAddressSpace  : Pos 18, 1 Bit
   +0x270 LaunchPrefetched : Pos 19, 1 Bit
   +0x270 InjectInpageErrors : Pos 20, 1 Bit
   +0x270 VmTopDown        : Pos 21, 1 Bit
   +0x270 ImageNotifyDone  : Pos 22, 1 Bit
   +0x270 PdeUpdateNeeded  : Pos 23, 1 Bit
   +0x270 VdmAllowed       : Pos 24, 1 Bit
   +0x270 CrossSessionCreate : Pos 25, 1 Bit
   +0x270 ProcessInserted  : Pos 26, 1 Bit
   +0x270 DefaultIoPriority : Pos 27, 3 Bits
   +0x270 ProcessSelfDelete : Pos 30, 1 Bit
   +0x270 SetTimerResolutionLink : Pos 31, 1 Bit
   +0x274 ExitStatus       : Int4B
   +0x278 VadRoot          : _MM_AVL_TABLE
   +0x298 AlpcContext      : _ALPC_PROCESS_CONTEXT
   +0x2a8 TimerResolutionLink : _LIST_ENTRY
   +0x2b0 RequestedTimerResolution : Uint4B
   +0x2b4 ActiveThreadsHighWatermark : Uint4B
   +0x2b8 SmallestTimerResolution : Uint4B
   +0x2bc TimerResolutionStackRecord : Ptr32 _PO_DIAG_STACK_RECORD

这个结构体里面有太多的成员,我们并不需要了解其中的每一个细节,下面介绍几个重要的成员

KPROCESS主要成员

EPROCESS偏移为0的地方是_KPROCESS结构体

kd> dt _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS

+0x000 Header

我们查看一下这个_KPROCESS结构体的内容

kd> dt _KPROCESS 
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER

_KPROCESS第一个成员叫Header,这个成员的类型是_DISPATCHER_HEADER。只有结构体里包含这个_DISPATCHER_HEADER数据类型,那么它就可以成为可等待对象。比如Mutex互斥体、Event事件等等(WaitForSingleObject)

**+0x018 DirectoryTableBase **

kd> dt _KPROCESS 
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 ProfileListHead  : _LIST_ENTRY
   +0x018 DirectoryTableBase : Uint4B

这个字段保存的是页目录表的基址,也就是CR3寄存器的值

+0x038 KernelTime&+0x03c UserTime : Uint4B

统计信息,记录了一个进程在内核模式/用户模式下所花的时间

+0x05c Affinity : Uint4B

在多核环境下,规定进程里面的所有线程能在哪个CPU上跑,如果值为1,那么这个进程的所有线程只能在0号CPU上跑(00000001)

如果值为3,那这个进程的所有线程能在0 1号CPU上跑(00000011)

如果值为4,那这个进程的所有线程能在2号CPU上跑(00000100)

如果值为5,那这个进程的所有线程能在0 2号CPU上跑(00000101)

4个字节共32位,所以最多32核,如果是Windows64位的操作系统,最多就64核

如果只有一个CPU,把这个设置为4,那么这个进程就死了

+0x062 BasePriority : Char

基础优先级或最低优先级,该进程中所有线程最起码的优先级。这个值设置成多少,那么这个进程下所有的线程默认的优先级就是多少。

EPROCESS其他成员

+0x070 CreateTime &+0x078 ExitTime : _LARGE_INTEGER

进程的创建/退出时间

+0x084 UniqueProcessId : Ptr32 Void

进程的编号 任务管理器中的PID

+0x088 ActiveProcessLinks : _LIST_ENTRY

在操作系统里,有一个全局变量PsActiveProcessHead

kd> dd PsActiveProcessHead
83f60f18  85edb9d8 884498b0 00000000 00000000
83f60f28  83ed448c 00000000 00000000 8ae01108
83f60f38  00000000 80000020 00000101 800002e4
83f60f48  80000024 00000000 00000000 00000000
83f60f58  00000000 00000000 00000113 00000000
83f60f68  00000000 83f1135a 00000000 00000000
83f60f78  00000000 00000000 00000008 00000000
83f60f88  83f60f88 83f60f88 00000000 00000000

这个全局变量是所有活动进程的链表头。而 ActiveProcessLinks : _LIST_ENTRY这个字段是一个双向链表,将所有的活动进程连接在一起。

PsActiveProcessHead就是链表头的位置。遍历进程的API,查的就是这个链表。如果将当前进程从链表中移除,就可以实现进程隐藏,这种技术称为断链。

在这里插入图片描述

+0x090 QuotaUsage&+0x09c QuotaPeak: [3] Uint4B

​ 物理页相关的统计信息

+0x0a8 CommitCharge&+0x0ac PeakVirtualSize&+0x0b0 VirtualSize : Uint4B

虚拟内存相关的统计信息

+0x11c VadRoot : Ptr32 Void

标识0-2G哪些地址没占用了

+0x0bc DebugPort&+0x0c0 ExceptionPort: Ptr32 Void

调试相关

**+0x0c4 ObjectTable: Ptr32 _HANDLE_TABLE **

句柄表

+0x174 ImageFileName : [16] UChar

进程镜像文件名 最多16个字节

+0x1a0 ActiveThreads : Uint4B

活动线程的数量

+0x1b0 Peb : Ptr32 _PEB

PEB((Process Environment Block 进程环境块):进程在3环的一个结构体,里面包含了进程的模块列表、是否处于调试状态等信息

ETHREAD

每个Windows线程在0环都有一个对应的结构体:ETHREAD,这个结构体包含了线程所有重要的信息

KTHREAD主要成员介绍

kd> dt _ETHREAD
nt!_ETHREAD
   +0x000 Tcb              : _KTHREAD

ETHREAD结构体的第一个成员就是KTHREAD,下面介绍KTHREAD的主要成员

+0x000 Header: _DISPATCHER_HEADER

“可等待”对象,比如Mutex互斥体、Event事件等(WaitForSingleObject)

+0x018 InitialStack : Ptr32 Void

+0x01c StackLimit : Ptr32 Void

+0x028 KernelStack : Ptr32 Void

线程切换相关

  • InitialStack:初始堆栈
  • StackLimit: 零环线程堆栈的界限
  • KernelStack:记录当前零环的堆栈栈顶

+0x020 Teb : Ptr32 Void

TEB,Thread Environment Block,线程环境块。

大小4KB,位于用户地址空间。

FS:[0] -> TEB(3环时 0环时FS执行KPCR)

+0x02c DebugActive : UChar

如果值为-1 不能使用调试寄存器:Dr0 - Dr7

+0x034 ApcState : _KAPC_STATE

+0x0e8 ApcQueueLock : Uint4B

+0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE

+0x14c SavedApcState : _KAPC_STATE

APC相关

+0x02d State : UChar

线程状态:就绪、等待还是运行

+0x06c BasePriority : Char

其初始值是所属进程的BasePriority值(KPROCESS->BasePriority),以后可以通过KeSetBasePriorityThread()函数重新设定

**+0x070 WaitBlock : [4] _KWAIT_BLOCK **

等待哪个对象(WaitForSingleObject)

**+0x0e0 ServiceTable : Ptr32 Void **

指向系统服务表基址

+0x134 TrapFrame

进0环时保存环境

+0x140 PreviousMode : Char

先前模式:某些内核函数会判断程序是0环调用还是3环调用的

**+0x1b0 ThreadListEntry : _LIST_ENTRY **

双向链表:当前进程所有的线程 都挂在一个链表中 挂的就是这个位置

一共有两个这样的链表,如图:

在这里插入图片描述

ETHREAD其他成员介绍

+0x1ec Cid:_CLIENT_ID

这个结构体里面保存有进程ID和线程ID

+0x220 ThreadsProcess:Ptr32 _EPROCESS

指向当前线程的所属进程

+0x22C ThreadListEntry:_LIST_ENTRY

双向链表,一个进程所有的线程,都挂在一个链表中

KPCR

KPCR:CPU控制区(Kernel Processor Control Region)

KPCR介绍

  1. 当线程进入0环时,FS:[0]指向KPCR
  2. 每个CPU都有一个KPCR结构体(一个核一个)
  3. KPCR中存储了CPU本身要用到的一些重要的数据:GDT IDT以及线程相关的一些信息

_NT_TIB主要成员介绍

kd> dt _KPCR
nt!_KPCR
   +0x000 NtTib            : _NT_TIB

_NT_TIB是KPCR的第一个成员,来查看一下这个结构体的成员

kd> dt _NT_TIB
nt!_NT_TIB
   +0x000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x004 StackBase        : Ptr32 Void
   +0x008 StackLimit       : Ptr32 Void
   +0x00c SubSystemTib     : Ptr32 Void
   +0x010 FiberData        : Ptr32 Void
   +0x010 Version          : Uint4B
   +0x014 ArbitraryUserPointer : Ptr32 Void
   +0x018 Self             : Ptr32 _NT_TIB

+0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD

当前线程的SEH链表

+0x004 StackBase : Ptr32 Void

当前线程内核栈的基址

+0x008 StackLimit : Ptr32 Void

当前线程内核栈的大小

+0x018 Self : Ptr32 _NT_TIB

指向自己(也就是指向KPCR结构) 这样设计的目的是为了查找方便

KPCR的其他成员介绍

+0x01c SelfPcr : Ptr32 _KPCR

指向自己,方便寻址

+0x020 Prcb : Ptr32 _KPRCB

指向拓展结构体PRCB

+0x038 IDT : Ptr32 _KIDTENTRY

IDT表基址

**+0x03c GDT : Ptr32 _KGDTENTRY **

GDT表基址

**+0x040 TSS : Ptr32 _KTSS **

指针,指向TSS,每个CPU都有一个TSS

+0x051 Number : UChar

CPU编号:0 1 2 3 4 5。。。

**+0x120 PrcbData : _KPRCB **

拓展结构体

KPRCB成员介绍

KPRCB是KPCR的拓展结构体

**+0x004 CurrentThread : Ptr32 _KTHREAD:**当前线程

+0x008 NextThread : Ptr32 _KTHREAD: 即将切换的下一个线程

+0x00c IdleThread : Ptr32 _KTHREAD : 空闲线程

IDTENTRY**

IDT表基址

**+0x03c GDT : Ptr32 _KGDTENTRY **

GDT表基址

**+0x040 TSS : Ptr32 _KTSS **

指针,指向TSS,每个CPU都有一个TSS

+0x051 Number : UChar

CPU编号:0 1 2 3 4 5。。。

**+0x120 PrcbData : _KPRCB **

拓展结构体

KPRCB成员介绍

KPRCB是KPCR的拓展结构体

**+0x004 CurrentThread : Ptr32 _KTHREAD:**当前线程

+0x008 NextThread : Ptr32 _KTHREAD: 即将切换的下一个线程

+0x00c IdleThread : Ptr32 _KTHREAD : 空闲线程

发布了99 篇原创文章 · 获赞 89 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_38474570/article/details/103722984
今日推荐