APK Reverse Engineering Nasıl Yapılır?
Yayımladığınız Kod Aslında Ne Kadar Gizli?
Play Store'a bir uygulama yüklediniz. Kodunuz derlendi, paketlendi ve dağıtıldı. Artık güvende, değil mi?
Maalesef bu kadar basit değil. APK dosyaları belirli araçlarla analiz edilebilir ve içindeki bilgilerin büyük bölümü geri elde edilebilir. Bu gerçeği anlamak — hem nasıl yapıldığını hem de neden önemli olduğunu — bir Android geliştiricisi için kritik bilgidir.
Neden Tersine Mühendislik Mümkün?
APK'nın içinde Kotlin ya da Java kaynak kodunuz değil, DEX bytecode'u vardır. DEX, makine kodundan çok daha yüksek seviyeli bir formattır. Kaynak kodun çoğu yapısal bilgisini — sınıf isimleri, metot imzaları, mantık akışı — korur.
Bu yapısal zenginlik DEX'i tersine mühendislik açısından son derece verimli kılar. Makine kodunu tersine mühendislemek son derece zordur çünkü üst seviye yapı kaybolmuştur. DEX'i tersine mühendislemek ise çok daha kolaydır çünkü yapı neredeyse bozulmadan korunur.
Bu temel gerçeği kabul etmek her şeyin başlangıcıdır: APK'daki kod tamamen gizli değildir.
Adım Adım: APK Nasıl Analiz Edilir?
Tersine mühendislik süreci birkaç aşamadan oluşur ve her aşama farklı araçlar kullanır.
İlk adım APK'yı açmaktır. APK bir ZIP arşivi olduğundan herhangi bir ZIP aracıyla açılabilir. İçindeki classes.dex, resources.arsc, AndroidManifest.xml ve diğer dosyalar görünür hale gelir. Manifest dosyası binary formattadır ama apktool ile insan okunabilir XML'e dönüştürülebilir. Bu sayede uygulamanın hangi izinleri istediği, hangi Activity'lerin tanımlı olduğu, hangi deep link'lerin desteklendiği açıkça görülür.
İkinci adım DEX'i Java'ya dönüştürmektir. classes.dex dosyası dex2jar aracıyla standart Java bytecode'una (classes.jar) dönüştürülür. Bu jar dosyası herhangi bir Java decompiler ile açılabilir. JD-GUI, Jadx gibi araçlar bu bytecode'u Java kaynak koduna son derece yakın bir forma dönüştürür.
Sonuç şaşırtıcı derecede okunabilirdir. Sınıf isimleri, metot isimleri, iş mantığı, API çağrıları, sabit değerler — bunların büyük bölümü görünür hale gelir. Obfuscation uygulanmamışsa kod neredeyse orijinal haliyle karşınızdadır.
Üçüncü adım kaynakları analiz etmektir. Apktool tüm kaynakları — layout XML'leri, string değerleri, görseller, raw dosyalar — orijinal yapısına yakın biçimde yeniden oluşturur. Uygulamanın UI yapısı, tüm metin içerikleri, yapılandırma dosyaları bu aşamada görünür olur.
Dördüncü adım statik analizdir. Elde edilen kod ve kaynaklar incelenerek uygulamanın nasıl çalıştığı anlaşılmaya çalışılır. API endpoint'leri, şifreleme anahtarları, authentication mantığı, gizli özellikler — bunlar kaynak kodda aranan başlıca bilgilerdir.
Ne Bulunabilir?
Tersine mühendislikle elde edilebilecekler listelendiğinde tablo endişe verici hale gelir.
Hardcoded değerler en kolay bulunan bilgilerdir. Kaynak koduna gömülmüş API anahtarları, şifreleme anahtarları, veritabanı şifreleri, özel endpoint URL'leri — bunlar string arama ile dakikalar içinde bulunabilir.
API yapısı uygulamanın tüm endpoint'lerini, istek formatlarını ve yanıt yapılarını ortaya koyar. Yetkisiz API çağrıları yapmak, rate limit'leri tespit etmek, gizli tutulmak istenen endpoint'leri keşfetmek bu bilgiyle mümkün olur.
İş mantığı özellikle obfuscation uygulanmamışsa büyük ölçüde geri elde edilebilir. Ödeme doğrulama mantığı, lisans kontrolleri, A/B test koşulları, gizli özellik bayrakları — bunların tamamı kaynak kodda yaşar.
Sertifika sabitleme (certificate pinning) detayları tersine mühendislikle ortaya çıkarılırsa bu koruma bypass edilebilir. Hangi sertifikanın kontrol edildiği bilinirse özel bir proxy kurularak bu kontrol atlatılabilir.
Dinamik Analiz: Çalışırken İzlemek
Statik analizin ötesinde dinamik analiz de mümkündür. Bu yaklaşımda uygulama emülatörde ya da gerçek cihazda çalıştırılırken izlenir.
Frida bu alandaki en güçlü araçtır. Çalışan bir uygulamaya JavaScript kodu enjekte ederek metot çağrılarını izlemenizi, dönüş değerlerini değiştirmenizi ve uygulama davranışını gerçek zamanlı manipüle etmenizi sağlar. Sertifika sabitlemeyi bypass etmek, şifreleme fonksiyonlarının çıktısını okumak, root tespitini devre dışı bırakmak — bunlar Frida ile birkaç satır kodla yapılabilir.
MITM (Man in the Middle) proxy'leri uygulamanın ağ trafiğini yakalar. Charles Proxy ya da Burp Suite cihazla sunucu arasına girerek tüm HTTP/HTTPS trafiğini görünür kılar. Sertifika sabitleme yoksa bu son derece kolaydır.
Bu Bilgi Neden Önemli?
Tersine mühendisliği yalnızca saldırganlar kullanmaz. Güvenlik araştırmacıları uygulamalardaki açıkları bulmak için kullanır. Rakip analizi yapmak için kullanılır. Kendi uygulamanızın ne kadar korunduğunu test etmek için kullanılır.
Bir geliştirici olarak bu bilgiden çıkarılacak pratik sonuç şudur: APK'nın içindeki her şeyin bir gün görüleceğini varsayarak kod yazın.
Geliştirici Perspektifinden Bakış
Güvenlik mimarinizi "kod görülmeyecek" varsayımı üzerine kurmayın. Bu varsayım her zaman yanlış çıkar.
Hassas iş mantığını sunucu tarafına taşıyın. API anahtarlarını ve şifreleri kaynak koduna gömmek yerine sunucu üzerinden dağıtın ya da güvenli depolama mekanizmalarını kullanın. Android Keystore sistemi, şifreleme anahtarlarını donanım düzeyinde saklamak için tasarlanmıştır.
Obfuscation uygulayın ama tek güvenlik katmanı olarak görmeyin. R8'in obfuscation özelliği tersine mühendisliği zorlaştırır ama imkânsız kılmaz. Anlamlı isimler anlamsız hale gelir ama mantık akışı görünür olmaya devam eder.
Ve kendi uygulamanızı zaman zaman kendiniz analiz edin. APK'nızı indirip Jadx ile açmak, dışarıdan ne göründüğünü kendi gözlerinizle görmenin en etkili yoludur.
Serinin bir sonraki yazısında uygulamaları bu tehditlerden nasıl koruyacağımızı inceleyeceğiz.