Analysis on the principle of Buffer Overflow1.1 process memory DivisionDepending on the operating system, a process may be allocated to different memory areas for execution, but no matter what operating system or computer architecture, the memory used by the process can be divided into the following four parts by function: Text: determined by the program, including code (instructions) and read-only data, this area is equivalent to the text segment of the executable file. The computer returns to this area to take the command and execute it. Therefore, this area is usually marked as read-only, and any write operation on it will cause a segment error. The Data area contains initialized and uninitialized data. The Data area corresponds to the data-bass segment of the executable file, and the large size can be called by the system brk (2) if the bss data is extended or the memory available for the user stack is exhausted, the process will be blocked and will be running after a larger memory space is available, the new memory is added to the middle of the data and stack segments. global variables and static variables are stored in the segments. Heap (Heap): A process can dynamically apply for a certain size of memory in the Heap area through functions such as malloc, and release the memory after use. Stack: Used to dynamically store call relationships between functions to ensure that the called functions are resumed to the master function when they are returned. Parameters and local variables used for function calling are stored in the stack. Automatically assigned by the system. For example, declare the local variable int B in the function, and the system automatically opens up space for B in the stack. On intel X86 systems, the stack is considered to be reverse, that is, the stack grows down from the high-end address. When a piece of information is pushed into the stack, esp decreases and new elements are written to the target address. However, when a piece of information is popped up, an element is read from the address pointed by the esp pointer, and esp increases, moving and compressing the stack above the boundary can be understood in this way, esp points to the actual top element of the stack. Example: (the structure of the program memory in windons)
Explanation: In windowns, the stack is a data structure extended to a low address and a continuous memory area. It can be understood as follows: the address at the top of the stack and the maximum capacity of the stack are pre-defined by the system. In short, it is a constant determined during compilation, if the requested space exceeds the stack's namespace, overflow is prompted. Therefore, the space available from the stack is small. In the windowns environment, write a c program to verify the allocated address space of different variables: # include <stdio. h>
# Include <stdlib. h> void main () {const int c1 = 1, c2 = 2, c3 = 3;/* defines Read-Only variables and assigns them to the text */static int s1 = 1, s2 = 2, s3 = 3;/* Static initialization *. data Segment/static int t1, t2, t3;/* static uninitialized variable, data segment */int n1 = 1, n2 = 1, n3 = 1;/* local variable, stack segment */int * p = (int *) malloc (sizeof (int) * 3 );. /* malloc function, heap segment */printf ("\ n ******** the memory address of the local variable is ******* \ n "); printf ("n1 \'s loacation is 0x % 08x \ n", & n1); printf ("n2 \'s loacation is 0x % 08x \ n", & n2 ); printf ("n3 \'s loacation is 0x % 08x \ n", & n3 ); printf ("\ n the first address of the memory space allocated by the malloc function is 0x % 08x \ n", p); printf ("the memory location of the read-only variable is: \ n "); printf (" c1 \'s loacation is: 0x % x08 \ n ", & c1); printf (" c2 \'s loacation is: 0x % x08 \ n ", & c2); printf (" c3 \'s loacation is: 0x % x08 \ n ", & c3 ); printf ("\ n ****** initialize static variable memory address: ******** \ n"); printf ("s1 \'s loacation is: 0x % x08 \ n ", & s1); printf (" s2 \'s loacation is: 0x % x08 \ n ", & s2 ); printf ("s3 \'s loacation is: 0x % x08 \ n", & s3); the memory address of printf ("\ n ***** not starting static variables is: * ****** \ n "); printf (" t1 \'s loacation is: 0x % x08 \ n ", & t1 ); printf ("t2 \'s loacation is: 0x % x08 \ n", & t2); printf ("t3 \'s loacation is: 0x % x08 \ n ", & t3 );}
Run the available variable running result
1.2 function call ProcessA stack is an advanced and backward data table structure. Stack has two common operations: push and pop ). Stack has two important attributes: Stack top and stack bottom. The memory stack actually refers to the system stack. The system stack is automatically maintained by the system and used to call functions in advanced languages. Each function has its own stack frame space when called. When a function is called, the system stack opens a new stack frame for the function stack and pushes it into the stack. Therefore, the running function is always at the top of the stack. When the function returns, the system stack displays the stack frame space corresponding to the function. The Win32 system provides several special registers to identify the top stack frame of the system: ESP (Extended stack pointer): Extended stack pointer. This register stores a pointer pointing to the stack top of the function stack frame at the top of the system. The system completes the push, pop operation based on it, and the esp pointer is directed to the location where it stores valid data. Therefore, the push operation first moves the stack top pointer to the lower address, and then stores the data; the pop operation reads data first, and then moves the top pointer of the stack to the high address. EBP (extended base pointer) extends the base address pointer. This register stores a pointer pointing to the stack bottom of the function stack frame at the top of the system, and relies on it to address the stack memory variables. The EIP (extended instruction pointer) extends the instruction pointer, which is very important for Stack operations. The eip saves the instruction address to be executed next. Function stack frame: the space between esp and ebp is the current stack frame. Each function has its own esp and ebp pointer. esp indicates the stack top of the current stack frame, ebp identifies the bottom of the current stack. in C language, you must construct a function stack before calling a function to store real parameters and temporary variables. In the function stack frame, it generally contains the following important information: local variables: Open up memory space for the function local variables, which are generally implemented through sub exp and xx commands. Stack frame status: saves the top and bottom of the current stack (in fact, only the bottom of the current stack frame is saved, and the top of the current stack can be calculated through stack balance ), it is used to restore the previous stack frame after the current stack is popped up. Function return address: stores the commands that should be returned to the master function (main function) that calls the function after the function is executed. In the WIN32 operating system, when a function call occurs in a program, the system automatically allocates a stack structure for this function call. Function calls include the following steps: generally, the parameters of the called function are pushed from right to left to the system stack (that is, the function stack frame of the primary function that calls the function. Return address to stack: press the value of the current eip (the address of the next instruction pointing to the instruction in the current Code area) into the stack as the return address. Code area jump: point the EIP to the entrance of the called function. Stack frame adjustment: it is mainly used to maintain the stack frame balance. This process can be executed by the called function or the master function, which is determined by the compiler. First, the ebp is pushed into the stack (used to return to the original stack when the returned result is called), and the esp value of the primary function is sent to the Register ebp, as a new base address (the ebp of the new stack frame actually saves the esp of the primary function), and finally sets aside space for the local variable to subtract the appropriate value from the esp (note: memory Allocation is in the unit of words) the following uses C language call functions as an example to describe the Code as follows:
# Include <stdio. h> void fun (int a, int B, int c) {char buffer1 [4], buffer2 [5]; /* define two character arrays * // * unsigned * p = (unsigned *) (buffer1 + 8 ); */printf ("\ nc \'s location is 0x % 08x \ n", & c); printf ("\ nb \'s location is 0x % 08x \ n ", & B); printf ("\ na \'s location is 0x % 08x \ n", & ); printf ("\ nbuffer1 \'s location is 0x % 08x \ n", buffer1); printf ("\ nbuffer2 \'s location is 0x % 08x \ n", buffer2 ); // printf ("% 08x", * p);} void main () {int n1 = 1, n2 = 2, n3 = 3; fun (n1, n2, n3);/* call the function */printf ("\ n **************** \ n ");}
Run the command and check the result. Write this in the first part !!!
Original article: http://niuyuanwu.blog.51cto.com/6732782/1220598