Windows內核情景分析——Windows進程的用戶空間

    應用軟件在用戶空間可以訪問的最低地址是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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章