首先说明这分析的是XP系统,WIN7每个单元偏移略有差距
每个windows进程在0环都有一个对应的结构体:EPROCESS 这个结构体包含了进程所有重要的信息。
PEB在3环,EPROCESS在0环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
1) +0x000 Header : _DISPATCHER_HEADER “可等待”对象,比如Mutex互斥体、Event事件等(WaitForSingleObject) 2) +0x018 DirectoryTableBase : [2] Uint4B 页目录表的基址,CR3的值 3) +0x020 LdtDescriptor : _KGDTENTRY +0x028 Int21Descriptor : _KIDTENTRY 历史遗留,16位Windows 段选择子不够 每个进程都有一个LDT表 Int21Descriptor 是 DOS下要用的 4) +0x038 KernelTime : Uint4B +0x03c UserTime : Uint4B 统计信息 记录了一个进程在内核模式/用户模式下所花的时间 5) +0x05c Affinity : Uint4B 规定进程里面的所有线程能在哪个CPU上跑,如果值为1,那这个进程的所以线程只能在0号CPU上跑(00000001) 如果值为3,那这个进程的所以线程能在0、1号CPU上跑(000000011) 如果值为4,那这个进程的所以线程能在2号CPU上跑(000000100) 如果值为5,那这个进程的所以线程能在0,2号CPU上跑(000000101) 4个字节共32位 所以最多32核 Windows64位 就64核 如果只有一个CPU 把这个设置为4 那么这个进程就死了 6) +0x062 BasePriority : Char 基础优先级或最低优先级 该进程中的所有线程最起码的优先级. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
1) +0x070 CreateTime : _LARGE_INTEGER +0x078 ExitTime : _LARGE_INTEGER 进程的创建/退出时间 2) +0x084 UniqueProcessId : Ptr32 Void 进程的编号 任务管理器中的PID 3) +0x088 ActiveProcessLinks : _LIST_ENTRY 双向链表 所有的活动进程都连接在一起,构成了一个链表 PsActiveProcessHead指向全局链表头 4) +0x090 QuotaUsage : [3] Uint4B +0x09c QuotaPeak : [3] Uint4B 物理页相关的统计信息 5) +0x0a8 CommitCharge : Uint4B +0x0ac PeakVirtualSize : Uint4B +0x0b0 VirtualSize : Uint4B 虚拟内存相关的统计信息 6) +0x11c VadRoot : Ptr32 Void 标识0-2G哪些地址没占用了 7) +0x0bc DebugPort : Ptr32 Void +0x0c0 ExceptionPort : Ptr32 Void 调试相关,DebugPort清0,就是一种反调试手段。 8) +0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE 句柄表,这里也可以反调试,遍历其他进程句柄表,如果发现自己就是被调试的 9) +0x174 ImageFileName : [16] UChar 进程镜像文件名 最多16个字节 10) +0x1a0 ActiveThreads : Uint4B 活动线程的数量 11) +0x1b0 Peb : Ptr32 _PEB PEB((Process Environment Block 进程环境块):进程在3环的一个结构体,里面包含了进程的模块列表、是否处于调试状态等信息。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
kd> dd PsActiveProcessHead 83f7bf18 865cd960 8819eb10 00000000 00000000 83f7bf28 83eef48c 00000000 00000000 8b6010a8 这个是活动的进程链,是从_EPROCESS偏移0x88处链起来的所以要查看如下 kd> dt _EPROCESS 865cd960-0x88 ntdll!_EPROCESS +0x000 Pcb : _KPROCESS +0x098 ProcessLock : _EX_PUSH_LOCK +0x0a0 CreateTime : _LARGE_INTEGER 0x83f6fcc0`0000000b +0x0a8 ExitTime : _LARGE_INTEGER 0x007b0000`00000000 +0x0b0 RundownProtect : _EX_RUNDOWN_REF +0x0b4 UniqueProcessId : (null) +0x0b8 ActiveProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ] +0x0c0 ProcessQuotaUsage : [2] 0 +0x0c8 ProcessQuotaPeak : [2] 0x8b601273 +0x0d0 CommitCharge : 0 +0x0d4 QuotaBlock : (null) +0x0d8 CpuQuotaBlock : (null) +0x0dc PeakVirtualSize : 0 +0x0e0 VirtualSize : 0x865f82e0 +0x0e4 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x3 ] +0x0ec DebugPort : 0x00000040 Void +0x0f0 ExceptionPortData : (null) +0x0f0 ExceptionPortValue : 0 +0x0f0 ExceptionPortState : 0y000 +0x0f4 ObjectTable : (null) +0x0f8 Token : _EX_FAST_REF +0x0fc WorkingSetPage : 0 +0x100 AddressCreationLock : _EX_PUSH_LOCK +0x104 RotateInProgress : (null) +0x108 ForkInProgress : (null) +0x10c HardwareTrigger : 0 +0x110 PhysicalVadRoot : (null) +0x114 CloneRoot : (null) +0x118 NumberOfPrivatePages : 0 +0x11c NumberOfLockedPages : 0 +0x120 Win32Process : 0x8b6088d8 Void +0x124 Job : (null) +0x128 SectionObject : 0x7ffe0000 Void +0x12c SectionBaseAddress : (null) +0x130 Cookie : 0 +0x134 Spare8 : 0 +0x138 WorkingSetWatch : (null) +0x13c Win32WindowStation : 0x74737953 Void +0x140 InheritedFromUniqueProcessId : 0x00006d65 Void +0x144 LdtInformation : (null) +0x148 VdmObjects : 0x02000000 Void +0x14c ConsoleHostProcess : 0 +0x150 DeviceMap : (null) +0x154 EtwDataSource : (null) +0x158 FreeTebHint : 0x865cd838 Void +0x160 PageDirectoryPte : _HARDWARE_PTE_X86 +0x160 Filler : 0x83f80fc0`00000000 +0x168 Session : 0x0000005c Void +0x16c ImageFileName : [15] "" +0x17b PriorityClass : 0 '' +0x17c JobLinks : _LIST_ENTRY [ 0x8709d522 - 0x9c ] +0x184 LockedPagesList : (null) +0x188 ThreadListHead : _LIST_ENTRY [ 0x6c - 0x0 ] +0x190 SecurityPort : 0x00000dfd Void +0x194 PaeTop : (null) +0x198 ActiveThreads : 0x18325b0 +0x19c ImagePathHash : 0 +0x1a0 DefaultHardErrorProcessing : 0x38ed48 +0x1a4 LastThreadExitStatus : 0n0 +0x1a8 Peb : 0x00036201 _PEB +0x1ac PrefetchTrace : _EX_FAST_REF +0x1b0 ReadOperationCount : _LARGE_INTEGER 0x0000002f`00000000 +0x1b8 WriteOperationCount : _LARGE_INTEGER 0x8b601070`00000000 +0x1c0 OtherOperationCount : _LARGE_INTEGER 0x0 +0x1c8 ReadTransferCount : _LARGE_INTEGER 0x87ae5f3c`00000000 +0x1d0 WriteTransferCount : _LARGE_INTEGER 0x87b1ff3c +0x1d8 OtherTransferCount : _LARGE_INTEGER 0x0 +0x1e0 CommitChargeLimit : 0 +0x1e4 CommitChargePeak : 0 +0x1e8 AweInfo : (null) +0x1ec SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO +0x1f0 Vm : _MMSUPPORT +0x25c MmProcessLinks : _LIST_ENTRY [ 0x904 - 0x86fa4ce8 ] +0x264 HighestUserAddress : (null) +0x268 ModifiedPageCount : 0 +0x26c Flags2 : 0x9a84f1f4 +0x26c JobNotReallyActive : 0y0 +0x26c AccountingFolded : 0y0 +0x26c NewProcessReported : 0y1 +0x26c ExitProcessReported : 0y0 +0x26c ReportCommitChanges : 0y1 |
上面这个与进程隐藏有关。
每个windows线程在0环都有一个对应的结构体:ETHREAD 这个结构体包含了线程所有重要的信息。
1 2 3 4 5 6 7 8 9 10 |
kd> dt _ETHREAD ntdll!_ETHREAD +0x000 Tcb : _KTHREAD +0x200 CreateTime : _LARGE_INTEGER +0x208 ExitTime : _LARGE_INTEGER +0x208 KeyedWaitChain : _LIST_ENTRY +0x210 ExitStatus : Int4B +0x214 PostBlockList : _LIST_ENTRY +0x214 ForwardLinkShadow : Ptr32 Void +0x218 StartAddress : Ptr32 Void |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
kd> dt _KTHREAD ntdll!_KTHREAD +0x000 Header : _DISPATCHER_HEADER +0x010 CycleTime : Uint8B +0x018 HighCycleTime : Uint4B +0x020 QuantumTarget : Uint8B +0x028 InitialStack : Ptr32 Void +0x02c StackLimit : Ptr32 Void +0x030 KernelStack : Ptr32 Void +0x034 ThreadLock : Uint4B +0x038 WaitRegister : _KWAIT_STATUS_REGISTER +0x039 Running : UChar +0x03a Alerted : [2] UChar +0x03c KernelStackResident : Pos 0, 1 Bit +0x03c ReadyTransition : Pos 1, 1 Bit +0x03c ProcessReadyQueue : Pos 2, 1 Bit +0x03c WaitNext : Pos 3, 1 Bit +0x03c SystemAffinityActive : Pos 4, 1 Bit +0x03c Alertable : Pos 5, 1 Bit |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
1) +0x000 Header : _DISPATCHER_HEADER 以这个开头的结构体,都可说是“可等待”对象,比如Mutex互斥体、Event事件等(WaitForSingleObject) 2) +0x018 InitialStack : Ptr32 Void +0x01c StackLimit : Ptr32 Void +0x028 KernelStack : Ptr32 Void 线程切换相关,,每个线程都有个0环的堆栈和0环的TSS。 3) +0x020 Teb : Ptr32 Void TEB,Thread Environment Block,线程环境块。 大小4KB,位于用户地址空间。 FS:[0] -> TEB(3环时 0环时FS执行KPCR) 4) +0x02c DebugActive : UChar 如果值为-1 不能使用调试寄存器:Dr0 - Dr7 5) +0x034 ApcState : _KAPC_STATE +0x0e8 ApcQueueLock : Uint4B +0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE +0x14c SavedApcState : _KAPC_STATE APC相关 6) +0x02d State : UChar 线程状态:就绪、等待还是运行 7) +0x06c BasePriority : Char 其初始值是所属进程的BasePriority值(KPROCESS->BasePriority),以后可以通过KeSetBasePriorityThread()函数重新设定 8) +0x070 WaitBlock : [4] _KWAIT_BLOCK 等待哪个对象(WaitForSingleObject) 9) +0x0e0 ServiceTable : Ptr32 Void 指向系统服务表基址 10) +0x134 TrapFrame 进0环时保存环境(3换的寄存器之类的) 11) +0x140 PreviousMode : Char 某些内核函数会判断程序是0环调用还是3环调用的 12) +0x1b0 ThreadListEntry : _LIST_ENTRY 双向链表 一个进程所有的线程 都挂在一个链表中 挂的就是这个位置 一共有两个这样的链表 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
1) +0x1ec Cid : _CLIENT_ID 进程ID、线程ID 2) +0x220 ThreadsProcess : Ptr32 _EPROCESS 指向自己所属进程 3) +0x22c ThreadListEntry : _LIST_ENTRY 双向链表 一个进程所有的线程 都挂在一个链表中 挂的就是这个位置 一共有两个这样的链表 |
这个是两个链圈,一个是在KTHREAD里一个是ETHREAD。
1
[1] 潘爱民老师《Windows内核原理与实现》 中的第3章
[2] 滴水视频