段寄存器

CS 代码段寄存器 描述的代码

SS 栈段 描述栈 比如:局部变量

DS 数据段 堆地址 全局变量

ES 扩展段 串 copy movsb so edi esi

FS 上下文环境 R3代码TEB , R0代表KPPCR

段和段之间不能之间进行操作

1
2
3
// mov ds,cs; -->错误的
mov ax,cs;
mov ds,ax;

ds 和es 的值不论在什么情况下都是相等的。

段选择符:

image-20241114211527485

RPL:请求访问权限

TI: 是表 取0和1查的不一样。 0->GDT 1->LDT

3-15字节是决定表上的某个描述符,索引号

选中16字节 -> 段描述符

数索引号太慢了:用段寄存器的值&F8 加上GDT表的base 就OK

段描述符

image-20241114214834398

windbg :

r是看寄存器 r eax

r gdtr 可以看这张表的指向

image-20241114211700991

d :查看内存 后面跟上单位:<byte word dword dqword> 在跟上地址 <通用限制符L> 【Limit】

L1就是一个 L2 就是两个

比如:dq 80b99000 L1 dq 80b99000 L2

在单位后面跟上s就是竖着排列

dds 80b99000

image-20241114212224950

e 和d的用法类似,但是是写。

例子:

CS = 1B

1B:0000 0000 0001 1011

F8:0000 0000 1111 1000

权限不管,选中gdr表的第三个索引 【索引是从0开始的】

image-20241114214544977

00cffb00`0000ffff

或者之间 1B&F8 = 18 + base[80b99000] 即可

0000 0000 1100 1111 1111 1011 0000 0000

0000 0000 0000 0000 1111 1111 1111 1111

1
2
3
4
5
6
7
8
9
10
limit:	F FFFF			//F FFFF + 1个页
base: 0000 0000
Type: B //查表,每个值又不同的权限【类型】
S: 1 //S=1的时候表示数据段或者代码段,=0的时候是系统描述符
DPL: 3
P: 1 //段描述符是否有效【1有效】
AVL: 0
def: 0
D/B: 1
G: 1 //粒度

G=1 则limit就是页为单位 =0 则是字节为单位

一个页是4096 字节 也就是0x1000字节

粒度:

(F FFFF +1)* 0x1000 = 0x100000000 = 0 ~ 0xFFFF FFFF ==> 4G

32位的内存: 0- 0xFFFF FFFF

FS = 3B

0040f300`00000fff

1
ds:[0x0];

32位下有16位下的寻址方式

base*0x10 + offset

ds:[0x0]; [0x0] 是offset base 是ds 的值通过GDT这个表寻找出来的base 一般是0

Type:的值0-15 对应的内容

B->11 code段 执行和读取

image-20241114223642300

作业就是拆这些段描述符【按照上面的格式】

1
2
3
4
5
6
7
8
80b99000  00000000`00000000 00cf9b00`0000ffff
80b99010 00cf9300`0000ffff 00cffb00`0000ffff
80b99020 00cff300`0000ffff 80008b1e`400020ab
80b99030 834093f6`5c003748 0040f300`00000fff
80b99040 0000f200`0400ffff 00000000`00000000
80b99050 830089f6`30000068 830089f6`30680068
80b99060 00000000`00000000 00000000`00000000
80b99070 800092b9`900003ff 00000000`00000000