引用栈上的变量
通常,在函数入口处会执行以下代码,这样子函数的栈底就是父函数栈顶。在ebp值上面的空间就是子函数需要使用的栈空间,下面是父函数使用的栈空间。所以ebp+正数代表的是传入子函数的参数,ebp+负数代表的是子函数的局部变量。
淡化段机制
操作系统大都使用分页机制作为内存管理的主要手段,这是因为段机制是不可禁止的,同时考虑到软件的兼容性,只能淡化段机制的作用。比如讲段基地址设置为0,边界设置为最大,再如共享段描述符。让不同的进程使用相同的段描述符,这就是调试不同的程序但是其段地址是相同的了。
每个CPU都有自己的全局描述表(GDT)
如下图,后面的数值表示的是段描述符在全局描述表的位置,当段选择子的第三位全部置零后得到对应的段描述符的偏移值。例如在cs的值为0x1b,但是对应的段描述符表的偏移则是0x18,对应的就是全局描述符表的KGDT_R3_CODE.
特殊的FS段
windows中FS寄存器有特殊的用法,当CPU在内核中运行时,FS指向的是PCR,当CPU在用户态运行时,FS指向的是TEB。利用dg命令
可以查看段描述信息。如下可以发现,使用dg 38和!teb查看的FS指向的TEB结构的基地址都是相同的。
我是谁?
PCR处理器控制区是用于存放CPU的编号,IDT和GDT表和重要状态的内存区域,使用!pcr命令
可以查看信息
不可缺少的TSS段
TSS段,用于存放一个任务的执行状态的段,一般的会给每个任务分配一个TSS段,便于进行任务的切换,但是,windows这样的操作系统只是创建少数的TSS段,例如KGDT_TSS,KGDT_DF_TSS和KGDT_NMI_TSS,但是后面两个TSS是处理双误和不可屏蔽中断的任务切换的,也就是说,CPU会根据这两个TSS进行任务切换,关于第一个TSS是所有线程共享的,它的内容是随着任务的切换而改变的,也就是说os在切换线程时候,并不跟换TSS,而是更新TSS的内容。
拓展到64位
和x32相比,x64取消了硬件方式下的任务切换,对TSS结构发生了很大修改。但是硬件还是保留了自动切换栈的功能,新增了一个名为IST的域。