Protected Mode - Segment Registers

Table of contents

think

Logical address, linear address, physical address

what is a segment

What are segment registers

Segment register structure

Detection of invisible parts

Segment base detection

segment limit detection

Detection of access rights


think


What does ds:[0x12345678] in the following assembly instructions mean?

mov eax, dword ptr ds:[0x12345678]

Logical address, linear address, physical address


In the x86 architecture, there is a certain relationship between logical addresses, linear addresses, and physical addresses. The conversion relationship of these addresses is as follows:

  • Logical Address: The logical address is the address generated by the program, including the segment selector (Seg.Selector) and the offset (Offset). The segment selector (Seg.Selector) is used to specify the index and offset of the segment descriptor (Seg.Descriptor) in the global descriptor table (GDT-Global Descriptor Table) or local descriptor table (LDT-Local Descriptor Table) (Offset) is used to specify the offset address within the segment. Since the logical address is relative to the segment, it is necessary to add the segment base address and the offset to obtain the linear address. As stated in the Intel white paper:

  • Linear Address: Linear address is a concept introduced in the x86 architecture, which refers to the address obtained after the logical address is converted by the segmentation mechanism. A linear address can be seen as an intermediate result of logical address to physical address translation, which is relative to the entire virtual address space.
  • Physical Address: The physical address refers to the actual address in the memory, which is the address sent by the CPU to the memory controller to access the memory through the address bus. The linear address is converted through the page directory table, page table, and page offset to obtain a physical address, which points to the actual physical storage unit. It should be noted that in the x86-64 architecture, since the flat model and 64-bit address space are adopted, physical addresses and linear addresses are in one-to-one correspondence, so paging conversion is not required.

The ds in ds:[0x12345678] is a segment register , which stores a segment selector. is an offset that specifies an offset address within the segment.0x12345678


what is a segment


In the x86 architecture, memory is divided into multiple segments (Segment), each segment has a different size and attributes. A segment is a contiguous area of ​​memory that can contain information such as code, data, stack, etc. Usually, the start address and size of a segment are described by a segment descriptor, which is a data structure that contains the attribute information of the segment, such as access rights, base address, segment length, etc.

What are segment registers

In the x86 architecture, the segment register is used to determine the segment that the CPU needs to operate when accessing memory. The segment register stores the segment selector currently in use. The segment selector is a 16-bit value that contains the offset of the segment descriptor in the GDT (Global Descriptor Table) or LDT (Local Descriptor Table). displacement, and the privilege level of the segment. Through the segment selector, the CPU can find the corresponding segment descriptor, so as to obtain the base address and attribute information of the segment, and then the CPU uses this information to access the memory, so as to realize the protection and isolation of the memory.

The following are common segment registers in the x86 architecture:

CS(Code Segment) Code segment registers (instructions used to access programs).
DS(Data Segment) Data segment registers (used to access data structures such as global variables, static variables, constants, heaps, etc.).
ES(Extra Segment) Additional segment registers (in some string manipulation instructions, such as MOVS, LODS, STOS, CMPS, etc., used to access the data segment of the target string).
SS(Stack Segment) Stack segment registers (used to access local variables of functions, parameters of functions, return addresses, etc.).
FS(F Segment) The FS segment is added to support the special requirements of some operating systems (such as Windows). When in Windows user mode, the FS segment register is used to access the TEB data structure (Thread Environment Block) of the previous thread, and in the kernel mode to access the KPCR data structure (Kernel Processor Control Region) of the current thread.
GS(G Segment) The GS segment is also added to support the special needs of certain operating systems. It has no purpose defined by the processor, but is run by the operating system to achieve the purpose. The GS segment is not used in the Windows system.

Segment register structure

Each segment register consists of a "Visible Part" part and a "Hidden Part" part, and this visible part is the Segment Selector often mentioned above . When the segment selector is loaded into the visible part of a segment register, the CPU also obtains the invisible information of the segment register through the segment descriptor pointed to by the segment selector: segment base address (Base Address), segment limit length ( Limit) and access rights (Access Infomation) .

The segment register has a total of 96 bits, of which the segment selector of the visible part occupies 16 bits, the segment base address of the invisible part occupies 32 bits, the segment length is 32 bits, and the access right is 16 bits.

Detection of invisible parts

We use OD to attach a program arbitrarily, and we can see that except the base address and length limit of the fs segment are special, the base address of other segments is 0 and the length limit is 0xFFFFFFFF. as the picture shows:

Segment base detection

Write the following test code:

#include "stdafx.h"
#include "Windows.h"

int a = 0;
int main(int argc, _TCHAR* argv[])
{
	__asm
	{
		//mov ax,fs;	
		//mov ds,ax;    //让ds等于fs
		mov ebx,dword ptr ds:[0];    //取0偏移处地址的值赋给ebx
		mov ax,es;
		mov ds,ax;    //还原ds(es的值一般与ds的值相同,这里用es帮助ds还原)
		mov dword ptr ds:[a],ebx;    //赋值a等于ebx(0偏移处地址的值)
	}
	printf("%x",a);
	system("pause");
	return 0;
}

As we all know, under normal circumstances, when the code runs to mov ebx,dword ptr ds:[0], an error will be reported, because address 0 is usually a reserved address. The running result is shown in the figure:

But when we open the comment in the code and rerun it, we will find that a value can be printed out normally, as shown in the figure:

The reason why it can be executed normally the second time is because the segment base addresses of the fs segment and the ds segment are different. When we run it for the first time, it cannot be accessed normally because ds.base + 0 = 0. But when running for the second time, the ds segment is first modified to be equal to the fs segment, and when the mov ebx,dword ptr ds:[0] is executed , it is actually equivalent to accessing fs.base + 0. Since fs.base is not 0, it can run smoothly.

segment limit detection

Write the following test code:

#include "stdafx.h"
#include "Windows.h"

int a = 0;
int main(int argc, _TCHAR* argv[])
{
	__asm
	{
		mov eax,dword ptr fs:[0xFFC];//0xFFC 0xFFD 0xFFE 0xFFF
		mov eax,dword ptr fs:[0xFFD];//0xFFD 0xFFE 0xFFF 0x1000
	}
	printf("%x",a);
	system("pause");
	return 0;
}

When the code runs to mov eax,dword ptr fs:[0xFFD], a memory access error occurs, as shown in the figure:

This is because when reading 4 bytes of data at offset 0xFFD, you need to access to offset 0x1000, which has exceeded the limit of the fs segment, and when reading 4 bytes of data at offset 0xFFC, Only the 0xFFF offset is accessed, and the segment length of 0xFFF is not exceeded.

Detection of access rights

Write the following test code:

#include "stdafx.h"
#include "Windows.h"

int a = 0;
int main(int argc, _TCHAR* argv[])
{
	__asm
	{
		mov dword ptr ds:[a],1;    //给a赋值
		mov ax,cs;    
		mov ds,ax;    //让ds等于cs
		mov dword ptr ds:[a],2;    //给a赋值
	}
	printf("%x",a);
	system("pause");
	return 0;
}

 When the code runs to mov dword ptr ds:[a],2 , a memory access error occurs, as shown in the figure:

 This is because the cs segment does not have write permission, so an error occurred during the second assignment.

Guess you like

Origin blog.csdn.net/weixin_43074760/article/details/131743110