exploit paylaşım grubumuz: t.me/HTTPwnn

ORTA SEVİYE C SERİSİ #1

Katılım
16 Haz 2026
Mesaj
111
Reaksiyon
83
xentr_thread_starter
╔════════════════════════════════════════════════════════════════════╗
║ ORTA SEVİYE C SERİSİ #1 ║
║ BELLEK MİMARİSİ ve STACK ║
║ (Artık Oyuncaklar Bitti, Gerçek C) ║
╚════════════════════════════════════════════════════════════════════╝

Bu noktaya kadar:

✓ Değişkenler

✓ Döngüler

✓ Fonksiyonlar

✓ Diziler

✓ Stringler

✓ Pointerlar

✓ Dinamik Bellek

öğrendik.

Fakat acı gerçek şu:

Şu ana kadar öğrendiğin şeyler C'nin belki %20'si.

Birçok kişi burada durur.

Kod yazmaya başlar.

Sonra:

Segmentation Fault

Stack Overflow

Memory Corruption

Buffer Overflow

Use After Free

gibi hatalarla karşılaşır.

Sebep?

Belleğin nasıl çalıştığını bilmemek.

Orta seviye C'nin ilk konusu:

BELLEK

çünkü C aslında bir programlama dilinden çok bellekle konuşma yöntemidir.

════════════════════════════════════════════════════════════════════

▓▓▓ C GERÇEKTE NEDİR?

Birçok dil:

Java

Python

C#

gibi diller geliştiriciyi korur.

Yanlış bir şey yaptığında:

"Dur kardeşim."

der.

C de ise:

"İstediğini yap."

der.

Sonra işletim sistemi gelir ve programı öldürür.

Bu yüzden:

C = Güç + Sorumluluk

demektir.

════════════════════════════════════════════════════════════════════

▓▓▓ PROGRAM ÇALIŞINCA NE OLUR?

Şunu yazdık:

int main()
{
return 0;
}

Derledik.

Çalıştırdık.

Peki ne oldu?

Birçok kişi:

"Program açıldı."

diye düşünür.

Ama arka planda çok daha fazla şey olur.

İşletim sistemi:

  1. Programı RAM'e yükler
  2. Bellek alanları oluşturur
  3. Stack oluşturur
  4. Heap oluşturur
  5. main fonksiyonunu çağırır
  6. Çalıştırmaya başlar
════════════════════════════════════════════════════════════════════

▓▓▓ BELLEK BÖLGELERİ

Bir C programının belleği genellikle şu bölümlere ayrılır:

+------------------+
| TEXT |
+------------------+
| DATA |
+------------------+
| BSS |
+------------------+
| HEAP |
| |
| |
| |
+------------------+
| |
| |
| |
| STACK |
+------------------+

Şimdilik en önemli yer:

STACK

════════════════════════════════════════════════════════════════════

▓▓▓ STACK NEDİR?

Stack:

Fonksiyonların yaşadığı yerdir.

Yerel değişkenlerin yaşadığı yerdir.

Programın geçici hafızasıdır.

Örnek:

int main()
{
int x = 10;

return 0;

}

Buradaki:

x

Stack'te tutulur.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK MANTIĞI

Stack:

LIFO

mantığıyla çalışır.

Last In First Out

Yani:

Son giren ilk çıkar.

════════════════════════════════════════════════════════════════════

▓▓▓ GERÇEK HAYAT ÖRNEĞİ

Bir tabak yığını düşün.

Üst üste diziliyor.

Yeni tabak:

en üste gelir.

Bir tabak alırken:

üsttekini alırsın.

Stack tam olarak böyledir.

════════════════════════════════════════════════════════════════════

▓▓▓ FONKSİYON ÇAĞRILINCA NE OLUR?

Örnek:

void test()
{
int x = 50;
}

int main()
{
test();
}

Program:

main()

çalıştırır.

Sonra:

