RAM – Random Access Memory
RAM olarak bilinen rastgele erişimli hafıza alanları geçici hafıza alanlarıdır ve işlemci ile birlıkte çalışan, donanımsal olarak işlemciye yakın duran bir alandır. Yazmaçlardan sonra en hızlı çalışan hafıza alanıdır. Bu alanlarda bulunan bilgiler geçici bilgilerdir. Fiziksel donanımın gücü kesildiğinde içinde barındırdığı bilgileri de kaybolmuş olur.
Sanal Bellek
Sanal bellek mekanizması, fiziksel bellek alanının boyutundan bağımsız olarak çalışan her proses için bellek alanı sağlayan bir mekanizmadır. Bu yapıya göre bir uygulama çalıştırıldığı zaman fiziksel hafıza alanına bağlı kalınmaksızın o proses için geniş ve kullanılabilir bir hafıza alanı ayırılır. Sanal olarak ayrımı yapılmış olan bu hafıza alanı işletim sistemi tarafından kontrol edilmektedir.
Sanal bellek kullanımının iki temel gerekçesi vardır(Wikipedia):
- Programların konumlandırılması, belleğin programlar arasında etkin ve güvenli bir şekilde paylaşılması.
- Sınırlı boyuta sahip ana belleğin programlama ve kullanım açısından yaratacağı güçlükleri aşmak.
Bu nedenle bu yazı ve sonrasındaki yazılarda kullandığımız adresler sanal bellek mekanizmasına ait olan adres değerleridir.
Memory Segmentation
İşletim sistemi üzerinde çalıştırılacak olan her proses, çalışma sırasında hafıza üzerinde kendine ait bir alana ihtiyaç duymaktadır. Proses için ayrılan bu hafıza alanı ise işletim sistemi tarafında farklı amaçlar için kullanılmak üzere bölümlere ayrılmıştır. Bu bölümler den kısaca bahsedelim
.text Segment
Bu hafıza alanı çalıştırılan binary dosyanın kodlarının saklandığı hafıza lanıdır. Bu alanda uygulamaya ait makina kodları şeklinde bulunmaktadır. Uygulama çalıştırıldığında işlemci program counter vasıtası ile bu alandaki kodaları işleyerek uygulamanın çalışmasını gerçekleştirir.
.data Segment
Bu alanda yazdığınız program içerisinde global olarak tanımlanmış ve ilk değer atanmış değişkenler bulunmaktadır.
.bss Segment
Bu alanda da aynen .data segment alanında olduğu gibi global olarak tanımlanmış değişkenler tutulur. Ancak bu değişkenler kodlama sırasında ilk değer almamışlardır.
Heap Segment
Heap alanı programın çalışması sırasında dinamik olarak kullanılan bir alandır. Bu alanın kullanımı programcı tarafından kontrol edilmektedir. Programı bu kontrol ederken malloc(), new() gibi allocator fonksiyonlarını kullanmalıdır.
Stack Segment
Bu alan uygulama çalıştırılırken kullanılan özel bir alandır. Çalıştırılan fonksiyonların geçici değerleri bu alanda barındırılmaktadır. Bir fonksiyon sistemde oluşturulduğu zaman stack üzerinde de o fonksiyon ile ilgili bir alan oluşturulur. Fonksiyonun çalışması tamamlandıktan sonra ise o fonksiyona ait hafıza alanı kullanılmaz ve stack ona göre tekrar düzenlenir. Bu alan programcı tarafından yönetilmesine gerek duyulmayan bir alandır. Diğer hafıza alanlarından farklı olarak stack yüksek adres alanından düşük adres alanına doğru büyüme gösterir.
Yukarıda bahsettiğimiz hafıza alanları ile aşağıdaki kod parçacığına baktığımız zaman daha iyi anlaşılacaktır.
123456789101112131415 #include <stdio.h>char g_varData = 0; // Data segmentchar g_varBSS; // BSS Segmentint main(){int varStack = 10; // Stackstatic int s_var1 = 12; // Data Segmentstatic int s_var2; // BSS Segmentint *ptrHeap; // HeapptrHeap = (int*)malloc(sizeof(int));return 0;}
Bu kod parçacığının değişlen adres değerlerine bakalım. GDB ile kodu çalıştırıp değşken adreslerini elde edelim.
123456789101112131415161718192021222324252627282930313233343536 root@kali-x86:~# gdb a.out -qReading symbols from /mnt/hgfs/D/VM_DATA/codes_and_examples/www.cihatyildiz.net/a.out...done.(gdb) list1 #include <stdio.h>23 char g_varData = 0; // Data segment4 char g_varBSS; // BSS Segment56 int main()7 {8 int varStack = 10; // Stack9 static int s_var1 = 12; // Data Segment10 static int s_var2; // BSS Segment11 int *ptrHeap; // Heap1213 ptrHeap = (int*)malloc(sizeof(int));1415 return 0;16 }(gdb) break 15Breakpoint 1 at 0x804843d: file memory_segment.c, line 15.(gdb) p &g_varData$1 = 0x8049684 ""(gdb) p &g_varBSS$2 = 0x804968c ""(gdb) p &varStack$3 = (int *) 0xbffff45c(gdb) p ptrHeap$4 = (int *) 0x804a008(gdb) p &s_var1$5 = (int *) 0x804967c(gdb) p &s_var2$6 = (int *) 0x8049688(gdb) info registers eipeip 0x804843d 0x804843d <main+33>(gdb)
GDB Kullanarak çalışan uygulama üzerinde değişken adreslerini görebiliyoruz. Bu durumda yazmış olduğumuz kod ile yukarıda gösterdiğimiz şekli ilişkilendirebiliriz. Bu şekil ile değişkenlerin hafızadaki konumları daha iyi anlaşılabilir.
Bu yazıda yaptıklarımızı kendiniz de bir Linux makine üzerinde gerçekleştirebilirsiniz. Registerlar, GCC ve GDB kullanımı gibi bazı konulara ileride değineceğim. Soru ve yorumlarınız için bu sayfanın altına yorumlarınızı yazabilirsiniz.
1 |
<strong>Kaynak:</strong> |
http://www.cihatyildiz.net/2015/03/exploitationdan-once-1-bellek-hakknda.html
www.wikipedia.org
http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/