The first thing you have to do is memory, register, and program run rules.
Storage knowledge:
File offset: The address of the data in the PE file, offset from the beginning of the file when the file is stored on disk;
Virtual memory address: 4G virtual space for each process;
Physical memory address;
These three addresses need to be mapped at a layer level
Memory:
Code area: Storing binary code
Data area: Storing global variables
Heap area: Dynamic memory space (not yet understood)
Stack: Store function call Relationship (buffer overflow occurs here)
Focus on the structure of the stack:
Stack frame: Each function has its own stack frame, only the called function will open the stack frame in the system stack, the call will pop up the stack frame
Two registers (used to indicate the stack frame of the currently executing function):
EBP: Point to bottom of top of stack
ESP: pointing to the top of the stack
The process of creating a stack frame when a function call occurs:
Parameters into the stack
return address into stack
Saves the current stack frame state, that is, the EBP and ESP of the key function stack frame, which seems to normally be as long as EBP.
Load the ESP register contents into the EBP register, which is the stack frame that creates the called function as the current stack frame
According to the variables required by the called function to open up a certain size of space, with ESP minus space to get the current stack frame stack top (from the bottom of the stack to the top memory address from high to the end)
Knowing this, you can start the buffer overflow experiment:
#include <stdio.h>void hack () {printf ("hello");//_exit (0); return;} int main () {int a[0]; A[3]=0x004016b6;return 0;}
The main function does not call the hack () function, but the output is
See, you'll see.
We know that the array is moving backwards from the position of a[0], then the position of a[3] (the words should be a[2], I guess it should be my computer not only saved the last function of EBP also saved ESP so is a[3]) is exactly the return address, but to a[3] Assign to the starting address of the hack () function then the main function jumps to the address of hack () to execute the hack function. Note that the main function also has a return address.
The address of the hack () function is first passed through a normal call and is easily found with the IDA tool. Disassembly software explosion will use the mapping of the above three storage addresses.
I didn't expect to write so tired.
It's probably first.
Buffer Overflow Note