Memory Segmentation
Memory segmentation is the division of a computer’s primary memory into segments or sections. In a computer system using segmentation, a reference to a memory location includes a value that identifies a segment and an offset within that segment. Segments or sections are also used in object files of compiled programs when they are linked together into a program image and when the image is loaded into memory.
Segments usually correspond to natural divisions of a program such as individual routines or data tables so segmentation is generally more visible to the programmer than paging alone. Different segments may be created for different program modules, or for different classes of memory usage such as code and data segments. Certain segments may be shared between programs.
Each process or an executing program needs to have access to its own areas in memory. Hence, memory is broken down into small segments and allocated to processes as needed. Registers are used to store and keep track of the current segments a process maintains. Offset registers are used to keep track of where in the segment the critical pieces of data are kept.
x86 Memory Segmentation
It refers to the implementation of memory segmentation in the Intel x86 computer instruction set architecture. Segmentation was introduced on the Intel 8086 in 1978 as a way to allow programs to address more than 64 KB (65,536 bytes) of memory. The Intel 80286 introduced a second version of segmentation in 1982 that added support for virtual memory and memory protection. At this point the original model was renamed real mode, and the new version was named protected mode. The x86-64 architecture, introduced in 2003, has largely dropped support for segmentation in 64-bit mode.
In both real and protected modes, the system uses 16-bit segment registers to derive the actual memory address. In real mode, the registers CS, DS, SS, and ES point to the currently used program code segment (CS), the current data segment (DS), the current stack segment (SS), and one extra segment determined by the programmer (ES). The Intel 80386, introduced in 1985, adds two additional segment registers, FS and GS, with no specific uses defined by the hardware. The way in which the segment registers are used differs between the two modes.
The choice of segment is normally defaulted by the processor according to the function being executed. Instructions are always fetched from the code segment. Any stack push or pop or any data reference referring to the stack uses the stack segment. All other references to data use the data segment. The extra segment is the default destination for string operations (for example MOVS or CMPS). FS and GS have no hardware-assigned uses. The instruction format allows an optional segment prefix byte which can be used to override the default segment for selected instructions if desired.
Virtual Address Space – The virtual address space for a process is the set of virtual memory addresses that it can use. The address space for each process is private and cannot be accessed by other processes unless it is shared. A virtual address does not represent the actual physical location of an object in memory; instead, the system maintains a page table for each process, which is an internal data structure used to translate virtual addresses into their corresponding physical addresses. Each time a thread references an address, the system translates the virtual address to a physical address.
The virtual address space for 32-bit Windows is 4 gigabytes (GB) in size and divided into two partitions: one for use by the process and the other reserved for use by the system.
Memory Pools – The memory manager creates the following memory pools that the system uses to allocate memory: non-paged pool and paged pool. Both memory pools are located in the region of the address space that is reserved for the system and mapped into the virtual address space of each process. The non-paged pool consists of virtual memory addresses that are guaranteed to reside in physical memory as long as the corresponding kernel objects are allocated. The paged pool consists of virtual memory that can be paged in and out of the system. To improve performance, systems with a single processor have three paged pools, and multiprocessor systems have five paged pools.
The handles for kernel objects are stored in the paged pool, so the number of handles you can create is based on available memory. The system records the limits and current values for its non-paged pool, paged pool, and page file usage.
Each process on 32-bit Microsoft Windows has its own virtual address space that enables addressing up to 4 gigabytes of memory. Each process on 64-bit Windows has a virtual address space of 8 terabytes. All threads of a process can access its virtual address space. However, threads cannot access memory that belongs to another process, which protects a process from being corrupted by another process.
Windows has both physical and virtual memory. Memory is managed in pages, with processes demanding it as necessary. Memory pages are 4KB in size (both for physical and virtual memory); but you can also allocate memory in large (2-4MB, depending on architecture) pages for efficiency.
On 32-bit (x86) architectures, the total addressable memory is 4GB (232 bytes), divided equally into user space and system space. Pages in system space can only be accessed from kernel mode; user-mode processes (application code) can only access data that is appropriately marked in user mode. There is one single 2GB system space that is mapped into the address space for all processes; each process also has its own 2GB user space.
With a 64-bit architecture, the total address space is theoretically 264 = 16EB, but for a variety of software and hardware architectural reasons, 64-bit Windows only supports 244 = 16TB today, split equally between user and system space.
Programs and Memory
When processes are loaded into memory, they are basically broken into many small sections. There are six main sections which are of focus for an hacker and which are
- .text Section – The .text section basically corresponds to the .text portion of the binary executable file. It contains the machine instructions to get the task done. This section is marked as read-only and will cause a segmentation fault if written to. The size is fixed at runtime when the process is first loaded.
- .data Section – The .data section is used to store global initialized variables. The size of this section is fixed at runtime.
- .bss Section – The below stack section (.bss) is used to store global noninitialized variables. The size of this section is fixed at runtime.
- Heap Section – It stores dynamically allocated variables and grows from the lower-addressed memory to the higher-addressed memory.
- Stack Section – It keeps track of function calls (recursively) and grows from the higher-addressed memory to the lower-addressed memory on most systems. As the stack grows in this manner, it allows the subject of buffer overflows to exist. Local variables exist in the stack section.
- Environment/Arguments Section – It stores a copy of system-level variables required by the process during runtime like the path or hostname. It is writable, allowing its use in format string and buffer overflow exploits. It also stores the command-line arguments.
Apply for IT Support Certification
https://www.vskills.in/certification/certified-it-support-professional