Jump to content

Recommended Posts

In acest articol voi vorbi despre memory segmentation.voi defini intrun mod destul de clar cum vine impartita memoria in segmente atunci cand vine creat un executabil.Avand in vedere faptul ca exista mai multe tipuri de memorie pentru a clarifica lucrurile main memory se refera la RAM.In acest tutorial am vorbit despre memorie hysical && Virtual Memory Explained iar aici voi vorbi despre modul in care memoria RAM vine impartita in segmente.Dupa acest tutorial se va putea intelege conceptul de stack si heap.Voi explica doar lucrurile esentiale iar ceea ce e mai complicat il veti intelege dpe parcurs doar daca veti programa in C sau Assembly.

Un alt tutorial care va poate fi de ajutor pentru a intelege ceea ce va fi descris aici este Basic GAS AT&T Assembly Syntax [Tutorial] .Daca vati saturat sa auziti de PUSH,POP,ESP,EBP,EIP,STACK,HEAP,BUFFER atunci lasati-o balta deoarece acest tutorial nu e pentru voi.

Voi incepe cu urmatoarea definite:Memoria ram vine impartita in segmente pe care le putem definii sectii de memorie.Cand si unde poate fi observat acest lucru?In momentul in care vine scris un executabil datele din codul sursa impreuna cu instructiile vin salvate in memorie.Ei bine fiecare data din executabil vine salvata intro anumita sectie de memorie.La ce ajuta sa cunosti acest lucru?Ei bine raspunsul e simplu , deoarece iti permite sa ai controlul asupra executabilului si a sistemului.Cum? Veti observa si va veti da seama doar daca veti continua sa studiati acest principiu.Voi prezenta sectiile in care poate fi impartita memoria iar in momentul in care voi face un exemplu cu o bucata de cod voi explica unde vine pusa fiecare instructie.


RAM
-------------
- stack - <-segment de memorie dinamic
-------------
- -
- -
- NULL - <-segment de memorie nealocat
- -
- -
-------------
- heap - <-segment de memorie dinamic
-------------
- BSS - <-variabile care nu sunt initializate
-------------
- data - <-variabile initializate
-------------
- text - <-instructiile executabilului
-------------
- -
- OS - <- spatiu alocat pentru sistemul operativ
- -
-------------

Sectiile sau zonele de memorie contin anumite adrese , ceea ce este important sa cunoasteti este faptul ca numerotarea adreselor vine facuta de la valoarea cea mai mare plecand in decrement spre 0 , iar segmentul OS ajunge la prima memoria disponibila in RAM.Inca un aspect important , in momentul in care vin introduse date in segmentul stack acesta incepe sa alocheze spatiu din segmentul NULL , iar cand datele vin extrase elibereaza segmentul NULL, acelasi lucru se intampla cu segmentul Heap, atunci cand vin stocate date acesta va ocupa spatiu in Null.(Note:Am chemat acest segment null dar de fapt nu are nici un nume generic ci e doar un spatiu de memorie care nu e folosit)In momentul in care vine scris un executabil variabilele, functiile si instructiile definite vin stocate in aceste segmente.Aici vom face cateva exemple:Urmatoarul exemplu demonstreaza in care segment vor fi stocate anumite variabile


#include<stdio.h>
#include <stdlib.h>

void function()
{
int first; //stack
printf("Introdu un caracter: ");
scanf("%d",&first);
printf("[+] int %d (va merge in segmentul stack la adresa addr %p)\x0a",first ,&first);
return;
}

int main()
{
static int second; // va merge in segmentul BSS
static int third = 2; // va merge in segmentul data

//int *fourth; // urmatoarea variabila este alocata in segmentul stack dar e un pointer in segmentul heap
int *fourth = (int*)malloc(sizeof(int)); //heap
int *fifth; // un pointer care merge in segmentul stack

printf("[+] int second addr %p (va merge in segmentul bss)\x0a",&second);
printf("[+] int third addr %p (va merge in segmentul data)\x0a",&third);
printf("[+] int fourth addr %p (va merge in segmentul heap)\x0a",&*fourth);
printf("[+] int fifth addr %p (va merge in segmentul stack)\x0a",&fifth);
function();
return 0;

}

Va trebui doar sa compilati si sa executati codul, asadar in output veti putea observa fiecare variabila la care adresa se gaseste si in care segment vine stocata.Dupa cum observati istructiile programului vor fi stocate in segmentul text


