您的位置:首页 > 其它

Windows内核进程管理器解析

2016-04-22 18:50 393 查看
Windows内核是如何实现线程挂起的?如何实现线程挂载到进程的?如何实现杀死进程和线程的?

从源码分析一下,这些操作具体在源码上是如何实现的。

进程创建、线程切换、线程跨越CPU权限级、进程挂靠、杀死进程、杀死线程

一.进程创建

可以分几个部分来说。首先说进程的地址空间是怎么创建起来的,进程的EPROCESS->VadRoot是用来描述进程的用户地址空间的。只有在VadRoot结构中分配了的空间才可能被使用。进程初始化空间使用了MmCreateProcessAddressSpace函数,这个函数如下.

二.线程切换

操作系统如何从一个线程切换到另一个线程?

首先,只有内核模式下有线程切换。

三.杀死进程

对应于官方接口分别是用户层的TerminateProcess()和内核层的ZwTerminateProcess()。

杀死进程与创建进程很像,都是一个由多步复合的过程。原因就是因为进程是一个包揽众多的容器。

比如进程有地址空间、有内核对象、也有所拥有的线程。倘若要创建进程势必要创建线程,倘若要杀死进程势必要杀死线程。

所以进程真正的“运行终止”,其实是取决于杀死线程。

四.创建线程

先放上KTHREAD和ETHREAD结构的情况,可见线程对象里面也是有很多东西的

typedef struct _ETHREAD
{
KTHREAD Tcb;
LARGE_INTEGER CreateTime;
union
{
LARGE_INTEGER ExitTime;
LIST_ENTRY KeyedWaitChain;
};
union
{
LONG ExitStatus;
PVOID OfsChain;
};
union
{
LIST_ENTRY PostBlockList;
struct
{
PVOID ForwardLinkShadow;
PVOID StartAddress;
};
};
union
{
PTERMINATION_PORT TerminationPort;
PETHREAD ReaperLink;
PVOID KeyedWaitValue;
PVOID Win32StartParameter;
};
ULONG ActiveTimerListLock;
LIST_ENTRY ActiveTimerListHead;
CLIENT_ID Cid;
union
{
KSEMAPHORE KeyedWaitSemaphore;
KSEMAPHORE AlpcWaitSemaphore;
};
PS_CLIENT_SECURITY_CONTEXT ClientSecurity;
LIST_ENTRY IrpList;
ULONG TopLevelIrp;
PDEVICE_OBJECT DeviceToVerify;
_PSP_RATE_APC * RateControlApc;
PVOID Win32StartAddress;
PVOID SparePtr0;
LIST_ENTRY ThreadListEntry;
EX_RUNDOWN_REF RundownProtect;
EX_PUSH_LOCK ThreadLock;
ULONG ReadClusterSize;
LONG MmLockOrdering;
ULONG CrossThreadFlags;
ULONG Terminated: 1;
ULONG ThreadInserted: 1;
ULONG HideFromDebugger: 1;
ULONG ActiveImpersonationInfo: 1;
ULONG SystemThread: 1;
ULONG HardErrorsAreDisabled: 1;
ULONG BreakOnTermination: 1;
ULONG SkipCreationMsg: 1;
ULONG SkipTerminationMsg: 1;
ULONG CopyTokenOnOpen: 1;
ULONG ThreadIoPriority: 3;
ULONG ThreadPagePriority: 3;
ULONG RundownFail: 1;
ULONG SameThreadPassiveFlags;
ULONG ActiveExWorker: 1;
ULONG ExWorkerCanWaitUser: 1;
ULONG MemoryMaker: 1;
ULONG ClonedThread: 1;
ULONG KeyedEventInUse: 1;
ULONG RateApcState: 2;
ULONG SelfTerminate: 1;
ULONG SameThreadApcFlags;
ULONG Spare: 1;
ULONG StartAddressInvalid: 1;
ULONG EtwPageFaultCalloutActive: 1;
ULONG OwnsProcessWorkingSetExclusive: 1;
ULONG OwnsProcessWorkingSetShared: 1;
ULONG OwnsSystemWorkingSetExclusive: 1;
ULONG OwnsSystemWorkingSetShared: 1;
ULONG OwnsSessionWorkingSetExclusive: 1;
ULONG OwnsSessionWorkingSetShared: 1;
ULONG OwnsProcessAddressSpaceExclusive: 1;
ULONG OwnsProcessAddressSpaceShared: 1;
ULONG SuppressSymbolLoad: 1;
ULONG Prefetching: 1;
ULONG OwnsDynamicMemoryShared: 1;
ULONG OwnsChangeControlAreaExclusive: 1;
ULONG OwnsChangeControlAreaShared: 1;
ULONG PriorityRegionActive: 4;
UCHAR CacheManagerActive;
UCHAR DisablePageFaultClustering;
UCHAR ActiveFaultCount;
ULONG AlpcMessageId;
union
{
PVOID AlpcMessage;
ULONG AlpcReceiveAttributeSet;
};
LIST_ENTRY AlpcWaitListEntry;
ULONG CacheManagerCount;
} ETHREAD, *PETHREAD;


ETHREAD

杀死线程是通过APC来实现的。首先会判断当前线程是否是最后的线程,如果是就直接调用 结束当前线程。如果有别的线程就向它们插入一个APC,用于结束。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: