Windows内核是如何实现线程挂起的?如何实现线程挂载到进程的?如何实现杀死进程和线程的?
从源码分析一下,这些操作具体在源码上是如何实现的。
进程创建、线程切换、线程跨越CPU权限级、进程挂靠、杀死进程、杀死线程
一.进程创建
可以分几个部分来说。首先说进程的地址空间是怎么创建起来的,进程的EPROCESS->VadRoot是用来描述进程的用户地址空间的。只有在VadRoot结构中分配了的空间才可能被使用。进程初始化空间使用了MmCreateProcessAddressSpace函数,这个函数如下.
二.线程切换
操作系统如何从一个线程切换到另一个线程?
首先,只有内核模式下有线程切换。
三.杀死进程
对应于官方接口分别是用户层的TerminateProcess()和内核层的ZwTerminateProcess()。
杀死进程与创建进程很像,都是一个由多步复合的过程。原因就是因为进程是一个包揽众多的容器。
比如进程有地址空间、有内核对象、也有所拥有的线程。倘若要创建进程势必要创建线程,倘若要杀死进程势必要杀死线程。
所以进程真正的“运行终止”,其实是取决于杀死线程。
四.创建线程
先放上KTHREAD和ETHREAD结构的情况,可见线程对象里面也是有很多东西的
1 typedef struct _KTHREAD 2 { 3 DISPATCHER_HEADER Header; 4 UINT64 CycleTime; 5 ULONG HighCycleTime; 6 UINT64 QuantumTarget; 7 PVOID InitialStack; 8 PVOID StackLimit; 9 PVOID KernelStack; 10 ULONG ThreadLock; 11 union 12 { 13 KAPC_STATE ApcState; 14 UCHAR ApcStateFill[23]; 15 }; 16 CHAR Priority; 17 WORD NextProcessor; 18 WORD DeferredProcessor; 19 ULONG ApcQueueLock; 20 ULONG ContextSwitches; 21 UCHAR State; 22 UCHAR NpxState; 23 UCHAR WaitIrql; 24 CHAR WaitMode; 25 LONG WaitStatus; 26 union 27 { 28 PKWAIT_BLOCK WaitBlockList; 29 PKGATE GateObject; 30 }; 31 union 32 { 33 ULONG KernelStackResident: 1; 34 ULONG ReadyTransition: 1; 35 ULONG ProcessReadyQueue: 1; 36 ULONG WaitNext: 1; 37 ULONG SystemAffinityActive: 1; 38 ULONG Alertable: 1; 39 ULONG GdiFlushActive: 1; 40 ULONG Reserved: 25; 41 LONG MiscFlags; 42 }; 43 UCHAR WaitReason; 44 UCHAR SwapBusy; 45 UCHAR Alerted[2]; 46 union 47 { 48 LIST_ENTRY WaitListEntry; 49 SINGLE_LIST_ENTRY SwapListEntry; 50 }; 51 PKQUEUE Queue; 52 ULONG WaitTime; 53 union 54 { 55 struct 56 { 57 SHORT KernelApcDisable; 58 SHORT SpecialApcDisable; 59 }; 60 ULONG CombinedApcDisable; 61 }; 62 PVOID Teb; 63 union 64 { 65 KTIMER Timer; 66 UCHAR TimerFill[40]; 67 }; 68 union 69 { 70 ULONG AutoAlignment: 1; 71 ULONG DisableBoost: 1; 72 ULONG EtwStackTraceApc1Inserted: 1; 73 ULONG EtwStackTraceApc2Inserted: 1; 74 ULONG CycleChargePending: 1; 75 ULONG CalloutActive: 1; 76 ULONG ApcQueueable: 1; 77 ULONG EnableStackSwap: 1; 78 ULONG GuiThread: 1; 79 ULONG ReservedFlags: 23; 80 LONG ThreadFlags; 81 }; 82 union 83 { 84 KWAIT_BLOCK WaitBlock[4]; 85 struct 86 { 87 UCHAR WaitBlockFill0[23]; 88 UCHAR IdealProcessor; 89 }; 90 struct 91 { 92 UCHAR WaitBlockFill1[47]; 93 CHAR PreviousMode; 94 }; 95 struct 96 { 97 UCHAR WaitBlockFill2[71]; 98 UCHAR ResourceIndex; 99 }; 100 UCHAR WaitBlockFill3[95]; 101 }; 102 UCHAR LargeStack; 103 LIST_ENTRY QueueListEntry; 104 PKTRAP_FRAME TrapFrame; 105 PVOID FirstArgument; 106 union 107 { 108 PVOID CallbackStack; 109 ULONG CallbackDepth; 110 }; 111 PVOID ServiceTable; 112 UCHAR ApcStateIndex; 113 CHAR BasePriority; 114 CHAR PriorityDecrement; 115 UCHAR Preempted; 116 UCHAR AdjustReason; 117 CHAR AdjustIncrement; 118 UCHAR Spare01; 119 CHAR Saturation; 120 ULONG SystemCallNumber; 121 ULONG Spare02; 122 ULONG UserAffinity; 123 PKPROCESS Process; 124 ULONG Affinity; 125 PKAPC_STATE ApcStatePointer[2]; 126 union 127 { 128 KAPC_STATE SavedApcState; 129 UCHAR SavedApcStateFill[23]; 130 }; 131 CHAR FreezeCount; 132 CHAR SuspendCount; 133 UCHAR UserIdealProcessor; 134 UCHAR Spare03; 135 UCHAR Iopl; 136 PVOID Win32Thread; 137 PVOID StackBase; 138 union 139 { 140 KAPC SuspendApc; 141 struct 142 { 143 UCHAR SuspendApcFill0[1]; 144 CHAR Spare04; 145 }; 146 struct 147 { 148 UCHAR SuspendApcFill1[3]; 149 UCHAR QuantumReset; 150 }; 151 struct 152 { 153 UCHAR SuspendApcFill2[4]; 154 ULONG KernelTime; 155 }; 156 struct 157 { 158 UCHAR SuspendApcFill3[36]; 159 PKPRCB WaitPrcb; 160 }; 161 struct 162 { 163 UCHAR SuspendApcFill4[40]; 164 PVOID LegoData; 165 }; 166 UCHAR SuspendApcFill5[47]; 167 }; 168 UCHAR PowerState; 169 ULONG UserTime; 170 union 171 { 172 KSEMAPHORE SuspendSemaphore; 173 UCHAR SuspendSemaphorefill[20]; 174 }; 175 ULONG SListFaultCount; 176 LIST_ENTRY ThreadListEntry; 177 LIST_ENTRY MutantListHead; 178 PVOID SListFaultAddress; 179 PVOID MdlForLockedTeb; 180 } KTHREAD, *PKTHREAD;
1 typedef struct _ETHREAD 2 { 3 KTHREAD Tcb; 4 LARGE_INTEGER CreateTime; 5 union 6 { 7 LARGE_INTEGER ExitTime; 8 LIST_ENTRY KeyedWaitChain; 9 }; 10 union 11 { 12 LONG ExitStatus; 13 PVOID OfsChain; 14 }; 15 union 16 { 17 LIST_ENTRY PostBlockList; 18 struct 19 { 20 PVOID ForwardLinkShadow; 21 PVOID StartAddress; 22 }; 23 }; 24 union 25 { 26 PTERMINATION_PORT TerminationPort; 27 PETHREAD ReaperLink; 28 PVOID KeyedWaitValue; 29 PVOID Win32StartParameter; 30 }; 31 ULONG ActiveTimerListLock; 32 LIST_ENTRY ActiveTimerListHead; 33 CLIENT_ID Cid; 34 union 35 { 36 KSEMAPHORE KeyedWaitSemaphore; 37 KSEMAPHORE AlpcWaitSemaphore; 38 }; 39 PS_CLIENT_SECURITY_CONTEXT ClientSecurity; 40 LIST_ENTRY IrpList; 41 ULONG TopLevelIrp; 42 PDEVICE_OBJECT DeviceToVerify; 43 _PSP_RATE_APC * RateControlApc; 44 PVOID Win32StartAddress; 45 PVOID SparePtr0; 46 LIST_ENTRY ThreadListEntry; 47 EX_RUNDOWN_REF RundownProtect; 48 EX_PUSH_LOCK ThreadLock; 49 ULONG ReadClusterSize; 50 LONG MmLockOrdering; 51 ULONG CrossThreadFlags; 52 ULONG Terminated: 1; 53 ULONG ThreadInserted: 1; 54 ULONG HideFromDebugger: 1; 55 ULONG ActiveImpersonationInfo: 1; 56 ULONG SystemThread: 1; 57 ULONG HardErrorsAreDisabled: 1; 58 ULONG BreakOnTermination: 1; 59 ULONG SkipCreationMsg: 1; 60 ULONG SkipTerminationMsg: 1; 61 ULONG CopyTokenOnOpen: 1; 62 ULONG ThreadIoPriority: 3; 63 ULONG ThreadPagePriority: 3; 64 ULONG RundownFail: 1; 65 ULONG SameThreadPassiveFlags; 66 ULONG ActiveExWorker: 1; 67 ULONG ExWorkerCanWaitUser: 1; 68 ULONG MemoryMaker: 1; 69 ULONG ClonedThread: 1; 70 ULONG KeyedEventInUse: 1; 71 ULONG RateApcState: 2; 72 ULONG SelfTerminate: 1; 73 ULONG SameThreadApcFlags; 74 ULONG Spare: 1; 75 ULONG StartAddressInvalid: 1; 76 ULONG EtwPageFaultCalloutActive: 1; 77 ULONG OwnsProcessWorkingSetExclusive: 1; 78 ULONG OwnsProcessWorkingSetShared: 1; 79 ULONG OwnsSystemWorkingSetExclusive: 1; 80 ULONG OwnsSystemWorkingSetShared: 1; 81 ULONG OwnsSessionWorkingSetExclusive: 1; 82 ULONG OwnsSessionWorkingSetShared: 1; 83 ULONG OwnsProcessAddressSpaceExclusive: 1; 84 ULONG OwnsProcessAddressSpaceShared: 1; 85 ULONG SuppressSymbolLoad: 1; 86 ULONG Prefetching: 1; 87 ULONG OwnsDynamicMemoryShared: 1; 88 ULONG OwnsChangeControlAreaExclusive: 1; 89 ULONG OwnsChangeControlAreaShared: 1; 90 ULONG PriorityRegionActive: 4; 91 UCHAR CacheManagerActive; 92 UCHAR DisablePageFaultClustering; 93 UCHAR ActiveFaultCount; 94 ULONG AlpcMessageId; 95 union 96 { 97 PVOID AlpcMessage; 98 ULONG AlpcReceiveAttributeSet; 99 }; 100 LIST_ENTRY AlpcWaitListEntry; 101 ULONG CacheManagerCount; 102 } ETHREAD, *PETHREAD;
杀死线程是通过APC来实现的。首先会判断当前线程是否是最后的线程,如果是就直接调用 结束当前线程。如果有别的线程就向它们插入一个APC,用于结束。