modules can really be helpful for reverse engineering process(read man/docs page)
functions
initially, function can be reverse-engineerd in isolation. Later, you can build up an understanding of how they fit together
function are represented as a graph
each block is a set of instructions that will execute one after the other
the stack
the stack is a region of memory used to store local variables and call context
elf sections:
- .data: used for preinitialized global writable data(such as global arrays with initial values)
- .rodata: read only data(such as string constants)
- .bss: used for uninitialized global writable data(such as global arrays without initial values)
the stack grows backwards
when you push to the stack, rsp is decreased by 8.
when you pop to the stack, rsp is increased by 8.
consider:
push 0x41; push 0x42; push 0x43

stack: initial layput:
The stack starts out storing (among some other things) the environment variables and the program arguments. For example:
$ env
USER=yans
HOME=/home/yans
PWD=/home/yans
$ ./program hello world
hello world

stack, calling a function
when a function is called, the address that the called funciton should return to implicityly pushed onto the stack
this return address is implicitly popped when the function return
the stack, function frame setup
every function sets up its stack frame, it has:
- stack pointer(rsp): point to the leftmost side of the stackframe
- baase pointer(rbp): point to the rightmost side of the stackframe.
- save off the callers base pointer
- set the current staack pointer as base pointer
- “allocate” space on the stack(substract from the stack pointer)