test()

çağrılır.

Stack görünümü:

+--------+
| test() |
+--------+
| main() |
+--------+

Fonksiyon bitince:

test()

stackten silinir.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK FRAME NEDİR?

Her fonksiyon çalıştığında:

Stack Frame

oluşturulur.

İçinde:

✓ Parametreler

✓ Yerel değişkenler

✓ Dönüş adresleri

bulunur.

Örnek:

void test(int a)
{
int x = 10;
int y = 20;
}

Bu fonksiyon çağrılınca stackte yeni bir alan oluşur.

Bu alan:

Stack Frame

olarak adlandırılır.

════════════════════════════════════════════════════════════════════

▓▓▓ NEDEN ÖNEMLİ?

Çünkü:

Buffer Overflow

Stack Overflow

ROP

Exploit Development

gibi konuların tamamı Stack üzerinden çalışır.

Reverse Engineering yapan biri için Stack bilmek zorunludur.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK ADRESLERİ

Örnek:

#include <stdio.h>

int main()
{
int x = 10;

printf("%p",&x);

return 0;
}

Çıktı:

0x7ffe....

benzeri bir şey olur.

Çünkü:

x

Stack üzerinde tutulmaktadır.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK VE POINTER

Örnek:

int x = 10;

int *ptr = &x;

Bellek:

Adres Veri

1000 10

ptr

1000 adresini tutar.

*ptr

ise:

1000 adresindeki değeri getirir.

Yani:

10

════════════════════════════════════════════════════════════════════

▓▓▓ EN KRİTİK HATA

Birçok kişi şöyle yapar:

int* test()
{
int x = 50;

return &x;
}

Kod derlenebilir.

Ama çok büyük hata vardır.

Neden?

Çünkü:

x

Stack üzerindedir.

Fonksiyon bitince:

x yok olur.

Adres artık geçersizdir.

Bu hataya:

Dangling Pointer

denir.

════════════════════════════════════════════════════════════════════

▓▓▓ ADIM ADIM İNCELEYELİM

Fonksiyon başladı.

Stack Frame oluştu.

x oluşturuldu.

Adres:

1000

olsun.

return &x;

dedi.

Fonksiyon bitti.

Stack Frame silindi.

Artık:

1000

adresindeki veri güvenilir değildir.

Pointer hala orayı gösterir.

İşte felaket burada başlar.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK OVERFLOW NEDİR?

Şu kodu düşün:

void test()
{
test();
}

int main()
{
test();
}

Ne olur?

test()

kendini çağırır.

Sonra tekrar.

Sonra tekrar.

Sonra tekrar.

Stack sürekli büyür.

Bir noktada:

RAM'deki ayrılan Stack alanı dolar.

Sonuç:

Stack Overflow

════════════════════════════════════════════════════════════════════

▓▓▓ RECURSION'A GİRİŞ

Bir fonksiyonun kendini çağırmasına:

Recursion

denir.

Örnek:

void say(int n)
{
if(n == 0)
return;

printf("%d\n",n);

say(n-1);
}

say(5);

Çıktı:

5
4
3
2
1

Burada recursion güvenlidir.

Çünkü durma şartı vardır.

════════════════════════════════════════════════════════════════════

▓▓▓ SEGMENTATION FAULT NEDİR?

Linux kullanıcılarının korkulu rüyası.

Sebep:

Programın erişmemesi gereken belleğe erişmesi.

Örnek:

int *ptr = NULL;

*ptr = 10;

Sonuç:

Segmentation Fault

Çünkü:

NULL

geçerli bir adres değildir.

════════════════════════════════════════════════════════════════════

▓▓▓ BUFFER OVERFLOW'A GİRİŞ

Örnek:

char isim[5];

scanf("%s",isim);

Kullanıcı:

Cyber3301RD

girerse ne olur?

5 karakterlik yere

11 karakter sığdırmaya çalışırız.

