xp下用户措施空间分派(2):栈
副标题#e#
每个线程都有本身的栈空间,这个空间巨细是在CreateThread时指定的,而主线程的栈则是由xp在创 建历程时指定的,在vs2008下配置一个断点,间断措施的执行,可以看到主线程ESP的值为0x00124914, 这个指针落在下面这个区域:
这块空间的上限是0x0013 0000,这个值与我们读出来的NT_TIB布局体内里的StackBase的值是一致的 ,也就是说主线程的栈空间从0x0013 0000开始往下增长。可是在NT_TIB内里的StackLimit值却只有 0x00000 a000,很显然,可用的栈空间是不但这么一点的。
留意到上述内存区域的分派基址与这个内 存区域的起始地点是纷歧样的,看看完整的内存块:
也就是说windows分派这块空间的时候是从0x0003 0000 ~ 0x0013 0000的,刚好1M,这也是默认环境 下主线程的栈空间巨细。但由于我们实际还没有利用这么大的栈空间,所以0x0003 0000开始的这一块空 间的状态是MEM_RESERVE。
再看中间的这个内存区域,它的掩护符号多了个PAGE_GUARD,MSDN内里这 样表明这个符号位:
Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm. For more information, see Creating Guard Pages.
When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.
从这里大抵可以知道,当ESP向下增长高出 今朝已经分派的空间,此时将触发一个异常,然后windows再调解这几块内存页的属性。虽然,ESP的增 长不能高出整个栈的巨细,不然措施就无法继承了。
在PAGE_GUARD的指引下,我们可以很等闲地从这 些内存块中找出其它的栈:
#p#副标题#e#
这个栈属于别的一个线程,其巨细为0x0003 c000,实际只利用了0x0000 3000。
下面是另一个线程的栈:
总共三个栈空间,和措施内里的三个线程一一对应。