您的位置:首页 > 其它

进程线程篇——进程线程基础

2021-11-23 20:34 78 查看 https://www.cnblogs.com/wingsu

写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

你如果是从中间插过来看的,请仔细阅读 羽夏看Win系统内核——简述 ,方便学习本教程。

  看此教程之前,问几个问题,基础知识储备好了吗?保护模式篇学会了吗?系统调用篇学会了吗?练习做完了吗?没有的话就不要继续了。

🔒 华丽的分割线 🔒

  为了更好的学习进程与线程,我们需要充分了解3个结构体:

EPROCESS
EHTREAD
KPCR
,下面将会进行详细介绍。

EPROCESS

  每个

windows
进程在0环都有一个对应的结构体:
EPROCESS
,这个结构体包含了进程所有重要的信息。我们先看看里面的成员有哪些:

kd> dt _EPROCESS
ntdll!_EPROCESS
+0x000 Pcb              : _KPROCESS
+0x06c ProcessLock      : _EX_PUSH_LOCK
+0x070 CreateTime       : _LARGE_INTEGER
+0x078 ExitTime         : _LARGE_INTEGER
+0x080 RundownProtect   : _EX_RUNDOWN_REF
+0x084 UniqueProcessId  : Ptr32 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY
+0x090 QuotaUsage       : [3] Uint4B
+0x09c QuotaPeak        : [3] Uint4B
+0x0a8 CommitCharge     : Uint4B
+0x0ac PeakVirtualSize  : Uint4B
+0x0b0 VirtualSize      : Uint4B
+0x0b4 SessionProcessLinks : _LIST_ENTRY
+0x0bc DebugPort        : Ptr32 Void
+0x0c0 ExceptionPort    : Ptr32 Void
+0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE
+0x0c8 Token            : _EX_FAST_REF
+0x0cc WorkingSetLock   : _FAST_MUTEX
+0x0ec WorkingSetPage   : Uint4B
+0x0f0 AddressCreationLock : _FAST_MUTEX
+0x110 HyperSpaceLock   : Uint4B
+0x114 ForkInProgress   : Ptr32 _ETHREAD
+0x118 HardwareTrigger  : Uint4B
+0x11c VadRoot          : Ptr32 Void
+0x120 VadHint          : Ptr32 Void
+0x124 CloneRoot        : Ptr32 Void
+0x128 NumberOfPrivatePages : Uint4B
+0x12c NumberOfLockedPages : Uint4B
+0x130 Win32Process     : Ptr32 Void
+0x134 Job              : Ptr32 _EJOB
+0x138 SectionObject    : Ptr32 Void
+0x13c SectionBaseAddress : Ptr32 Void
+0x140 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
+0x144 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
+0x148 Win32WindowStation : Ptr32 Void
+0x14c InheritedFr
ad8
omUniqueProcessId : Ptr32 Void
+0x150 LdtInformation   : Ptr32 Void
+0x154 VadFreeHint      : Ptr32 Void
+0x158 VdmObjects       : Ptr32 Void
+0x15c DeviceMap        : Ptr32 Void
+0x160 PhysicalVadList  : _LIST_ENTRY
+0x168 PageDirectoryPte : _HARDWARE_PTE_X86
+0x168 Filler           : Uint8B
+0x170 Session          : Ptr32 Void
+0x174 ImageFileName    : [16] UChar
+0x184 JobLinks         : _LIST_ENTRY
+0x18c LockedPagesList  : Ptr32 Void
+0x190 ThreadListHead   : _LIST_ENTRY
+0x198 SecurityPort     : Ptr32 Void
+0x19c PaeTop           : Ptr32 Void
+0x1a0 ActiveThreads    : Uint4B
+0x1a4 GrantedAccess    : Uint4B
+0x1a8 DefaultHardErrorProcessing : Uint4B
+0x1ac LastThreadExitStatus : Int4B
+0x1b0 Peb              : Ptr32 _PEB
+0x1b4 PrefetchTrace    : _EX_FAST_REF
+0x1b8 ReadOperationCount : _LARGE_INTEGER
+0x1c0 WriteOperationCount : _LARGE_INTEGER
+0x1c8 OtherOperationCount : _LARGE_INTEGER
+0x1d0 ReadTransferCount : _LARGE_INTEGER
+0x1d8 WriteTransferCount : _LARGE_INTEGER
+0x1e0 OtherTransferCount : _LARGE_INTEGER
+0x1e8 CommitChargeLimit : Uint4B
+0x1ec CommitChargePeak : Uint4B
+0x1f0 AweInfo          : Ptr32 Void
+0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
+0x1f8 Vm               : _MMSUPPORT
+0x238 LastFaultCount   : Uint4B
+0x23c ModifiedPageCount : Uint4B
+0x240 NumberOfVads     : Uint4B
+0x244 JobStatus        : Uint4B
+0x248 Flags            : Uint4B
+0x248 CreateReported   : Pos 0, 1 Bit
+0x248 NoDebugInherit   : Pos 1, 1 Bit
+0x248 ProcessExiting   : Pos 2, 1 Bit
+0x248 ProcessDelete    : Pos 3, 1 Bit
+0x248 Wow64SplitPages  : Pos 4, 1 Bit
+0x248 VmDeleted        : Pos 5, 1 Bit
+0x248 OutswapEnabled   : Pos 6, 1 Bit
+0x248 Outswapped       : Pos 7, 1 Bit
+0x248 ForkFailed       : Pos 8, 1 Bit
+0x248 HasPhysicalVad   : Pos 9, 1 Bit
+0x248 AddressSpaceInitialized : Pos 10, 2 Bits
+0x248 SetTimerResolution : Pos 12, 1 Bit
+0x248 BreakOnTermination : Pos 13, 1 Bit
+0x248 SessionCreationUnderway : Pos 14, 1 Bit
+0x248 WriteWatch       : Pos 15, 1 Bit
+0x248 ProcessInSession : Pos 16, 1 Bit
+0x248 OverrideAddressSpace : Pos 17, 1 Bit
+0x248 HasAddressSpace  : Pos 18, 1 Bit
+0x248 LaunchPrefetched : Pos 19, 1 Bit
+0x248 InjectInpageErrors : Pos 20, 1 Bit
+0x248 VmTopDown        : Pos 21, 1 Bit
+0x248 Unused3          : Pos 22, 1 Bit
+0x248 Unused4          : Pos 23, 1 Bit
+0x248 VdmAllowed       : Pos 24, 1 Bit
+0x248 Unused           : Pos 25, 5 Bits
+0x248 Unused1          : Pos 30, 1 Bit
+0x248 Unused2          : Pos 31, 1 Bit
+0x24c ExitStatus       : Int4B
+0x250 NextPageColor    : Uint2B
+0x252
ad0
SubSystemMinorVersion : UChar
+0x253 SubSystemMajorVersion : UChar
+0x252 SubSystemVersion : Uint2B
+0x254 PriorityClass    : UChar
+0x255 WorkingSetAcquiredUnsafe : UChar
+0x258 Cookie           : Uint4B

  虽然有很多成员,我们只要知道几个重要的成员即可,由于

Windows
是闭源的,如果需要详细了解就必须花费大量的时间进行逆向分析才能明白。这个结构体还嵌套了一个结构体
_KPROCESS
,我们看一下:

kd> dt _KPROCESS
ntdll!_KPROCESS
+0x000 Header           : _DISPATCHER_HEADER
+0x010 ProfileListHead  : _LIST_ENTRY
+0x018 DirectoryTableBase : [2] Uint4B
+0x020 LdtDescriptor    : _KGDTENTRY
+0x028 Int21Descriptor  : _KIDTENTRY
+0x030 IopmOffset       : Uint2B
+0x032 Iopl             : UChar
+0x033 Unused           : UChar
+0x034 ActiveProcessors : Uint4B
+0x038 KernelTime       : Uint4B
+0x03c UserTime         : Uint4B
+0x040 ReadyListHead    : _LIST_ENTRY
+0x048 SwapListEntry    : _SINGLE_LIST_ENTRY
+0x04c VdmTrapcHandler  : Ptr32 Void
+0x050 ThreadListHead   : _LIST_ENTRY
+0x058 ProcessLock      : Uint4B
+0x05c Affinity         : Uint4B
+0x060 StackCount       : Uint2B
+0x062 BasePriority     : Char
+0x063 ThreadQuantum    : Char
+0x064 AutoAlignment    : UChar
+0x065 State            : UChar
+0x066 ThreadSeed       : UChar
+0x067 DisableBoost     : UChar
+0x068 PowerState       : UChar
+0x069 DisableQuantum   : UChar
+0x06a IdealNode        : UChar
+0x06b Flags            : _KEXECUTE_OPTIONS
+0x06b ExecuteOptions   : UChar