Sonuç:

Bellek taşması.

Buna:

Buffer Overflow

denir.

Bu konu güvenlik dünyasının temelidir.

════════════════════════════════════════════════════════════════════

▓▓▓ REVERSE ENGINEERING'DE STACK

Bir crackme açtığında

bir oyun analiz ettiğinde

bir malware incelediğinde

sürekli göreceğin şeyler:

ESP

EBP

RSP

RBP

CALL

RET

PUSH

POP

olacaktır.

Bunların tamamı Stack ile ilgilidir.

Bu yüzden bu konuyu ezber değil anlayarak öğrenmek gerekir.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ LAB #1

Adresleri İnceleme

#include <stdio.h>

int main()
{
int a = 10;
int b = 20;
int c = 30;

printf("%p\n",&a);
printf("%p\n",&b);
printf("%p\n",&c);

return 0;
}

Adreslerin birbirine yakın olduğunu göreceksin.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ LAB #2

Dangling Pointer

int* test()
{
int x = 100;

return &x;
}

int main()
{
int *p = test();

printf("%d",*p);
}

Davranış tanımsızdır.

Bazen çalışır.

Bazen çöker.

Bazen saçma değer verir.

En tehlikeli hata türlerinden biridir.

════════════════════════════════════════════════════════════════════

✓ BÖLÜM ÖZETİ

Bu bölümde:

✓ Program belleği

✓ Text Segment

✓ Data Segment

✓ BSS

✓ Heap

✓ Stack

✓ Stack Frame

✓ Fonksiyon çağrıları

✓ Dangling Pointer

✓ Stack Overflow

✓ Segmentation Fault

✓ Buffer Overflow'a giriş

✓ Reverse Engineering bağlantısı

öğrendik.

Bir sonraki bölümde:

HEAP MİMARİSİ

malloc'un arkasında gerçekte ne oluyor

Heap Exploitation temelleri

Fragmentation

Allocator Mantığı

konularına geçeceğiz.
 
╔════════════════════════════════════════════════════════════════════╗
║ ORTA SEVİYE C SERİSİ #1 ║
║ BELLEK MİMARİSİ ve STACK ║
║ (Artık Oyuncaklar Bitti, Gerçek C) ║
╚════════════════════════════════════════════════════════════════════╝

Bu noktaya kadar:

✓ Değişkenler

✓ Döngüler

✓ Fonksiyonlar

✓ Diziler

✓ Stringler

✓ Pointerlar

✓ Dinamik Bellek

öğrendik.

Fakat acı gerçek şu:

Şu ana kadar öğrendiğin şeyler C'nin belki %20'si.

Birçok kişi burada durur.

Kod yazmaya başlar.

Sonra:

Segmentation Fault

Stack Overflow

Memory Corruption

Buffer Overflow

Use After Free

gibi hatalarla karşılaşır.

Sebep?

Belleğin nasıl çalıştığını bilmemek.

Orta seviye C'nin ilk konusu:

BELLEK

çünkü C aslında bir programlama dilinden çok bellekle konuşma yöntemidir.

════════════════════════════════════════════════════════════════════

▓▓▓ C GERÇEKTE NEDİR?

Birçok dil:

Java

Python

C#

gibi diller geliştiriciyi korur.

Yanlış bir şey yaptığında:

"Dur kardeşim."

der.

C de ise:

"İstediğini yap."

der.

Sonra işletim sistemi gelir ve programı öldürür.

Bu yüzden:

C = Güç + Sorumluluk

demektir.

════════════════════════════════════════════════════════════════════

▓▓▓ PROGRAM ÇALIŞINCA NE OLUR?

Şunu yazdık:

int main()
{
return 0;
}

Derledik.

Çalıştırdık.

Peki ne oldu?

Birçok kişi:

"Program açıldı."

diye düşünür.

Ama arka planda çok daha fazla şey olur.

İşletim sistemi:

  1. Programı RAM'e yükler
  2. Bellek alanları oluşturur
  3. Stack oluşturur
  4. Heap oluşturur
  5. main fonksiyonunu çağırır
  6. Çalıştırmaya başlar
════════════════════════════════════════════════════════════════════

▓▓▓ BELLEK BÖLGELERİ

Bir C programının belleği genellikle şu bölümlere ayrılır:

+------------------+
| TEXT |
+------------------+
| DATA |
+------------------+
| BSS |
+------------------+
| HEAP |
| |
| |
| |
+------------------+
| |
| |
| |
| STACK |
+------------------+

Şimdilik en önemli yer:

STACK

════════════════════════════════════════════════════════════════════

▓▓▓ STACK NEDİR?

Stack:

Fonksiyonların yaşadığı yerdir.

Yerel değişkenlerin yaşadığı yerdir.

Programın geçici hafızasıdır.

Örnek:

int main()
{
int x = 10;

return 0;

}

Buradaki:

x

Stack'te tutulur.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK MANTIĞI

Stack:

LIFO

mantığıyla çalışır.

Last In First Out

Yani:

Son giren ilk çıkar.

════════════════════════════════════════════════════════════════════

▓▓▓ GERÇEK HAYAT ÖRNEĞİ

Bir tabak yığını düşün.

Üst üste diziliyor.

Yeni tabak:

en üste gelir.

Bir tabak alırken:

üsttekini alırsın.

Stack tam olarak böyledir.

════════════════════════════════════════════════════════════════════

▓▓▓ FONKSİYON ÇAĞRILINCA NE OLUR?

Örnek:

void test()
{
int x = 50;
}

int main()
{
test();
}

Program:

main()

çalıştırır.

Sonra:

test()

çağrılır.

Stack görünümü:

+--------+
| test() |
+--------+
| main() |
+--------+

Fonksiyon bitince:

test()

stackten silinir.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK FRAME NEDİR?

Her fonksiyon çalıştığında:

Stack Frame

oluşturulur.

İçinde:

✓ Parametreler

✓ Yerel değişkenler

✓ Dönüş adresleri

bulunur.

Örnek:

void test(int a)
{
int x = 10;
int y = 20;
}

Bu fonksiyon çağrılınca stackte yeni bir alan oluşur.

Bu alan:

Stack Frame

olarak adlandırılır.

════════════════════════════════════════════════════════════════════

▓▓▓ NEDEN ÖNEMLİ?

Çünkü:

Buffer Overflow

Stack Overflow

ROP

Exploit Development

gibi konuların tamamı Stack üzerinden çalışır.

Reverse Engineering yapan biri için Stack bilmek zorunludur.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK ADRESLERİ

Örnek:

#include <stdio.h>

int main()
{
int x = 10;

printf("%p",&x);

return 0;
}

Çıktı:

0x7ffe....

benzeri bir şey olur.

Çünkü:

x

Stack üzerinde tutulmaktadır.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK VE POINTER

Örnek:

int x = 10;

int *ptr = &x;

Bellek:

Adres Veri

1000 10

ptr

1000 adresini tutar.

*ptr

ise:

1000 adresindeki değeri getirir.

Yani:

10

════════════════════════════════════════════════════════════════════

▓▓▓ EN KRİTİK HATA

Birçok kişi şöyle yapar:

int* test()
{
int x = 50;

return &x;
}

Kod derlenebilir.

Ama çok büyük hata vardır.

Neden?

Çünkü:

x

Stack üzerindedir.

Fonksiyon bitince:

x yok olur.

Adres artık geçersizdir.

Bu hataya:

Dangling Pointer

denir.

════════════════════════════════════════════════════════════════════

▓▓▓ ADIM ADIM İNCELEYELİM

Fonksiyon başladı.

Stack Frame oluştu.

x oluşturuldu.

Adres:

1000

olsun.

return &x;

dedi.

Fonksiyon bitti.

Stack Frame silindi.

Artık:

1000

adresindeki veri güvenilir değildir.

Pointer hala orayı gösterir.

İşte felaket burada başlar.

════════════════════════════════════════════════════════════════════

▓▓▓ STACK OVERFLOW NEDİR?

Şu kodu düşün:

void test()
{
test();
}

int main()
{
test();
}

Ne olur?

test()

kendini çağırır.

Sonra tekrar.

Sonra tekrar.

Sonra tekrar.

Stack sürekli büyür.

Bir noktada:

RAM'deki ayrılan Stack alanı dolar.

Sonuç:

Stack Overflow

════════════════════════════════════════════════════════════════════

▓▓▓ RECURSION'A GİRİŞ

Bir fonksiyonun kendini çağırmasına:

Recursion

denir.

Örnek:

void say(int n)
{
if(n == 0)
return;

printf("%d\n",n);

say(n-1);
}

say(5);

Çıktı:

5
4
3
2
1

Burada recursion güvenlidir.

Çünkü durma şartı vardır.

════════════════════════════════════════════════════════════════════

▓▓▓ SEGMENTATION FAULT NEDİR?

Linux kullanıcılarının korkulu rüyası.

Sebep:

Programın erişmemesi gereken belleğe erişmesi.

Örnek:

int *ptr = NULL;

*ptr = 10;

Sonuç:

Segmentation Fault

Çünkü:

NULL

geçerli bir adres değildir.

════════════════════════════════════════════════════════════════════

▓▓▓ BUFFER OVERFLOW'A GİRİŞ

Örnek:

char isim[5];

scanf("%s",isim);

Kullanıcı:

Cyber3301RD

girerse ne olur?

5 karakterlik yere

11 karakter sığdırmaya çalışırız.

Sonuç:

Bellek taşması.

Buna:

Buffer Overflow

denir.

Bu konu güvenlik dünyasının temelidir.

════════════════════════════════════════════════════════════════════

▓▓▓ REVERSE ENGINEERING'DE STACK

Bir crackme açtığında

bir oyun analiz ettiğinde

bir malware incelediğinde

sürekli göreceğin şeyler:

ESP

EBP

RSP

RBP

CALL

RET

PUSH

POP

olacaktır.

Bunların tamamı Stack ile ilgilidir.

Bu yüzden bu konuyu ezber değil anlayarak öğrenmek gerekir.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ LAB #1

Adresleri İnceleme

#include <stdio.h>

int main()
{
int a = 10;
int b = 20;
int c = 30;

printf("%p\n",&a);
printf("%p\n",&b);
printf("%p\n",&c);

return 0;
}

Adreslerin birbirine yakın olduğunu göreceksin.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ LAB #2

Dangling Pointer

int* test()
{
int x = 100;

return &x;
}

int main()
{
int *p = test();

printf("%d",*p);
}

Davranış tanımsızdır.

Bazen çalışır.

Bazen çöker.

Bazen saçma değer verir.

En tehlikeli hata türlerinden biridir.

════════════════════════════════════════════════════════════════════

✓ BÖLÜM ÖZETİ

Bu bölümde:

✓ Program belleği

✓ Text Segment

✓ Data Segment

✓ BSS

✓ Heap

✓ Stack

✓ Stack Frame

✓ Fonksiyon çağrıları

✓ Dangling Pointer

✓ Stack Overflow

✓ Segmentation Fault

✓ Buffer Overflow'a giriş

✓ Reverse Engineering bağlantısı

öğrendik.

Bir sonraki bölümde:

HEAP MİMARİSİ

malloc'un arkasında gerçekte ne oluyor

Heap Exploitation temelleri

Fragmentation

Allocator Mantığı

konularına geçeceğiz.
eline sağlık fakat
Kod:
Code etiketler içinde yaz kodları.
 
Geri
En Üst