Bir uygulama çalışırken aslında “tek bir şey” olmaz: bellek yerleşimi yapılır, izinler tanımlanır, kontrol akışı korunur ve bir şey ters giderse istisna (exception) mekanizması devreye girer. Bu yazı, o perde arkasındaki dört ana kavramı anlatmak için var.
Kısa bir hikâye: “Çalışıyor… ama niye bu kadar güvenli?”
Bir uygulamayı açtın. Her şey normal. Ama aslında arka planda Windows şöyle bir “güvenlik rutini” çalıştırıyor: “Bu kod nereye yerleşecek?” “Hangi sayfalar çalıştırılabilir?” “Bu fonksiyon çağrısı gerçekten nereye gidiyor?”
Ve bir şeyler ters giderse… “tamam, bu hata nasıl ele alınacak?” diye SEH devreye giriyor.
ASLR, DEP ve CFG çoğunlukla “mitigation” diye konuşulur. SEH ise doğrudan bir mitigation değil; Windows’un hata/istisna yönetim mekanizması. Ama güvenlikte rolü büyük, çünkü istismar senaryolarında (ve savunmada) sık sık adı geçer.
Hızlı Özet
- ASLR: Kodun/bileşenlerin bellekte her seferinde farklı adrese yerleşmesini hedefler; tahmin edilebilirliği azaltır.
- DEP / NX: Veri sayfalarının “çalıştırılmasını” engeller; kod ve veriyi net ayırır.
- CFG: Dolaylı çağrı/sıçramalarda (function pointer, vtable vb.) kontrol akışını kısıtlar; hedef doğrulaması yapar.
- SEH: Windows’un structured exception handling mekanizmasıdır; crash/exception durumlarında kontrolün nasıl aktarıldığını belirler.
- Bu özelliklerin bir kısmı PE Optional Header → DllCharacteristics bayraklarında, bir kısmı da Data Directories altında iz bırakır.
ASLR (Address Space Layout Randomization) nedir?
ASLR’ın olayı çok net: “Aynı bina, farklı sokak.” Uygulamanın ve DLL’lerin bellekteki adresi her çalıştırmada farklı olursa, saldırganın “şu fonksiyon kesin şu adreste” diye tahmin yürütmesi zorlaşır.
Pratikte ASLR; tahmin edilebilirliği düşürür, bazı istismar sınıflarının maliyetini artırır. Tek başına “imkânsız” yapmaz; ama savunmayı katman katman güçlendirir.
PE tarafında yalnızca “bayrağın açık olması” yetmeyebilir. İmajın taşınabilmesi için çoğu senaryoda relocation verisinin de anlamlı olması gerekir. (Relocation verisi yoksa, “rastgele yerleşim” etkisi azalabilir.)
DEP / NX (Data Execution Prevention) nedir?
DEP (NX), “veriyi çalıştırma” fikrine karşı çıkar. Stack/heap gibi veri bölgelerinin çalıştırılabilir olması, eski istismar tekniklerinin can damarıydı.
DEP/NX ile amaç şudur: Veri sayfaları çalıştırılamaz olsun. Kod çalışacaksa kod sayfasında dursun. Veri veride kalsın.
DEP, saldırganın “veri içine kod koyup çalıştırma” gibi kolay yollarını zorlaştırır. Bu yüzden modern istismarlar çoğu zaman “var olan kodu yeniden kullanma” (ör. ROP) gibi yaklaşımlara kayar. (Detaylı saldırı adımlarına girmiyorum; burada amaç savunma mantığını netleştirmek.)
CFG (Control Flow Guard) nedir?
CFG, özellikle “dolaylı” kontrol akışında devreye girer: function pointer’lar, virtual function çağrıları, callback’ler…
Mantığı şu: Program bir hedefe “atlarken” (indirect call/jump), o hedefin geçerli bir hedef olup olmadığını kontrol etmek. Böylece kontrol akışını manipüle eden bazı saldırı tekniklerinin hareket alanı daralır.
CFG, “her şeyi engelleyen tek bayrak” değildir. Ama modern Windows güvenliğinde önemli bir katmandır ve özellikle derleyici/linker desteğiyle birlikte güçlü hale gelir.
SEH (Structured Exception Handling) nedir?
SEH, Windows’un istisna yönetim mekanizmasıdır. Bir erişim ihlali (access violation), sıfıra bölme, illegal instruction… Bu gibi durumlarda sistem “ne yapacağını” SEH üzerinden belirler.
SEH’in güvenlikle ilişkisi şuradan gelir: Exception akışı, doğru tasarlanmadıysa geçmişte istismar için “yüzey” olabilmiştir. Bu yüzden Windows ekosisteminde yıllar içinde SafeSEH, SEHOP gibi önlemler ve x64’te daha tablo-temelli yaklaşımlar gelişmiştir.
32-bit (x86) dünyasında SEH geçmişte daha “zincir/stack tabanlı” yaklaşımlarla anılırken, 64-bit (x64) tarafta exception/unwind mekanizması daha “tablo-temelli” bilgilerle yürür. Bu fark, PE içinde hangi dizinlerin dolu/önemli olduğunu da etkiler.
PE Header’da nerede bulunurlar?
“Bunlar PE’nin neresinde?” sorusu çok iyi. Çünkü bir kısmı Optional Header içindeki bayraklarda görünür, bir kısmı ise Data Directories ve Load Config gibi yapılarda iz bırakır.
| Özellik | PE’de görünen yer | Ne ararsın? |
|---|---|---|
| ASLR | Optional Header → DllCharacteristics |
DYNAMIC_BASE bayrağı (ve pratikte relocation verisi/Reloc Directory) |
| DEP / NX | Optional Header → DllCharacteristics |
NX_COMPAT bayrağı (+ bölüm izinleri: RX/RW; RWX risk sinyali) |
| CFG |
Optional Header → DllCharacteristicsData Directories → Load Config
|
GUARD_CF bayrağı + Load Config altında Guard/CFG ile ilişkili alanlar |
| SEH |
(x64) Data Directories → Exception Directory(x86) (Mitigation olarak) Data Directories → Load Config (SafeSEH izleri)
|
x64’te unwind/exception tabloları (.pdata/.xdata gibi).x86’ta SafeSEH için Load Config içindeki handler table alanları (varsa). |
ASLR/DEP/CFG bayrakları çoğu zaman Optional Header → DllCharacteristics içinde görülür.
CFG ve SEH tarafında ise Load Config ve Exception Directory gibi “dizinler” devreye girer.
PE içindeki bu ayarları nasıl görüntülersin?
En pratik yol, bir PE inceleme aracıyla “Optional Header” ve “Data Directories” alanlarına bakmak. Benim önerdiğim akış şu:
- PE-bear veya CFF Explorer aç → Optional Header →
DllCharacteristicsalanına bak. - Data Directories bölümünde Load Config ve (x64 için) Exception girişleri var mı kontrol et.
- CLI seviyorsan: Visual Studio araçlarıyla
dumpbin /headersçıktısı da iş görür.
“Bu binary taşınabilir mi?” (ASLR/reloc)
“Veri çalıştırılabilir mi?” (DEP/NX + section izinleri)
“Dolaylı çağrılar korunuyor mu?” (CFG + Load Config)
“Exception/unwind bilgileri nasıl?” (özellikle x64)
SSS (Sık Sorulan Sorular)
1) ASLR/DEP/CFG açık olması “güvenli” demek mi?
Hayır. Bu özellikler güvenliği katman katman güçlendirir ama tek başına “garanti” vermez. Kod kalitesi, güncellemeler, üçüncü parti bağımlılıklar ve daha birçok faktör var.
2) SEH bir güvenlik özelliği mi?
SEH esasen bir hata/istisna yönetim mekanizması. Güvenlikle ilişkisi, exception akışının kötüye kullanıldığı tarihsel senaryolar ve buna karşı alınan önlemler üzerinden gelir.
3) CFG’yi sadece bir bayrakla mı anlarsın?
Bayrak (GUARD_CF) iyi bir işaret ama CFG’nin “tam resmi” çoğunlukla Load Config tarafındaki verilere de bakmayı gerektirir.
4) Neden bazı binary’lerde “reloc” yok?
Bazı derleme/bağlama ayarları relocation verisini kırpabilir. Bu, taşınabilirliği azaltabilir. Modern pratikte ASLR için relocation’ın anlamlı olması beklenir.
Kaynaklar / İleri Okuma
- Microsoft Learn — PE Format (PE/COFF) dokümantasyonu
- Microsoft Learn — IMAGE_OPTIONAL_HEADER (DllCharacteristics dahil)
- Microsoft Learn — /DYNAMICBASE (ASLR)
- Microsoft Learn — /NXCOMPAT (DEP/NX uyumluluğu)
- Microsoft Learn — /GUARD:CF (Control Flow Guard)
- Microsoft Learn — Structured Exception Handling (SEH)
- Microsoft Learn — /SAFESEH (x86 SafeSEH)
- Microsoft Learn — IMAGE_LOAD_CONFIG_DIRECTORY (CFG/SafeSEH gibi verilerin yapısı)