Contents of section .text:
80483a0 31ed5e89 e183e4f0 50545268 20850408 1.^.....PTRh ...
80483b0 68308504 08515668 98840408 e897ffff h0...QVh........
80483c0 fff49090 90909090 90909090 90909090 ................
80483d0 5589e553 83ec0480 3d289804 0800753f U..S....=(....u?
80483e0 a12c9804 08bb2097 040881eb 1c970408 .,.... .........
80483f0 c1fb0283 eb0139d8 731e8db6 00000000 ......9.s.......
8048400 83c001a3 2c980408 ff14851c 970408a1 ....,...........
8048410 2c980408 39d872e8 c6052898 04080183 ,...9.r...(.....
8048420 c4045b5d c38d7426 008dbc27 00000000 ..[]..t&...'....
8048430 5589e583 ec18a124 97040885 c07412b8 U......$.....t..
8048440 00000000 85c07409 c7042424 970408ff ......t...$$....
8048450 d0c9c390 5589e583 ec28b8e0 85040889 ....U....(......
8048460 0424e801 ffffffb8 f6850408 8d55f489 .$...........U..
8048470 54240489 0424e80d ffffff8b 55f4b8fc T$...$......U...
8048480 8504088d 4df4894c 24088954 24048904 ....M..L$..T$...
8048490 24e8d2fe ffffc9c3 5589e583 e4f083ec $.......U.......
80484a0 20c70424 04000000 e8cbfeff ff894424 ..$..........D$
80484b0 1cb83c86 0408c744 24043098 04088904 ..<....D$.0.....
80484c0 24e8a2fe ffffb874 860408c7 44240424 $......t....D$.$
80484d0 98040889 0424e88d feffffb8 ac860408 .....$..........
80484e0 8b54241c 89542404 890424e8 78feffff .T$..T$...$.x...
80484f0 b8d88604 088d5424 18895424 04890424 ......T$..T$...$
8048500 e863feff ffe84aff ffffb800 000000c9 .c....J.........
8048510 c3909090 90909090 90909090 90909090 ................
8048520 5589e55d c38d7426 008dbc27 00000000 U..]..t&...'....
8048530 5589e557 5653e84f 00000081 c3c11200 U..WVS.O........
8048540 0083ec1c e8bffdff ff8dbb18 ffffff8d ................
8048550 8318ffff ff29c7c1 ff0285ff 742431f6 .....)......t$1.
8048560 8b451089 4424088b 450c8944 24048b45 .E..D$..E..D$..E
8048570 08890424 ff94b318 ffffff83 c60139fe ...$..........9.
8048580 72de83c4 1c5b5e5f 5dc38b1c 24c39090 r....[^_]...$...
8048590 5589e553 83ec04a1 14970408 83f8ff74 U..S...........t
80485a0 13bb1497 04086690 83eb04ff d08b0383 ......f.........
80485b0 f8ff75f4 83c4045b 5dc39090 ..u....[]...

Vom continua cu 2 segmente de memorie importante si anume Stack si Heap


-------------
- stack - <-segment de memorie dinamic
-------------
- -
- -
- NULL - <-segment de memorie nealocat
- -
- -
-------------
- heap - <-segment de memorie dinamic
-------------

Recapituland , ori de cate ori vor fi stocate date in stack acesta va cobora in jos luand spatiul necesar pentru a stoca aceste date din segmentul NULL, acelasi efect se va intampla daca datele for fi stocate in segmentul heap.Probabil intrebarea voastra este urmatoarea , ce se intampla daca ambele segmente preiau spatiul disponibil din NULL?Ei bine segmentul stack este dinamic iar o data ce datele au fost procesate elibera spatiul din null ,acelasi lucru face si segmentul heap doar ca aici depinde de programator deoarece memoria in acest segment vine alocata prin functia malloc() si vine eliberata folosind functia free()Evident daca careva va aloca o gramada de memorie fara sa fie eliberata folosind-use de segmentul heap vom avea un memory leak.Segmentul stack este divers de heap si o data ce nu mai are nevoie de date va alibera memoria in mod dinamic si automat.

Cum functioneaza segmentul stack?In stack vin alocate diverse avariabile in mod dinamic.Spre exemplu daca noi stocam in stack valorile 1,2,3 , pentru a elibera sau extrage valorile se va face in mod invers , si anume prima valoare pe care o vom extrage afara din stack este 3 dupa care 2 si unu.Acest concept vine chemat LIFO (Last In First Out).O mica demonstratie:

Avem urmatorul cod:


int main()
{
int var1; //declar o variabila var1
int var2; //declar o variabila var2
int var3; //declar o variabila var3
}

Aceste date vin alocate in segmentul stack exact in modul in care au fost declarate si anume:


STACK
---------- <-EBP
- var1 -
----------
- var2 -
----------
- var3 -
---------- <-ESP

Segmentul de stack va creste in jos ocupand spatiu din segmentul NUll

Aici voi introduce 2 noi aspecte, in assembly vin folositi doi registrii

Registrul ce contine ultima adresa de memorie din stack care se numeste ESP /Extended Stack Pointer), un alt registru ce va contine primul record de memorie din functia sau procedura in care ne aflam si se numeste EBP(Extended Base Pointer)Momentan exista doar o singura functie si anume main.

