快乐虾
http://blog.csdn.net/lights_joy/
本文适用于
Xp sp3
vs2008
欢迎转载,但请保留作者信息
每个线程都有自己的栈空间,这个空间大小是在CreateThread时指定的,而主线程的栈则是由xp在创建进程时指定的,在vs2008下设置一个断点,中断程序的执行,可以看到主线程ESP的值为0x00124914,这个指针落在下面这个区域:
基址 |
分配基址 |
分配保护 |
大小 |
状态 |
保护 |
类型 |
0011e000 |
00030000 |
00000004 |
00012000 |
00001000 |
00000004 |
00020000 |
这块空间的上限是0x0013 0000,这个值与我们读出来的NT_TIB结构体里面的StackBase的值是一致的,也就是说主线程的栈空间从0x0013 0000开始往下增长。但是在NT_TIB里面的StackLimit值却只有0x00000 a000,很显然,可用的栈空间是不只这么一点的。
注意到上述内存区域的分配基址与这个内存区域的起始地址是不一样的,看看完整的内存块:
基址 |
分配基址 |
分配保护 |
大小 |
状态 |
保护 |
类型 |
00030000 |
00030000 |
00000004 |
000ed000 |
00002000 |
00000000 |
00020000 |
0011d000 |
00030000 |
00000004 |
00001000 |
00001000 |
00000104 |
00020000 |
0011e000 |
00030000 |
00000004 |
00012000 |
00001000 |
00000004 |
00020000 |
也就是说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的指引下,我们可以很轻易地从这些内存块中找出其它的栈:
基址 |
分配基址 |
分配保护 |
大小 |
状态 |
保护 |
类型 |
00390000 |
00390000 |
00000004 |
0003c000 |
00002000 |
00000000 |
00020000 |
003cc000 |
00390000 |
00000004 |
00001000 |
00001000 |
00000104 |
00020000 |
003cd000 |
00390000 |
00000004 |
00003000 |
00001000 |
00000004 |
00020000 |
这个栈属于另外一个线程,其大小为0x0003 c000,实际只使用了0x0000 3000。
下面是另一个线程的栈:
基址 |
分配基址 |
分配保护 |
大小 |
状态 |
保护 |
类型 |
00c00000 |
00c00000 |
00000004 |
000f9000 |
00002000 |
00000000 |
00020000 |
00cf9000 |
00c00000 |
00000004 |
00001000 |
00001000 |
00000104 |
00020000 |
00cfa000 |
00c00000 |
00000004 |
00006000 |
00001000 |
00000004 |
00020000 |
总共三个栈空间,和程序里面的三个线程一一对应。
xp下用户程序空间分配(1):大致框架(2009-8-26)