Programs in Memory
When processes are loaded into memory, they are basically broken into many small
sections
.text Section
The .text section, also known as the code segment, 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 readable and executable and will cause an access violation
if a write attempt is made. The size is fixed at runtime when the process is first loaded
.data Section
The .data section is used to store global initialized variables, such as
int a = 0;
The size of this section is fixed at runtime. It should only be marked as readable.
.bss Section
The below stack section (.bss) is used to store certain types of global uninitialized variables,
such as
int a;
The size of this section is fixed at runtime. This segment needs to be readable and writ-
able but should not be executable.
Heap Section
The heap section is used to store dynamically allocated variables and grows from the
lower-addressed memory to the higher-addressed memory. The allocation of memory is
controlled through the malloc(), realloc(), and free() functions. The heap section should be readable and writable but should not be executable
Stack Section
The stack section is used to keep track of function calls (recursively) and grows from
the higher-addressed memory to the lower-addressed memory on most system
Environment/Arguments Section
The environment/arguments section is used to store a copy of system-level variables that
may be required by the process during runtime
This sectionis writable, allowing its use in format string and buffer overflow exploits
Buffers
The term buffer refers to a storage place used to receive and hold data until it can be
handled by a process. Since each process can have its own set of buffers, it is critical to
keep them straight; this is done by allocating the memory within the .data or .bss section
of the process’s memory. Remember, once allocated, the buffer is of fixed length. The
buffer may hold any predefined type of data; however, for our purpose, we will focus on
string-based buffers, which are used to store user input and text-based variables.
Strings in Memory
strings are just continuous arrays of character data in memory. The string is
referenced in memory by the address of the first character. The string is terminated or
ended by a null character (\0 in C).
Pointers
Pointers are special pieces of memory that hold the address of other pieces of memory.
Moving data around inside of memory is a relatively slow operation. It turns out that
instead of moving data, keeping track of the location of items in memory through pointers and simply changing the pointers is much easier. Pointers are saved in 4 or 8 bytes
of contiguous memory, depending on whether the application is 32-bit or 64-bit.
Now that you have the basics down, we will look at a simple example
sections
.text Section
The .text section, also known as the code segment, 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 readable and executable and will cause an access violation
if a write attempt is made. The size is fixed at runtime when the process is first loaded
.data Section
The .data section is used to store global initialized variables, such as
int a = 0;
The size of this section is fixed at runtime. It should only be marked as readable.
.bss Section
The below stack section (.bss) is used to store certain types of global uninitialized variables,
such as
int a;
The size of this section is fixed at runtime. This segment needs to be readable and writ-
able but should not be executable.
Heap Section
The heap section is used to store dynamically allocated variables and grows from the
lower-addressed memory to the higher-addressed memory. The allocation of memory is
controlled through the malloc(), realloc(), and free() functions. The heap section should be readable and writable but should not be executable
Stack Section
The stack section is used to keep track of function calls (recursively) and grows from
the higher-addressed memory to the lower-addressed memory on most system
Environment/Arguments Section
The environment/arguments section is used to store a copy of system-level variables that
may be required by the process during runtime
This sectionis writable, allowing its use in format string and buffer overflow exploits
Buffers
The term buffer refers to a storage place used to receive and hold data until it can be
handled by a process. Since each process can have its own set of buffers, it is critical to
keep them straight; this is done by allocating the memory within the .data or .bss section
of the process’s memory. Remember, once allocated, the buffer is of fixed length. The
buffer may hold any predefined type of data; however, for our purpose, we will focus on
string-based buffers, which are used to store user input and text-based variables.
Strings in Memory
strings are just continuous arrays of character data in memory. The string is
referenced in memory by the address of the first character. The string is terminated or
ended by a null character (\0 in C).
Pointers
Pointers are special pieces of memory that hold the address of other pieces of memory.
Moving data around inside of memory is a relatively slow operation. It turns out that
instead of moving data, keeping track of the location of items in memory through pointers and simply changing the pointers is much easier. Pointers are saved in 4 or 8 bytes
of contiguous memory, depending on whether the application is 32-bit or 64-bit.
Now that you have the basics down, we will look at a simple example
C:
#include <stdlib.h>
#include <string.h>
/* memory.c */ // this comment simply holds the program name
int _index = 5; // integer stored in data (initialized)
char * str; // string stored in bss (uninitialized)
int nothing; // integer stored in bss (uninitialized)
void funct1(int c){ // bracket starts function1 block with argument (c)
int i=c; // stored in the stack region
str = (char*) malloc (10 * sizeof (char)); // Reserves 10 characters in
// the heap region
strncpy(str, "abcde", 5); // copies 5 characters "abcde" into str
} // end of function1
void main (){ // the required main function
funct1(1); // main calls function1 with an argument
} // end of the main function