Dupa cum am precizat numerotarea adreselor vine facut de sus in jos in mod invers, nu vom avea niciodata un stack care pleaca de la 0 deoarece intotdeauna in sistem vor exista deja alte processe care se vor folosi de aceste adrese.Asadar presupunem ca in momentul in care vrem sa introducem o valoare in stack ESP se afla la adresa 0xbffff9e8 ,deci pentru a stoca 4 byte in stack va trebui facut un decrement de 4 byte. Deci 0xbffff9e8 - 4 = bffff9e88.Acum ESP se va afla la adresa 0xbffff9e8.De cate ori vine introdusa o valoare vine facut un decrement.Acum in momentul in care eu fac urmatoare operatie matematica si anume bffff9e88 + 4 = 0xbffff9e8 voi sterge 4 byte din stack iar registrl ESP se va afla acum la adresa 0xbffff9e8.Avand in vedere faptul ca pleaca de la ao adresa superioara in decrement spre 0 cand se va face o adunare se vor sterge elemente iar in momentul in care se vor pune elemente se va face un decrement iar adresa stack-ului va creste in jos spre 0.Assembly pune la dispozitie doua instructii pentru a stoca si extrage date din stack, acestea sunt PUSH si POP.PUSH Va stoca o valoare in segmentul stack iar POP va extrage o valoare.Mai exista un aspect foarte important a acestui segment de memorie pe care il voi incerca sa explic cu urmatorul exemplu de cod:


#include <stdio.h>

int doprint()
{
printf("Hello\n");

}

int main ()
{
doprint();
return 0;
}

Avem un simplu executabil care chiama o functie care face un print.Vom analiza datele din stack in momentul in care vine chemata functia doprint.

Deci in momentul in care vine chemata functia print se intampla acest lucru

MAIN chiama doprint


0x080483de <main+6>: call 0x80483c4 <doprint>
0x080483e3 <main+11>: mov $0x0,%eax

In acest moment urmatoarea adresa care va trebui sa fie executata dupa ce doprint isi termina treaba va fi stocata in stack ca adresa de return.Can doprint termina treaba se intoarce aici si main continua.

Vine pusa valoarea registrului EBP in stack


0x080483c4 <doprint+0>: push %ebp

Valoarea EBP 0xbffff9a8

Valoarea actuala din ESP vine pusa in EBP

0x080483c5 <doprint+1>:	mov    %esp,%ebp

In stacK vine facut un decrement de 24 byte pentru a aloca spatiul necesar pentru variabile.

0x080483c7 <doprint+3>:	sub    $0x18,%esp

Note 0x18 este echivalent cu 24 in hex

Vin incarcate si stampate datele din functia doprint


0x080483ca <doprint+6>: movl $0x80484b0,(%esp)
0x080483d1 <doprint+13>: call 0x80482f8 <puts@plt>

Urmatoarea instructie este importanta deoarece aici functia doprint a terminat treaba si va trebui sa se intoarca in main ca sa termine programul


0x080483d6 <doprint+18>: leave
0x080483d7 <doprint+19>: ret

Instructia leave face in asa fel incat registrii ESB si EBP sa isi preia locul initial pe care il aveau inainte sa intre in doprint.Instructia ret va copia adresa 0x080483e3 in EIP asadar procesorul va executa instructtia care se gaseste la aceasta adresa si anume return 0;


Stack
--------------
- 0x080483e3 - <-Return Address
--------------
- EBP (OLD) -
-------------- <-EBP
- 0xbffff980 -
--------------
- 0xbffff990 -
-------------- <-ESP

In debugger segmentul de stack pentru aceste instructii poate fi reprezentat in acest mod


0xbffff980: 0xb7fc5304 0xb7fc4ff4 0x08048400 0xbffff9a8
0xbffff990: 0xb7eb3365 0xb7ff1040 0xbffff9a8 0x080483e3

Momentan inchei aici tutorialul, voi continua cu alte articole unde voi discuta despre buffer overflow.Daca aveti intrebari , le puteti face.Multe alte lucruri nu au fost explicate pentru a nu pune in confuzie user-ul.

Scopul acestui tutorial era sa explice faptul ca memoria poate fi impartita in segmente si ca in aceste segmente pot fi stocate diverse date.

Edited by pyth0n3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...