-
-
[原创]内核内存的创建过程残缺版(一)
-
发表于:
2015-3-25 12:13
6827
-
为啥叫残缺版啊,因为这玩意,我实在写不下去了,写这个帖子及其费力,网上基本找不到可参考的文章,只能硬着头皮写个,这还只是个半成品,其他的,用到了再研究吧,内存创建分为两个过程,百分之九十都集中了阶段0,这里我们也只研究阶段0
第一步:调整bb000000-c0000000的地址空间
1:得到系统视图的开始地址和会话空间的结束地址分别为bb000000,c0000000
2:得到会话空间的开始地址为bc000000
nt!MmInitSystem+0x1ee:
80696a12 890dec935580 mov dword ptr [nt!MiSessionPoolStart (805593ec)],ecx
调试的时候,有点乱,这里就不加入图片了:
kd> dd MiSessionPoolStart
805593ec bc000000 01000000 bb000000 00000000
805593fc 00000000 04000000 00000000 00000000
ps:会话空间分为会话内存池,会话视图和会话映像,会话内存池开始地址也就是会话空间开始地址
第二步:得到系统缓存的开始地址到结束地址为C1000000-E1000000
第三步: 得到页面数量和系统PTE数量
系统PTE数量-判断1:
INIT:005E6D6D PanDuan1:
INIT:005E6D6D cmp [ebp+var_24], 1300h
INIT:005E6D74 jnb short PanDuan2
INIT:005E6D76 mov eax, 1B58h
INIT:005E6D7B jmp 第四步
系统PTE数量-判定2:
INIT:005E6D80 PanDuan2:
INIT:005E6D80 cmp [ebp+var_24], edx
INIT:005E6D83 mov eax, 2AF8h
INIT:005E6D88 jbe 第四步
系统PTE数量-判断3:
INIT:005E6D8E cmp ds:_ExpMultiUserTS, esi
INIT:005E6D94 mov eax, 55F0h
INIT:005E6D99 jz short loc_5E6DA8
INIT:005E6D9B jmp systempte
第四步:初始化堆变量:
MmHeapSegmentReserve,MmHeapSegmentCommit,MmHeapDeCommitTotalFreeThreshold,MmHeapDeCommitFreeBlockThreshold
kd> dd 8054b1d8
8054b1d8 00100000 00002000 00010000 00001000
PS:重要的一步来了,第三步中,并没有设置系统PTE,这里才设置了系统PTE
第五步:当前进程的低2G页目录清零(也就是用户层的页目录)
INIT:005D33E6 push ds:_ZeroKernelPte ; Pattern
INIT:005D33EC mov [ebp+BugCheckParameter1], eax
INIT:005D33EF push 800h ; Length
INIT:005D33F4 push 0C0300000h ; Destination
INIT:005D33F9 call _RtlFillMemoryUlong@12 ; RtlFillMemoryUlong(x,x,x)
第六步:根据loader_parameter_block->MemoryDescriptorListHead得到物理页面和最高可能的物理页面:
暂且把这里当作对页面的筛选吧,物理页面会决定非分页内存池分配的大小,最高可能的物理页面决定非分页内存池可以分配的可能最大值,接下来我们分配非分页内存池的值,就取决于最高可能的物理页面,好了,先看看物理页面和物理页面最大值的分配
然后是物理页面最大值的分配:
第七步:根据刚刚分配的物理页面和物理页面最大值,来分配非分页内存池和非分页内存池最大值
非分页内存池:
上面的算法,可以概括为:
1:非分页内存池初始化为0,然后为它赋值最小值 MmMinimumNonPagedPoolSize : 40000
2:非分页内存池+( [(MmNumberOfPhysicalPages-400)/100] * 8000)=40000+( [(1fb7c-400)/100]*8000 )=40000+FD8000=1018000
非分页内存池可能的最大值:
因为它会先得出非换页内存池最大值,然后会再进行调整,我的电脑上得出的结果是6786000
大致的计算如下:
1:非分页内存池最大值初始化为0,然后为它赋值默认最大值MmDefaultMaximumNonPagedPool:00100000
2: 非分页内存池最大值=(MmHighestPhysicalPage+1)*1C+100000(;MMPFN)=480000
3: if(MmHighestPhysicalPage>1F000)
{
非分页内存池最大值=480000+( [(MmNumberOfPhysicalPages-400)/100]*64000 )/2 = 6786000
}
else
{
非分页内存池最大值=480000+( [(MmNumberOfPhysicalPages-400)/100]*64000 ) = ?
}
4. 如果最大值小于8000000,则赋值非换页内存池最大值为8000000,这里并没有超过,所以赋值为8000000
第八步:设置PFN数据库
第九步:终于熬到这里了,开始调整非换页内存池了,系统为了保险起见,用的是非换页内存池的可能最大值
第十步:设置系统PTE开始地址和结束地址
这个地址不能低于EB000000,如果低于这个地址,就设置系统PTE开始地址为EB000000
第十一步:设置换页内存池开始地址和结束地址
如果换页内存池的结束位置,越过了系统PTE的开始位置,则还需要调整换页内存池
至此,从bb000000-ffbe0000的地址空间就被建设好了
bb000000-bc000000为系统视图空间
bc000000-c0000000为会话空间
c0000000-c0300000为PTE空间
c0300000-c0400000为PDE空间
c0400000-c0e00000为进程工作集和超空间空间
c1000000-e1000000为缓存空间
e1000000-eb000000为换页内存池空间
eb000000-f7be0000为系统PTE空间
f7be0000-ffbe0000 为非换页内存池空间
大爷的,不写了,累死哥了,女朋友也不理我了,如果有错误的地方,希望 大神们指出来,毕竟,都是为了进步嘛
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课