Windows内核情景分析——Windows进程的用户空间

本文介绍Windows操作系统中进程用户空间的创建过程,包括用户空间的起始地址、共享数据区域的作用及位置、目标EXE映像如何映射到用户空间、动态链接库的加载方式以及进程环境块PEB的建立等关键内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    应用软件在用户空间可以访问的最低地址是MM_LOWEST_USER_ADDRESS,定义为0x10000,就是一个64KB边界的地方,从0开始的64KB不能访问

    KI_USER_SHARED_DATA这个常数定义为0xFFDF0000,是一个区间的起点。这个区间是在系统空间,却又划出来让用户空间的程序访问,目的是用来让用户空间的程序访问内核中的一些数据。而且,这个区间是由系统空间和所有用户空间共享即为所有进程所共享的。

nt!_KUSER_SHARED_DATA
   +0x000 TickCountLow     : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Uint2B
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 Reserved2        : [8] Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 NXSupportPolicy  : UChar
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2f0 TraceLogging     : Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 SystemCall       : Uint4B
   +0x304 SystemCallReturn : Uint4B
   +0x308 SystemCallPad    : [3] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x330 Cookie           : Uint4B

    地址0xFFDF0000就是KUSER_SHARED_DATA数据结构的起点,而用户空间的程序则可以通过指针SharedUserData读取这个结构中各个成分的内容。

    进程用户空间的创建:

    1.进程控制块EPROCESS结构中有个成分VadRoot,就是代表用户空间的MADRESS_SPACE数据结构。所以在创建进程时要通过MmInitializeAddressSpace()对新建进程的地址空间VadRoot进行初始化,特别是将此数据结构中的成分LowestAddress设置成MM_LOWEST_USER_ADDRESS

    2.建立用户共享区,把从USER_SHARED_DATA即0xFFDF0000开始的一个页面分配给用户空间,让用户空间的程序可以对该页面作“可执行和只读”访问。实际大小是一个页面4KB。

    3.目标EXE映像的映射,在调用NtCreateProcess之前,调用者已经为目标映像创建了一个Section即“文件映射区”,通过MmMapViewOfSection把这个映射区映射到新建进程的用户空间。

    4.把许多动态链接库也装入或映射到用户空间。ntdll.dll是最基本的DLL,Windows内核在初始化阶段首次需要装入这个DLL的时候为其创建一个文件映射区,并使一个全局指针PspSystemDllSection指向该对象的数据结构,以后凡需要装入这个DLL的进程就只有映射这个文件映射区就可以了。

    5.进程环境块PEB的建立,有PspCreateProcess调用MmCreatePeb完成的。MiCreatePeborTeb在分配地址空间时是由上而下的,所以是从0x7FFE0000开始往下搜索,以找到第一块满足大小要求的区间。由于此时的用户空间尚是空白,所要求的地址肯定能够满足,而PEB和TEB的大小都是一个页面,即0x1000(4KB),所以PEB分得的地址肯定是0x7FFDF000。

   6.通过MmMapViewOfSection将NLS的码表映射到用户空间。

   7.初始化PEB,PEB占用一个页面,但是实际使用的大小却没有那么大,所以把剩下的部分用做一个存储堆(Heap)指针数组。剩余的部分能容纳多少个指针,这个进程最多就可以有多少个堆。

   8.把进程参数写入新进程的参数块。

   9.创建新进程的第一个线程及TEB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值