2.进程和线程的结构是什么?

2.进程和线程的结构是什么?

先不要着急它们是如何创建的,要说明白它们是如何被创建的是很复杂的,步骤繁多,而且这也不是我们的核心内容,在KPCRB这个非常复杂的结构里我们找到了KTHREAD的结构,接下来我们就去找找这个结构,在WRK-v1.2\base\ntos\inc\Ke.h里我们找到了这个结构的定义:

typedef struct _KTHREAD {

   DISPATCHER_HEADER Header;//分发器头

LIST_ENTRY MutantListHead;

......

    KSPIN_LOCKThreadLock;//线程自旋锁

   ......

    UCHARWaitReason;//线程等待原因

    SCHARPriority;//优先级

    UCHAREnableStackSwap;

    volatileUCHAR SwapBusy;

    BOOLEANAlerted[MaximumMode];

    union {

       LIST_ENTRY WaitListEntry;

        SINGLE_LIST_ENTRYSwapListEntry;

    };

 

    PRKQUEUEQueue;

 

 

    PVOIDTeb;//线程环境块

    union{     //定时器信息

        KTIMERTimer;

        struct{

           UCHAR TimerFill[KTIMER_ACTUAL_LENGTH];

   

   PKTRAP_FRAME TrapFrame;

    PVOIDCallbackStack;

    PVOIDServiceTable;

    ......

    BOOLEANKernelStackResident;

    SCHARBasePriority;//基础优先级

    SCHARPriorityDecrement;

    CHARSaturation;

    KAFFINITYUserAffinity;

    PKPROCESSProcess;

    KAFFINITYAffinity;

    ......

    LIST_ENTRYThreadListEntry;

PVOID SListFaultAddress;

......

} KTHREAD, *PKTHREAD, *PRKTHREAD;

这又是一个非常变态长的结构,一句话,越长的数据结构越重要,这句话在内核中绝对正确,找啊找啊,发现了一些有趣的事情,这个结构里面有很重要的信息,有很多表,但是我们这时候不能一下子跳进去,在source insight里面找一下调用这个结构的信息发现了一个很重要的结构ETHREAD,找到这个ETHREAD结构,看看有什么发现没有,如果没有的话我就只能回到EPRCB结构中找一些重要的信息了,幸好在WRK-v1.2\base\ntos\inc\Ps.h 里面找到了ETHREAD,其结构如下:

typedefstruct _ETHREAD {

    KTHREAD Tcb;//进程控制块

    LARGE_INTEGER CreateTime;

    union {

        LARGE_INTEGER ExitTime;

        LIST_ENTRY LpcReplyChain;

        LIST_ENTRY KeyedWaitChain;

    };

    union {

        NTSTATUS ExitStatus;

        PVOID OfsChain;

    };

    LIST_ENTRY PostBlockList;

        struct_ETHREAD *ReaperLink;

    KSPIN_LOCK ActiveTimerListLock;

    LIST_ENTRY ActiveTimerListHead;

    CLIENT_ID Cid;//本进程的CID

    ......

    union {

        PVOID LpcReplyMessage;         

        PVOID LpcWaitingOnPort;

    };

    ......

     LIST_ENTRY IrpList;

        ......

    PEPROCESS ThreadsProcess;

    PVOID StartAddress;

    ......

    LIST_ENTRY ThreadListEntry;//挂入EPROCESS中的线程队列

    ......

    BOOLEAN ForwardClusterOnly;

    BOOLEAN DisablePageFaultClustering;

    UCHAR ActiveFaultCount;

 

 ......

 

}ETHREAD, *PETHREAD;

 

又是一个非常变态长的结构,上来就给我一个超大的惊喜,Tcb!!!上课老师重点讲的这玩意,终于在代码中看到了,冷静一下,这时候不是马上去看Tcb的结构代码,我们没有解决我们的核心问题,THREAD翻译成线程,那进程呢?进程的结构是什么?而且KTHREAD和ETHREAD到底哪个是线程的结构,这两个结构之间到底是什么关系?有了ETHREAD和KTHREAD,那么我们可以猜想一下是不会会存在E进程和K进程?一般来说进程的英文单词是PROCESS,所以我们尝试查一下EPROCESS和KPROCES,果然不负重托,和ETHREAD结构在同一个文件里就有:

typedef struct _EPROCESS {

    KPROCESSPcb;

   EX_PUSH_LOCK ProcessLock;

    LARGE_INTEGERCreateTime;//进程创建时间

   LARGE_INTEGER ExitTime;//退出时间

 

    ......

    HANDLEUniqueProcessId;

    LIST_ENTRYActiveProcessLinks;//活动的进程链接

    ......

    struct_ETHREAD *ForkInProgress;

    ULONG_PTRHardwareTrigger;

 

   PMM_AVL_TABLE PhysicalVadRoot;

    PVOIDCloneRoot;

    PFN_NUMBERNumberOfPrivatePages;

    PFN_NUMBERNumberOfLockedPages;

    PVOIDWin32Process;//指向本进程的Win32Process结构

    struct_EJOB *Job;

    PVOIDSectionObject;//指向可执行程序映像的文件映射区对象

 

    PVOIDSectionBaseAddress;

 

    PEPROCESS_QUOTA_BLOCKQuotaBlock;

 

   PPAGEFAULT_HISTORY WorkingSetWatch;

    HANDLEWin32WindowStation;

    HANDLEInheritedFromUniqueProcessId;

 

    PVOIDLdtInformation;

    PVOIDVadFreeHint;

    PVOIDVdmObjects;

    PVOIDDeviceMap;

    ......

    PVOID Session;

    UCHARImageFileName[ 16 ];所执行程序映像的文件名

 

    LIST_ENTRYJobLinks;

    PVOIDLockedPagesList;

 

LIST_ENTRY ThreadListHead;//本进程的线程队列

......

 

    ULONGActiveThreads;

 

   ACCESS_MASK GrantedAccess;//允许访问方式

 

    ULONGDefaultHardErrorProcessing;

 

    NTSTATUSLastThreadExitStatus;

    ......

    PPEBPeb;//指向用户空间的“进程环境块”

 

    ......

    UCHARPriorityClass;//本进程的优先级类别

 

   MM_AVL_TABLE VadRoot;//指向本进程用户空间的数据结构

 

    ULONGCookie;

 

} EPROCESS, *PEPROCESS;

这个结构也是老长老长的,关键是他们还非常重要,哎,这个结构里面的信息就不得了,基本上课堂上老师和我们讲的进程的很多信息这里么就包括了,君不见第一个就是传说中的PCB,有EPROCESS,那就有KPROCESS了,不过这次是在WRK-v1.2\base\ntos\inc\Ke.h里面找到这个结构:

typedef struct _KPROCESS {

   DISPATCHER_HEADER Header;//分发器头

    LIST_ENTRYProfileListHead;

ULONG_PTR DirectoryTableBase[2];//本进程页面映射表的物理地址

......

    LIST_ENTRYReadyListHead;//本进程的就绪线程队列

   SINGLE_LIST_ENTRY SwapListEntry;

    ......

    LIST_ENTRYThreadListHead;//本进程的线程队列

KSPIN_LOCK ProcessLock;//进程自旋锁

......

    SCHARBasePriority;//本进程的基本优先级

SCHAR QuantumReset;

......

    ULONG_PTRStackCount;

    LIST_ENTRYProcessListEntry;//挂入内核的进程队列

} KPROCESS, *PKPROCESS, *PRKPROCESS;

这个结构也是不得了,后面的很多信息都是跟这里么打交道的,我加了注释的都是很重要的,很多内容的中文翻译那是如雷贯耳啊,看着英文你就可以翻译出来很多了,这一点微软做的真的很好,命名是很有水平的,也可以直接把这个结构叫做进程控制块结构了。总结一下我们的问题:EPROCESS中的E是Executive(管理层之意),KPROCESS中的K是kernel的意思,不过这里不是我们概念中的内核,这是因为微软把Kernel当成内核的一部分,而LINUX里面Kernel就是内核。线程同样的道理,而在进程的结构中就有线程队列,到此我们已经明白了进程和线程的结构已经它们之间是什么关系了。

注意:在我的这种探索方式下,我们漏过了一些很重要的东西,比如TEB和PEB,而WRK-v1.2\public\sdk\inc\Pebteb.h:

typedef struct PEBTEB_STRUCT(_PEB) {

    BOOLEANInheritedAddressSpace;      // These four fields cannot change unless the

    BOOLEANReadImageFileExecOptions;   //

    BOOLEAN BeingDebugged;              //

    union {

        BOOLEAN BitField;                  //

        struct {

            BOOLEANImageUsesLargePages : 1;

            BOOLEAN SpareBits : 7;

         };

    };

    PEBTEB_POINTER(HANDLE)Mutant;      // INITIAL_PEB structure isalso updated.

 

    PEBTEB_POINTER(PVOID)ImageBaseAddress;

    PEBTEB_POINTER(PPEB_LDR_DATA)Ldr;

    PEBTEB_POINTER(struct_RTL_USER_PROCESS_PARAMETERS*) ProcessParameters;

    PEBTEB_POINTER(PVOID)SubSystemData;

    PEBTEB_POINTER(PVOID)ProcessHeap;

    PEBTEB_POINTER(struct_RTL_CRITICAL_SECTION*) FastPebLock;

    PEBTEB_POINTER(PVOID)AtlThunkSListPtr;     // Used only forAMD64

    PEBTEB_POINTER(PVOID)SparePtr2;

    ULONG EnvironmentUpdateCount;

    PEBTEB_POINTER(PVOID)KernelCallbackTable;

    ULONG SystemReserved[1];

    ULONG SpareUlong;

    PEBTEB_POINTER(PPEB_FREE_BLOCK)FreeList;

    ULONG TlsExpansionCounter;

    PEBTEB_POINTER(PVOID)TlsBitmap;

    ULONG TlsBitmapBits[2];         // TLS_MINIMUM_AVAILABLE bits

   ......

    PEBTEB_POINTER(struct_ASSEMBLY_STORAGE_MAP *) SystemAssemblyStorageMap;

    PEBTEB_POINTER(SIZE_T)MinimumStackCommit;

    PEBTEB_POINTER(PPVOID) FlsCallback;

    PEBTEB_STRUCT(LIST_ENTRY)FlsListHead;

    PEBTEB_POINTER(PVOID)FlsBitmap;

    ULONGFlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];

    ULONG FlsHighIndex;

} PEBTEB_STRUCT(PEB), * PEBTEB_STRUCT(PPEB);

简单来说PEB和TEB描述了进程和线程的运行环境,包括映像基地址,加载器数据库,线程局部存储区数据,代码页数据,进程标志,进程堆,映像进程亲和性掩码,FLS/TLS数据等信息,开头我们就说过FS段寄存器在用户空间的时候指向的是TEB也就是当前线程环境块,在这里系统就知道当前线程的信息了,


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值