Header

  在3环使用

API
的时候,我们都用过等待对象的函数,为什么有的内核对象是可以等待的?是因为它有
_DISPATCHER_HEADER
这个结构。

DirectoryTableBase

  页目录表的基址,也就是所谓的

CR3

LdtDescriptor / Int21Descriptor

  历史遗留问题,16位

Windows
段选择子不够,每个进程都有一个
LDT
表,
Int21Descriptor
DOS
下要用的。

KernelTime / UserTime

  统计信息,记录了一个进程在内核模式/用户模式下所花的时间,没什么太大的用处。

Affinity

  这个成员十分重要,它有4个字节,每一个二进制位控制进程里面的所有线程能在哪个

CPU
上跑,如果值为1,那这个进程的所以线程只能在0号
CPU上跑;如果值为3,那这个进程的所以线程能在0、1号CPU
上跑;如果值为4,那这个进程的所以线程能在2号
CPU
上跑;如果值为5,那这个进程的所以线程能在0,2号
CPU
上跑。如果只有一个
CPU
,把这个设置为4,那么这个进程就死了。
  由于4个字节共32位,所以最多支持32核。64位的
Windows
这个成员就是8个字节了,最多支持64核。

BasePriority

  基础优先级或最低优先级,该进程中的所有线程最起码的优先级。

CreateTime / ExitTime

  统计信息,记录了一个进程的创建/退出时间。

UniqueProcessId

  进程的编号,也就是任务管理器中显示的

PID

ActiveProcessLinks

  所有的活动进程都连接在一起,构成的双向链表。全局变量

PsActiveProcessHead
指向这个全局链的表头。如下是示意图:

QuotaUsage / QuotaPeak

  物理页相关的统计信息。

CommitCharge / PeakVirtualSize / VirtualSize

  虚拟内存相关的统计信息。

VadRoot

  这东西我们之前介绍过,是一个二叉树,指示了进程的线性地址的使用情况和记录。

DebugPort / ExceptionPort

  调试相关,经常有人使用

DebugPort
清零实现反调试。

ObjectTable

  句柄表,装着内核对象句柄,是用来标识某个内核对象的一个

id
,同一个对象的该
id
对于每个进程是不同的。后面的教程将会对句柄表进行讲解。

ImageFileName

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

ActiveThreads

  活动线程的数量。

Peb

  英文全称为

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

ETHREAD

  每个

Windows
线程在0环都有一个对应的结构体
ETHREAD
,这个结构体我们曾在前面对某一部分进行简略的讲解,本篇将会详细介绍重要成员,它的结构体如下所示:

kd> dt _ETHREAD
ntdll!_ETHREAD
+0x000 Tcb              : _KTHREAD
+0x1c0 CreateTime       : _LARGE_INTEGER
+0x1c0 NestedFaultCount : Pos 0, 2 Bits
+0x1c0 ApcNeeded        : Pos 2, 1 Bit
+0x1c8 ExitTime         : _LARGE_INTEGER
+0x1c8 LpcReplyChain    : _LIST_ENTRY
+0x1c8 KeyedWaitChain   : _LIST_ENTRY
+0x1d0 ExitStatus       : Int4B
+0x1d0 OfsChain         : Ptr32 Void
+0x1d4 PostBlockList    : _LIST_ENTRY
+0x1dc TerminationPort  : Ptr32 _TERMINATION_PORT
+0x1dc ReaperLink       : Ptr32 _ETHREAD
+0x1dc KeyedWaitValue   : Ptr32 Void
+0x1e0 ActiveTimerListLock : Uint4B
+0x1e4 ActiveTimerListHead : _LIST_ENTRY
+0x1ec Cid              : _CLIENT_ID
+0x1f4 LpcReplySemaphore : _KSEMAPHORE
+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
+0x208 LpcReplyMessage  : Ptr32 Void
+0x208 LpcWaitingOnPort : Ptr32 Void
+0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION
+0x210 IrpList          : _LIST_ENTRY
+0x218 TopLevelIrp      : Uint4B
+0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT
+0x220 ThreadsProcess   : Ptr32 _EPROCESS
+0x224 StartAddress     : Ptr32 Void
+0x228 Win32StartAddress : Ptr32 Void
+0x228 LpcReceivedMessageId : Uint4B
+0x22c ThreadListEntry  : _LIST_ENTRY
+0x234 RundownProtect   : _EX_RUNDOWN_REF
+0x238 ThreadLock       : _EX_PUSH_LOCK
+0x23c LpcReplyMessageId : Uint4B
+0x240 ReadClusterSize  : Uint4B
+0x244 GrantedAccess    : Uint4B
+0x248 CrossThreadFlags : Uint4B
+0x248 Terminated       : Pos 0, 1 Bit
+0x248 DeadThread       : Pos 1, 1 Bit
+0x248 HideFromDebugger : Pos 2, 1 Bit
+0x248 ActiveImpersonationInfo : Pos 3, 1 Bit
+0x248 SystemThread     : Pos 4, 1 Bit
+0x248 HardErrorsAreDisabled : Pos 5, 1 Bit
+0x248 BreakOnTermination : Pos 6, 1 Bit
+0x248 SkipCreationMsg  : Pos 7, 1 Bit
+0x248 SkipTerminationMsg : Pos 8, 1 Bit
+0x24c SameThreadPassiveFlags : Uint4B
+0x24c ActiveExWorker   : Pos 0, 1 Bit
+0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit
+0x24c MemoryMaker      : Pos 2, 1 Bit
+0x250 SameThreadApcFlags : Uint4B
+0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
+0x250 LpcExitThreadCalled : Pos 1, 1 Bit
+0x250 AddressSpaceOwner : Pos 2, 1 Bit
+0x254 ForwardClusterOnly : UChar
+0x255 DisablePageFaultClustering : UChar

  第一个成员还嵌套了一个结构体,我们查看一下:

kd> dt _KTHREAD
ntdll!_KTHREAD
+0x000 Header           : _DISPATCHER_HEADER
+0x010 MutantListHead   : _LIST_ENTRY
+0x018 InitialStack     : Ptr32 Void
+0x01c StackLimit       : Ptr32 Void
+0x020 Teb              : Ptr32 Void
+0x024 TlsArray         : Ptr32 Void
+0x028 KernelStack      : Ptr32 Void
+0x02c DebugActive      : UChar
+0x02d State            : UChar
+0x02e Alerted          : [2] UChar
+0x030 Iopl             : UChar
+0x031 NpxState         : UChar
+0x032 Saturation       : Char
+0x033 Priority         : Char
+0x034 ApcState         : _KAPC_STATE
+0x04c ContextSwitches  : Uint4B
+0x050 IdleSwapBlock    : UChar
+0x051 Spare0           : [3] UChar
+0x054 WaitStatus       : Int4B
+0x058 WaitIrql         : UChar
+0x059 WaitMode         : Char
+0x05a WaitNext         : UChar
+0x05b WaitReason       : UChar
+0x05c WaitBlockList    : Ptr32 _KWAIT_BLOCK
+0x060 WaitListEntry    : _LIST_ENTRY
+0x060 SwapListEntry    : _SINGLE_LIST_ENTRY
+0x068 WaitTime         : Uint4B
+0x06c BasePriority     : Char
+0x06d DecrementCount   : UChar
+0x06e PriorityDecrement : Char
+0x06f Quantum          : Char
+0x070 WaitBlock        : [4] _KWAIT_BLOCK
+0x0d0 LegoData         : Ptr32 Void
+0x0d4 KernelApcDisable : Uint4B
+0x0d8 UserAffinity     : Uint4B
+0x0dc SystemAffinityActive : UChar
+0x0dd PowerState       : UChar
+0x0de NpxIrql          : UChar
+0x0df InitialNode      : UChar
+0x0e0 ServiceTable     : Ptr32 Void
+0x0e4 Queue            : Ptr32 _KQUEUE
+0x0e8 ApcQueueLock     : Uint4B
+0x0f0 Timer            : _KTIMER
+0x118 QueueListEntry   : _LIST_ENTRY
+0x120 SoftAffinity     : Uint4B
+0x124 Affinity         : Uint4B
+0x128 Preempted        : UChar
+0x129 ProcessReadyQueue : UChar
+0x12a KernelStackResident : UChar
+0x12b NextProcessor    : UChar
+0x12c CallbackStack    : Ptr32 Void
+0x130 Win32Thread      : Ptr32 Void
+0x134 TrapFrame        : Ptr32 _KTRAP_FRAME
+0x138 ApcStatePointer  : [2] Ptr32 _KAPC_STATE
+0x140 PreviousMode     : Char
+0x141 EnableStackSwap  : UChar
+0x142 LargeStack       : UChar
+0x143 ResourceIndex    : UChar
+0x144 KernelTime       : Uint4B
+0x148 UserTime         : Uint4B
+0x14c SavedApcState    : _KAPC_STATE
+0x164 Alertable        : UChar
+0x165 ApcStateIndex    : UChar
+0x166 ApcQueueable     : UChar
+0x167 AutoAlignment    : UChar
+0x168 StackBase        : Ptr32 Void
+0x16c SuspendApc       : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry  : _LIST_ENTRY
+0x1b8 FreezeCount      : Char
+0x1b9 SuspendCount     : Char
+0x1ba IdealProcessor   : UChar
+0x1bb DisableBoost     : UChar

Header

  和

EPROCESS
一样的,就不赘述了。

InitialStack / StackLimit / KernelStack

  这三个成员十分重要,与线程切换相关。

KernelStack
为当前切换线程的
esp
,它们的细节将会在后面的随笔介绍。

Teb

  英文全称为

Thread Environment Block
,意为线程环境块,大小4KB,位于用户地址空间。在3环时,
fs
寄存器中存储该结构。

DebugActive

  如果值为-1,则不能使用调试寄存器

Dr0
-
Dr7

ApcState / ApcQueueLock / ApcStatePointer / SavedApcState

  

APC
相关,具体细节将会在后面的一个篇章进行讲解。

State

  指示线程状态:

waiting
/
ready
/
running

BasePriority

  其初始值是所属进程的

BasePriority
值,以后可以通过
KeSetBasePriorityThread
函数重新设定。

WaitBlock

  里面存储了等待哪个对象,比如调用

WaitForSingleObject

ServiceTable

  指向系统服务表基址。

TrapFrame

  存储着进0环时保存环境。

PreviousMode

  先前模式,指示程序是0环调用还是3环调用的。

ThreadListEntry

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

KTHREAD
一个,
ETHREAD
外面一个,示意图如下:

Cid

  存储着进程ID和线程ID,它的结构体如下:

kd> dt _CLIENT_ID
ntdll!_CLIENT_ID
+0x000 UniqueProcess    : Ptr32 Void
+0x004 UniqueThread     : Ptr32 Void

ThreadsProcess

  指向自己所属进程。

KPCR

  

KPCR
中存储了
CPU
本身要用的一些重要数据:
GDT
IDT
以及线程相关的一些信息。当线程进入0环时,
FS:[0]
指向
KPCR
,3环时
FS:[0]
指向
TEB
。每个
CPU
都有一个
KPCR
结构体,即一个核一个。之前也略有介绍,它的结构如下:

kd> dt _KPCR
nt!_KPCR
+0x000 NtTib            : _NT_TIB
+0x01c SelfPcr          : Ptr32 _KPCR
+0x020 Prcb             : Ptr32 _KPRCB
+0x024 Irql             : UChar
+0x028 IRR              : Uint4B
+0x02c IrrActive        : Uint4B
+0x030 IDR              : Uint4B
+0x034 KdVersionBlock   : Ptr32 Void
+0x038 IDT              : Ptr32 _KIDTENTRY
+0x03c GDT              : Ptr32 _KGDTENTRY
+0x040 TSS              : Ptr32 _KTSS
+0x044 MajorVersion     : Uint2B
+0x046 MinorVersion     : Uint2B
+0x048 SetMember        : Uint4B
+0x04c StallScaleFactor : Uint4B
+0x050 DebugActive      : UChar
+0x051 Number           : UChar
+0x052 Spare0           : UChar
+0x053 SecondLevelCacheAssociativity : UChar
+0x054 VdmAlert         : Uint4B
+0x058 KernelReserved   : [14] Uint4B
+0x090 SecondLevelCacheSize : Uint4B
+0x094 HalReserved      : [16] Uint4B
+0x0d4 InterruptMode    : Uint4B
+0x0d8 Spare1           : UChar
+0x0dc KernelReserved2  : [17] Uint4B
+0x120 PrcbData         : _KPRCB

NtTib

  我们先看第一个成员,它的结构体如下:

kd> dt _NT_TIB
ntdll!_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

ExceptionList

  存储当前线程内核异常链表,简称

SEH

StackBase / StackLimit

  存储当前线程内核栈的基址和大小。

Self

  指向自己的指针,也就是指向

KPCR
结构,这样设计的目的是为了查找方便,只需要一个偏移就能知道自己的地址。

SelfPcr

  指向自己,方便寻址。

Prcb

  指向拓展结构体

PRCB
的地址。

IDT

  指向

IDT
表基址。

GDT

  指向

GDT
表基址。

TSS

  指向

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

Number

  CPU编号,从0开始索引。

PrcbData

  拓展结构体,它是结构体如下所示:

kd> dt _KPRCB
ntdll!_KPRCB
+0x000 MinorVersion     : Uint2B
+0x002 MajorVersion     : Uint2B
+0x004 CurrentThread    : Ptr32 _KTHREAD
+0x008 NextThread       : Ptr32 _KTHREAD
+0x00c IdleThread       : Ptr32 _KTHREAD
+0x010 Number           : Char
+0x011 Reserved         : Char
+0
ad8
x012 BuildType        : Uint2B
+0x014 SetMember        : Uint4B
+0x018 CpuType          : Char
+0x019 CpuID            : Char
+0x01a CpuStep          : Uint2B
+0x01c ProcessorState   : _KPROCESSOR_STATE
+0x33c KernelReserved   : [16] Uint4B
+0x37c HalReserved      : [16] Uint4B
+0x3bc PrcbPad0         : [92] UChar
+0x418 LockQueue        : [16] _KSPIN_LOCK_QUEUE
+0x498 PrcbPad1         : [8] UChar
+0x4a0 NpxThread        : Ptr32 _KTHREAD
+0x4a4 InterruptCount   : Uint4B
+0x4a8 KernelTime       : Uint4B
+0x4ac UserTime         : Uint4B
+0x4b0 DpcTime          : Uint4B
+0x4b4 DebugDpcTime     : Uint4B
+0x4b8 InterruptTime    : Uint4B
+0x4bc AdjustDpcThreshold : Uint4B
+0x4c0 PageColor        : Uint4B
+0x4c4 SkipTick         : Uint4B
+0x4c8 MultiThreadSetBusy : UChar
+0x4c9 Spare2           : [3] UChar
+0x4cc ParentNode       : Ptr32 _KNODE
+0x4d0 MultiThreadProcessorSet : Uint4B
+0x4d4 MultiThreadSetMaster : Ptr32 _KPRCB
+0x4d8 ThreadStartCount : [2] Uint4B
+0x4e0 CcFastReadNoWait : Uint4B
+0x4e4 CcFastReadWait   : Uint4B
+0x4e8 CcFastReadNotPossible : Uint4B
+0x4ec CcCopyReadNoWait : Uint4B
+0x4f0 CcCopyReadWait   : Uint4B
+0x4f4 CcCopyReadNoWaitMiss : Uint4B
+0x4f8 KeAlignmentFixupCount : Uint4B
+0x4fc KeContextSwitches : Uint4B
+0x500 KeDcacheFlushCount : Uint4B
+0x504 KeExceptionDispatchCount : Uint4B
+0x508 KeFirstLevelTbFills : Uint4B
+0x50c KeFloatingEmulationCount : Uint4B
+0x510 KeIcacheFlushCount : Uint4B
+0x514 KeSecondLevelTbFills : Uint4B
+0x518 KeSystemCalls    : Uint4B
+0x51c SpareCounter0    : [1] Uint4B
+0x520 PPLookasideList  : [16] _PP_LOOKASIDE_LIST
+0x5a0 PPNPagedLookasideList : [32] _PP_LOOKASIDE_LIST
+0x6a0 PPPagedLookasideList : [32] _PP_LOOKASIDE_LIST
+0x7a0 PacketBarrier    : Uint4B
+0x7a4 ReverseStall     : Uint4B
+0x7a8 IpiFrame         : Ptr32 Void
+0x7ac PrcbPad2         : [52] UChar
+0x7e0 CurrentPacket    : [3] Ptr32 Void
+0x7ec TargetSet        : Uint4B
+0x7f0 WorkerRoutine    : Ptr32     void
+0x7f4 IpiFrozen        : Uint4B
+0x7f8 PrcbPad3         : [40] UChar
+0x820 RequestSummary   : Uint4B
+0x824 SignalDone       : Ptr32 _KPRCB
+0x828 PrcbPad4         : [56] UChar
+0x860 DpcListHead      : _LIST_ENTRY
+0x868 DpcStack         : Ptr32 Void
+0x86c DpcCount         : Uint4B
+0x870 DpcQueueDepth    : Uint4B
+0x874 DpcRoutineActive : Uint4B
+0x878 DpcInterruptRequested : Uint4B
+0x87c DpcLastCount     : Uint4B
+0x880 DpcRequestRate   : Uint4B
+0x884 MaximumDpcQueueDepth : Uint4B
+0x888 MinimumDpcRate   : Uint4B
+0x88c QuantumEnd       : Uint4B
+0x890 PrcbPad5         : [16] UChar
+0x8a0 Dpc
2080
Lock          : Uint4B
+0x8a4 PrcbPad6         : [28] UChar
+0x8c0 CallDpc          : _KDPC
+0x8e0 ChainedInterruptList : Ptr32 Void
+0x8e4 LookasideIrpFloat : Int4B
+0x8e8 SpareFields0     : [6] Uint4B
+0x900 VendorString     : [13] UChar
+0x90d InitialApicId    : UChar
+0x90e LogicalProcessorsPerPhysicalProcessor : UChar
+0x910 MHz              : Uint4B
+0x914 FeatureBits      : Uint4B
+0x918 UpdateSignature  : _LARGE_INTEGER
+0x920 NpxSaveArea      : _FX_SAVE_AREA
+0xb30 PowerState       : _PROCESSOR_POWER_STATE

CurrentThread

  指向当前线程结构体指针。

NextThread

  指向即将切换的下一个线程结构体指针。

CurrentThread

  指向空闲线程的指针。

本节练习

本节的答案将会在下一节进行讲解,务必把本节练习做完后看下一个讲解内容。不要偷懒,实验是学习本教程的捷径。

  俗话说得好,光说不练假把式,如下是本节相关的练习。如果练习没做好,就不要看下一节教程了,越到后面,不做练习的话容易夹生了,开始还明白,后来就真的一点都不明白了。本节练习较多,请保质保量的完成。

1️⃣ 断链进程结构体,实现隐藏,并思考为什么断链进程为什么还能够执行。
2️⃣ 使用

DebugPort
清零实现反调试。
3️⃣ 如何判断一个进程是否为
GUI
线程。
4️⃣ 断链线程结构体,实现隐藏,并思考为什么断链线程为什么还能够执行。

下一篇

  进程线程篇——线程切换(上)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: