intel白皮书介绍如下: 2.4.1 Global Descriptor Table Register (GDTR)
The GDTR register holds the base address (32 bits in protected mode; 64 bits in IA-32e mode) and the 16-bit table limit for the GDT. The base address specifies the linear address of byte 0 of the GDT; the table limit specifies the number of bytes in the table.
0.1 通过Windbg查找GDT表
r指令为查看寄存器
r gdtr指令为查看GDT.Base
r gdtl指令为查看GDT.Length
dq 有效所在 指令为查看内存数据8字节方式显示(xxxxxxxx(高4字节)`xxxxxxxx(低4字节))
GDT中存储段形貌符(数据段形貌符,代码段形貌符,系统段形貌符) 段形貌符大小为8个字节 intel白皮书介绍如下: 3.4.5 Segment Descriptors
A segment descriptor is a data structure in a GDT or LDT that provides the processor with the size and location of a segment, as well as access control and status information. Segment descriptors are typically created by compilers, linkers, loaders, or the operating system or executive, but not application programs. Figure 3-8 illustrates the general descriptor format for all types of segment descriptors.
2.段选择子与段形貌符关系
intel白皮书介绍如下:
A segment selector is a 16-bit identifier for a segment (see Figure 3-6). It does not point directly to the segment, but instead points to the segment descriptor that defines the segment. A segment selector contains the following items: Index ( 段形貌符在GDT/LDT(windows并未使用LDT)表中的索引值 索引值 * 8 + GDTBase 为要加载的段形貌符 )(Bits 3 through 15) — Selects one of 8192 descriptors in the GDT or LDT. The processor multiplies the index value by 8 (the number of bytes in a segment descriptor) and adds the result to the base address of the GDT or LDT (from the GDTR or LDTR register, respectively). Requested Privilege Level (RPL)( 哀求特权级别 用什么样的权限去哀求加载一个段形貌符 )(Bits 0 and 1) — Specifies the privilege level of the selector. The privilege level can range from 0 to 3, with 0 being the most privileged level. TI (table indicator) flag( 0查GDT表 1查LDT表)(Bit 2) — Specifies the descriptor table to use: clearing this flag selects the GDT; setting this flagselects the current LDT.
P == 1 段形貌符有效 P == 0 段形貌符无效 P (segment-present) flag -Indicates whether the segment is present in memory (set) or not present (clear). If this flag is clear, the processor generates a segment-not-present exception (#NP) when a segment selector that points to the segment descriptor is loaded into a segment register. Memory management software can use this flag to control which segments are actually loaded into physical memory at a given time. It offers a control in addition to paging for managing virtual memory.
//测试P位 #include #include int main(){ //00cff300`0000ffff (从0开始计数高4字节)16进制位第3位>=8为有效段形貌符 2进制位第15位=1为有效段形貌符 WORD Segment = 0; DWORD dwData = 0; //P位 __asm { mov Segment, ss //0023 //0000 0000 0010 0011 //00cff300`0000ffff //P == 1 DPL == 3 S == 1 TYPE == 0011 mov eax, ss:[esp + 8] mov dwData, eax } printf("SS:[0x%04x] DATA:[0x%08x] \n",Segment,dwData); __asm { //构建段形貌符 //00cf7300`0000ffff //P == 0 //windbg input eq 80b99048 00cf7300`0000ffff mov ax, 0x4B mov ss, ax//加载失败段形貌符无效 mov eax, ss:[esp] } system("Pause"); return 0;} 3.2 G位
假设显式Limit为0xFFFFF环境下: G == 0 粒度为(BYTE) (0xFFFFF + 1) * 1 - 1 0x000FFFFF(Limit最终大小) G == 1 粒度为(PAGE) (0xFFFFF + 1) * 4KB - 1 0xFFFFFFFF(Limit最终大小) G (granularity) flag - Determines the scaling of the segment limit field. When the granularity flag is clear, the segment limit is interpreted in byte units; when flag is set, the segment limit is interpreted in 4-KByte units.(This flag does not affect the granularity of the base address; it is always byte granular.) When the granularity flag is set, the twelve least significant bits of an offset are not tested when checking the offset against the segment limit. For example, when the granularity flag is set, a limit of 0 results in valid offsets from 0 to 4095.
//测试G位#include #include int main(){ //00cff300`0000ffff (从0开始计数高4字节)16进制位第5位>=8为G = 1 2进制位第23位= 1 G = 1 WORD Segment = 0; DWORD dwData = 0; //G位 __asm { mov Segment, ds //0023 //0000 0000 0010 0011 //00cff300`0000ffff //G == 1 Limit == 0xFFFFFFFF BASE == 0x00000000 mov eax, ds:[0x400000] mov dwData, eax } printf("SS:[0x%04x] DATA:[0x%08x] \n",Segment,dwData); __asm { //构建段形貌符 //004ff300`0000ffff //G == 0 Limit = 0xFFFFF BASE == 0x00000000 //windbg input eq 80b99048 004ff300`0000ffff mov ax, 0x4B mov ds, ax mov eax, ds:[0x400000]//错误超出段线长 } system("Pause"); return 0;} 3.3 S位
S == 0 系统段形貌符 S == 1 代码段或数据段形貌符 S (descriptor type) flag - Specifies whether the segment descriptor is for a system segment (S flag is clear) or a code or data segment (S flag is set). 通过windbg中断后查看段寄存器值:
Type field -Indicates the segment or gate type and specifies the kinds of access that can be made to the segment and the direction of growth. The interpretation of this field depends on whether the
descriptor type flag specifies an application (code or data) descriptor or a system descriptor. S位 = 1环境下 TYPE域如下图: