Ne zaman "Assembly günümüzde işe yaramaz" cümlesini duysam, hep aynı şeyi düşünürüm: O zaman muhtemelen hiçbir zaman bir binary dosyasının içine girip neden çöktüğünü bulmak zorunda kalmamışsınızdır. Üst düzey dillerle çalışırken bu katman çoğunlukla görünmezdir—ancak bir şeyler ters gittiğinde, tek gerçek kanıt tam orada durur.
Kaynak Kodu Olmadığında Ne Yaparsınız?
Elinizde sadece derlenmiş bir binary olduğunu düşünün—kaynak kodu yok, dokümantasyon yok, hatta tersine mühendisliği zorlaştırmak için biraz karartma (obfuscation) bile yapılmış olabilir. O noktada işlemcinin gördüğü tek şey assembly komutlarıdır. Bir fonksiyonun ne yaptığını anlamak istiyorsanız, yazmaçların nasıl kullanıldığını, yığının (stack) nasıl büyüyüp küçüldüğünü ve hangi bayrakların (flags) ayarlandığını okumak zorundasınız.
Bu beceri sadece "eski usul" bir merak değildir; bugün hâlâ ciddi pratik değeri vardır. Kapalı kaynaklı bir kütüphanede bir hata (bug) arıyorsanız, bir zararlı yazılımın ne yaptığını anlamaya çalışıyorsanız veya bir lisans kontrol mekanizmasının nasıl çalıştığını inceliyorsanız, tek yol budur.
Yama Yapmak (Patching): Küçük Bir Değişiklik, Büyük Bir Etki
Binary yamalama genellikle göründüğünden çok daha küçük bir müdahaledir. Önceki yazımda bahsettiğim JNZ / JZ örneğini hatırlayın: Tek bir baytı değiştirerek, bir programın akışını tersine çevirebilirsiniz. Bu hem ofansif hem de defansif olarak kullanılabilecek bir güçtür.
; Original check — jump if condition not met
CMP EAX, 0
JNZ fail_label
; After patch — invert the condition
CMP EAX, 0
JZ fail_labelDefansif tarafta, bu bilgi, bir yazılımın tam olarak hangi noktalarının manipülasyona açık olduğunu görmenizi sağlar. Kaynak kodu seviyesinde "güvenli görünen" bir kontrol bırakmak yeterli değildir; derlendikten sonra hâlâ aynı garantiyi sağlayıp sağlamadığını test etmeniz gerekir.
Güvenlik Açığı Avcılığında Assembly‘nin Rolü
Fuzzing araçları bir çökme bulduğunda, size sadece "burada bir şeyler patladı" der. Asıl iş, çökmenin tam olarak neden gerçekleştiğini anlamaktır. Stack overflow mu oldu? Integer overflow mu yaşandı? Yoksa bir use-after-free mi tetiklendi? Cevap neredeyse her zaman assembly seviyesinde gizlidir. Bir disassembler'da çökme anındaki yazmaç durumunu ve stack frame'ini inceleyerek, "Bu güvenlik açığı gerçekten sömürülebilir (exploitable) mi?" sorusuna cevap verebilirsiniz.
Sonuç Yerine
Assembly öğrenmek size her gün kullandığınız bir beceri kazandırmayabilir, ancak buna sahip olduğunuzda, herkesin "çözülemez" dediği bir sorunu çözme şansınız olur. Bence bu yapılmaya değer bir yatırımdır.