Başlangıç > Diğerleri > Kod güvenliği

Kod güvenliği

.NET’te kod güvenliği ile ilgili Microsoft Develors Network’un bir makalesini buldum,duzenleme yaptım ve huzurunuza sunuyorum. sonuna kadr okuyan sayısı az olsa da 🙂 )


       .NET mimarisinin bizlere sunduğu avantajlardan biri, ILDASM (intermediate language disassembler) ile edinebileceğimiz pek çok faydalı bilgiyi barındıran assembly’lerdir. Bu bizim için bir avantaj olsa da, binary dosyalarınıza ulaşan biri, assembly’lerdeki bilgileri kullanarak orijinal kodlarınıza (neredeyse tamamına) ulaşabilir. Bu noktada reverse-engineering işlemlerinin önüne geçmek için, kaynak kodu reverse engineering ile okunduğunda anlamsız olarak görüntüleyen obfuscation metodu geliştirildi. Bu makalede, uygulamalarımızın kodlarını, reverse-engineering’e karşı korumak için kullanabileceğimiz etkili bir metot olan obfuscating’i ve .NET ortamında uygulanmasını ele alıyor olacağız.

Şu ana kadar muhtemelen Microsof .NET Framework mimarisinde yer alan zengin metadata’nın, uygulamaların dağıtımı ve versiyonlanmasından, kendisi ile ilgili bilgiler içeren binary dosyalar ile sağlanan zengin IDE fonksiyonelliğine kadar pek çok alanda sunduğu faydalara tanık olmuşsunuzdur. Bunca avantajına karşın, metadata şu ana kadar uygulama geliştiriciler açısından ciddi bir risk oluşturmayan bir riskin üzerinde daha fazla durulması gereğini ortaya çıkarttı. Managed kod ile yazılan uygulamalar, kolayca reverse-engineering işlemine tabi tutulabilmekte. Bu .NET Framework’un tasarımından kaynaklanan bir hata olarak algılanabilecek olsa da, aslında modern, intermediate-compiled dillerin (java gibi) bir gerçeğidir. Hem Java hem de .NET Framework metadata bilgilerinin (.NET Framework’te MSIL (Microsoft Intermediate Language), Java’da ise bytecode) executable kodun içine embed edilmesi yöntemini kullanmakadır. Makina kodundan daha yüksek seviyede olmasından dolayı, executable dosyalar kolayca deşifre edilebilecek pek çok bilgi ile yüklüdür. ILDASM (.NET Framework SDK ile birlikte gelen MSIL disassembler) ve benzeri araçlar veya Anakrino veya Reflector for .NET benzeri decompiler uygulamaları ile assembly’lerinizin içeriği kolayca incelenebilir ve yeniden okunabilir / kullanılabilir kaynak koda kolayca dönüştürülebilir. Kötü niyetli kullanıcılar uygulamanızdaki güvenlik sorunlarını keşfederek bunlardan faydalanabilir, özgün fikirlerinizi kullanabilir ve lisanslama kodunuzu bypass edebilirler. Sanırım bu kadar olasılık, bu konuda nasıl önlem alabileceğinizi düşünmenizi sağlamak için yeterli olacaktır 🙂

Bu aşamada bu tür reverse-engineering uygulamalarına karşı kodlarımızı korumak için uygulanması son derece basit olan obfuscation metodunu ele alacağız. Obfuscation, assembly’lerimiz üzerinde reverse-engineering işlemlerinin uygulanmasını engellemiyor. Ancak assembly’lerimizin içerdiği sembolleri reverse-engineering sonrasında anlamsız (hatta son derece anlamsız) bir çıktı oluşmasını sağlayacak şekilde (tabi uygulamamızın çalışmasını etkileyemeyecek şekilde) rename ediyor. Aslında bu yöntem, Java platformunda geliştirilen ürünlerin korunmasında uzun zamandır kullanılmaktadır.

Pek çok firma, .NET için 3. parti obfuscation araçları geliştirerek yayınlamış durumda. Microsoft’ta Visual Studio 2003 ile birlikte, PreEmptive Solutions firmasına ait Dotfuscator uygulamasının Community Edition versiyonunu uygulama geliştiricilerin kullanımına sunmaktadır.

Makalenin geri kalan bölümünde, obfuscation konusunu, kullanılabilecek obfuscation metodlarını ve bir obfuscator ile çalışırken karşılaşabileceğimiz senaryoları çok detaylı olarak ele alacağız.
Decompilation ve obfuscation işlemlerini örnekleyebilmek için makale boyunca Vexed oyununun Roey Ben-amotz tarafından geliştirilmiş olan .NET implementasyonunu kullanıyor olacağız. Bir puzzle oyunu olan Vexed.NET ve kaynak kodları http://vexeddotnet.benamotz.com adresinden download edilebilmekte. Aşağıda Vexed.NET’in kaynak kodlarından aldığım bir metod yer alıyor.

Şekil 1:1 :: Vexed.NET oyunundan bir görüntü..

public void undo() {
if (numOfMoves>0) {
numOfMoves–;
if (_UserMoves.Length>=2)
_UserMoves = _UserMoves.Substring(0, _UserMoves.Length02);
this.loadBoard(this.moveHistory[numOfMmoves –
(numOfMoves/50) * 50]);
this.drawBoard(this.gr);
}
}

Disassembly

.NET Framework SDK, .NET Framework assembly’lerini IL assembly ifadelerine dönüştürmenizi (decompile etmenizi) sağlayan ILDASM adlı bir disassembler aracı içermektedir. ILDASM aracını çalıştırmak için .NET Framework SDK’nın kurulu olduğundan emin olmanız gerekmektedir. .NET Framework komut satırına ILDASM ve sonrasında disassemble etmek istediğiniz uygulamanın adını yazmanız yeterlidir. Örneğimizde komut satırına “ILDASM vexed.net.exe” yazarak ILDASM uygulamasını çalıştıracağız. Şekil 1:2, undo metodunun disassemble edilmiş halini göstermektedir.

Şekil 1:2 :: Undo metodunun dissassemble edilmiş hali

Decompilation

Eğer bu aşamada sadece çok az sayıda kişinin IL Assembly dilini bildiğini ve bu kodu yorumlayarak sizin kaynak kodunuzu anlayabileceğinizi düşünüyorsanız üzülerek decompilation’ın bu noktada durmadığını söylemem gerekiyor. Bir decompiler aracılığıyla sizin yazdığınız kodları aynen yeniden oluşturabiliriz. Bu tür decompiler uygulamaları binary .NET Assembly’lerini doğrudan C#, Visual Basic.NET veya C++ gibi yüksek seviyeli bir dile çevirebilmektedir. .NET Reflector aracını kullanarak bunu örnekleyelim;


Örnek 1:1 :: .NET Reflector Çalıştırılır


Örnek 1:2 :: Vexed.NET Uygulamasının .exe dosyası açılır


Örnek 1:3 :: Açılan assembly’i sağ tuşla tıklayıp, Disassembler komutunu tıklıyoruz.


Örnek 1:4 :: undo metodunu seçiyoruz ve C# olarak orjinal kodu görebiliyoruz.. Hatta;


Örnek 1:5 :: Tek dil alternatifimizin C# olmadığını da görüyoruz..

Sonuç olarak reverse-engineering işlemimizin sonucunda ortaya aşağıdaki kod çıkıyor ve orjinal kodla karşılaştırdığımızda birebir aynı sayılabileceğini görüyoruz..

public void undo()
{
if (this.numOfMoves > 0)
{
this.numOfMoves–;
if (this._UserMoves.Length >= 2)
{
this._UserMoves = this._UserMoves.Substring(0, this._UserMoves.Length – 2);
}
this.loadBoard(this.moveHistory[this.numOfMoves – ((this.numOfMoves / 50) * 50)]);
this.drawBoard(this.gr);
}
}

Ortaya çıkan bu sonuca ileride geri dönerek yeniden inceleyeceğiz..

Enine Boyna Obfuscation

Obfuscation birbiri ile ilgili pek çok teknoloji kullanılarak ortaya çıkarılmıştır. Temel hedefi, uygulamanın çalışmasını (hiç) etkilemeden kodlarını gizlemektir. Obfuscation’ı şifreleme ile bir tutamayız. .NET Assembly’lerini şifreleyerek tamamen okunamaz hale getirebiliriz ancak runtime, şifrelenmemiş kodu çalıştırmak zorunda olduğundan dolayı decryption anahtarı şifrelenmiş programda tutulmak durumundadır ve bu yöntemde uygulamayı decrypt etmekte kullanılacak anahtarı şifrelenmiş koddan ayırt edecek, kodu decrypt edecek ve IL kodunu diske yazacak, dolayısıyla kodu decompilation’a tamamen açık bırakacak bir uygulama kolayca geliştirilebilir.


Şekil 1:3 :: Konu mankenimiz: İskender

Şifrelemeyi yukarıdaki iskender tabağını kilitli bir kutuya saklamaya benzetebiliriz. Kutunun anahtarı sadece iskender’in sahibinde (yani CLR) mevcut ve biz kutunun içinde ne olduğunu, bu arkadaşın dışında hiç kimsenin bilmesini istemiyoruz. Ancak malesef yemek zamanı geldiğinde bu güzel iskender tabağı kilitli kutudan çıkarak masadaki yerini alacak ve meraklı gözlere karşı korunmasız olacak. Obfuscation’ı ise iskender tabağını Şekil 1:4’te gördüğünüz blenderdan geçirerek masaya plastik bir tabak içinde getirmeye benzetebiliriz. Tabakta taşıdığımız “şeyi” herkesin göreceği kesin ancak tabağın içindeki şeyin aslında ne olduğunu kimse bilemeyecek/anlayamayacak. Yemek plastik tabağın içinde sahibine ulaştığında hala ilk halindeki (Şekil 1:3) gıda değerini korumakta (ve şans bu ki, CLR lezzet açısından çok seçici değil). Obfuscation, CLR’a aynı kaynağı aktarırken, meraklı gözleri yanıltmaktan başka bir şey değildir.


Şekil 1:4 :: Blender

Elbette Obfuscation veya şifreleme için de, diğer yöntemler gibi %100 güvenilirdir diyemeyiz. Eğer compile edilmiş C++ disassemble edilebilirse,hacker yeterince inatçı ve sabırlıysa, kodunuzu yeniden oluşturabilir.


Şekil 1:5 :: Obfuscation Süreci

Obfuscation, kaynak koda değil, compile edilmiş .NET assemblylerine uygulanan bir metoddur. Obfuscation araçları sizin kaynak kodlarınızı asla okumaz, değiştirmez. Şekil 1:5 obfuscation sürecinin akışını göstermektedir. Obfuscation aracının çıktısı, bir başka assembly setidir ancak kaynak ve çıktı assemblyları işlevsel/fonksiyonel açıdan birbirinin aynısı olacaktır. Şimdi Dotfuscator Community Edition’ın bu hedef için kullandığı iki tekniği inceleyeceğiz: yeniden adlandırma ve gereksiz metadata’nın silinmesi.

Metadata’nın Yeniden Adlandırılması

Obfuscation’ın ilk adımı, anlamlı isimlerin anlamsız isimler halinde yeniden adlandırılmasıdır. Bildiğiniz gibi belirlenmiş isimlerde pek çok değer yer alır ve kodunuzun kendisini açıklamasını sağlar. CLR bir ismin ne kadar açıklayıcı olduğuyla ilgilenmez dolayısıyla obfuscation uygulamaları bu isimleri değiştirdiklerinde ortaya herhangi bir sorun çıkmamaktadır.
Obfuscation uygulamalarının assembly üzerinde yapacağı yeniden adlandırmalarda belirli kısıtlamalar vardır. Üç genel obfuscation senaryosu mevcuttur.

Eğer uygulamamız bir veya daha fazla sayıda standalone (herhangi bir onfuscationdan geçirilmemiş kod bu assemblyleri kullanmıyorsa) assemblyden oluşuyorsa, obfuscator assembly üzerinde, isimler ve referanslar tutarlı olmak kaydıyla serbestçe yeniden adlandırma yapabilir. Eğer uygulamanız obfuscate edilmemiş kod tarafından kullanılacaksa, obfuscation aracı uygulamanızdaki türlerin veya istemciler tarafından kullanılacak üyelerin isimlerini değiştiremez. Bu tür uygulamalara shared class library’leri, yeniden kullanılabilir bileşenleri v.b. uygulamaları verebiliriz.

Dotfuscator Community Edition “overload induction” adı verilen bir yeniden adlandırma metodu kullanmaktadır. Metod tanımlayıcıları detaylı kapsam analizinden sonra en yüksek seviyede overload edilmektedir. Her bir eski isim yerine yeni bir isim eklemek yenide, “overload induction” tekniği mümkün olduğunca fazla metodu aynı şekilde isimlendirmektedir. Böylece decompile edilmiş kodu okuyanlar kodu yorumlamakta zorlanmaktadırlar.

Ek olarak hoş bir yan etki olarak uygulamanın boyutu, assemblynin daha az miktarda string veri içermesinden dolayı daha da küçülmektedir. Örneğin 20 karakter uzunluğunda bir isim kullanıyorsanız bu ismi “a” olarak yeniden adlandırmak 19 karakterlik kazanım anlamına gelmektedir. Ek olarak isimleri sürekli olarak yeniden kullanmak string heap kayıtlarını azaltarak yer kazanımı sağlamaktadır. Herşeyin “a” olarak yeniden adlandırılması “a” isminin bir defa kaydedilmesi ve “a” olarak adlandırılan her metodun veya alanın aynı kayıdı kullanması anlamına gelmektedir. Overload induction en kısa identifierların sürekli olarak yeniden kullandığından dolayı bu etkiyi oldukça arttırmaktadır.

Yeniden adlandırma sürecinden sonra Undo metodumuzun aldığı görünüm aşağıdaki gibi olmaktadır.

public void c() {
if (this.p > 0) {
this.p = this.p – 1;
if (this.r.Length >= 2)
this.r = this.r.Substring(0, this.r.Length – 2);
this.a(this.q[this.p – this.p / 50 * 50]);
this.a(this.e);
}
}

Görebileceğiniz gibi farklı herhangi bir obfuscation uygulanmadan metodu yeterince anlaşılmaz hale getirebildik.

Gereksiz Metadata’nın Kaldırılması

Compile edilen bir .NET uygulamasındaki metadata’nın tamamı runtime tarafından kullanılmaz. Bu metadata’nın bir kısmı farklı bazı araçların, (tasarım araçları, debuggerlar v.b.) kullanımı için mevcuttur. Örneğin bir C# projesinde “Size” adlı bir property tanımlarsanız, derleyici “Size” adlı property için metadatayı kaydedecek ve bu ismi get ve set işlemlerini (“get_Size” ve “set_Size”) yapan metodlarla ilişkilendirecektir. Size özelliğini belirleyen bir kod yazdığınız zaman derleyici “set_Size” metoduna bir çağrı oluşturacak ve hiç bir zaman özelliği kendi ismi ile kullanmayacaktır. Gerçekte özelliğin ismi sadece IDE ve uygulama geliştiriciler içindir, CLR tarafından asla kullanılmaz.

Eğer uygulamanız sadece runtime tarafından kullanılacaksa (diğer araçlar tarafından kullanılmayacaksa) obfuscation aracının bu tür metadatayı silmesinde herhangi bir sakınca yoktur. Özellik isimlerine ek olarak event isimler ve metod parametre isimleri de bu kategoriye girmektedir. Dotfuscator Community Edition bu tür metadata verilerini kaldırmanın güvenli olacağını öngördüğü durumlarda kaldırmaktadır.

Ek Obfuscation Tenikleri

Dotfuscator Community Edition yukarıda saydığımız teknikleri sunmaktadır ancak daha yüksek güvenlik için kullanılabilecek bazı obfuscation teknikleri de mevcuttur. Bu bölümde açıklayacağım flow obfuscation, string encryption, incremental obfuscation ve size reduction teknikleri Dotfuscator Professional Edition tarafından sunulmaktadır. Control flow, mantığı değiştirmeden bir komut dizisini amacını gizlemeyi hedefleyen güçlü bir obfuscation metodudur. Control Flow Obfuscation’ın daha önemli bir özelliği ise decompilerlar tarafından yüksek seviye kodları oluşturmak için kullanılan ipuçlarının (döngüler ve if blokları gibi) kaldırılmasında kullanılmaktadır.

Control Flow’u uygulamada görmek için aşağıdaki renaming ve control flow obfuscatin uygulanmış undo metoduna bakın;

public void c() {
if (this.o > 0) {
goto i0;
do {
while (true) {
this.a(this.p[this.o – this.o / 50 * 50]);
this.a(this.d);
goto i1;
i2: this.q = this.q.Substring(0, this.q.Length – 2);
}
i0: this.o = this.o – 1;
} while (this.q.Length < 2);
goto i2;
}
}

Orijinal if blokları yerine decompiler’ın bir if bloğu, iki while döngüsü ve bunları bir araya getirmek için bazı goto ifadeleri oluşturduğunu görüyoruz. i1 adlı lael refere edildi ancak decompiler tarafından oluşturulmadı.

String Encryption uygulamanın içinde yer alan string bölümler üzerinde basit bir şifreleme algoritması uygulayan bir tekniktir. Daha önce belirttiğim gibi runtime esnasında yapılacak şifreleme doğal olarak güvensizdir. Zeki bir hacker kolaylıkla şifreleme algoritmasını kırabilir ancak dolayısıyla bu bir zaman kaybı olarak görülebilir ancak sadece uygulamanın içindeki string bölümler için şifreleme, alınması gereken bir önlemdir. Neden? Eğer bir hacker uygulamanızın kodlarını incelemeye başladığında işe yeniden adlandırılmış türleri arayarak başlamaz. Genellikle “Invalid License Key” ve benzeri doğrudan lisanslama işlemlerinin yapıldığı blokları arayarak işe başlar. Stringler üzerinde arama yapmak son derece kolaydır ve string encryption compile edilmiş kodda sadece şifrelenmiş string verilerini saklayarak bunu engellemek için güçlü bir önlem oluşturur.

Incremental Obfuscation , obfuscation koşulları altında bir müşterinin sorununa yönelik yamalar uygulamaktaki zorluklar karşısında yardımcı olmaktadır. Kodlardaki bugların düzeltilmesi sırasında yeni sınıflar, metodlar veya alanlar oluşturulur, mevcut olanlar silinir. Kodun değiştirilmesi (örneğin bir metodun eklenmesi veya silinmesi) sonradan uygulanacak obfuscationın isimleri daha farklı olarak yeniden adlandırmasına neden olabilir. Önceden “a” olarak adlandırılan bir yapı “b” olarak adlandırılabilir. Malesef neyin nasıl yeniden adlandırıldığını bilememekteyiz. Incremental Obfuscation bu sorun karşısında yardımcı olmaktadır. Dotfuscator yeniden adlandırmayı ne şekilde uyguladığına dair bir map dosyası oluşturmaktadır. Aynı map dosyası, güncellemelerden sonra uygulanacak obfuscationlarda önceden kullanılan isimlendirmelerin mümkün olduğu noktalarda değiştirilmeden aynı şekilde kullanılmasını sağlamak için bir input dosyası olarak kullanılabilmektedir. Uygulamanız için belirli sınıflarda yenilikler getiren bir güncelleme yayınladığınız zaman Dotfuscator önceden kullanılan isimlendirme şemasına göre sadece güncel sınıfları obfuscationdan geçirebilmektedir.

Size reduction doğrudan reverse-engineering’i önleyici bir metod değildir ancak obfuscation araçlarının her zaman için input assemblylerine bir bağımlılık analizi uygulamaları gerektiği için önem taşımaktadır. Böylece obfuscation aracı obfuscation işleminin yanı sıra, uygulamanızda bulunan ancak kullanılmayan kodları da temizlemektedir. Kullanılmayan kodların temizlenmesi gereksiz gibi görünebilir. Sonuçta kim kullanmayacağı kodları uygulamasına ekler ki? Aslında bu sorunun cevabı: “hepimiz”. Hepimiz uygulamalarımızda başka kişiler tarafından yazılmış olan yeniden kullanılabilir kütüphaneleri ve türleri kullanıyoruz.

Yeniden kullanılabilir kod pek çok durumu handle eden bir kod grubu anlamına gelmektedir ve çoğu durumda uygulamalar bu kod grubunun belirli bir kaç koşulunu / bölümünü kullanırlar. Gelişmiş bir obfuscation aracı kullanılan ve kullanılmayan kod bloklarını ayırt ederek kullanılmayan bölümleri uygulamadan kaldırabilir (compile edilmiş assemblyden, kaynak koddan değil). Sonuç olarak geriye sadece uygulamanızın gerçekten ihtiyaç duyduğu tür ve metodlardan başka bir şey kalmaz. Küçük boyutlu uygulamaların daha az kaynak kullanımı, daha kısa yükleme süreleri gibi pek çok avantajı vardır. Bu özellikle .NET Compact Framework’te çalışan veya distributed uygulamalar için son derece önemli olabilecek bir özelliktir.

Dotfuscator Community Edition’ın Kullanımı

Obfuscation üzerinde bu kadar durduktan sonra uygulanmasına dair bir örnek yapalım. Şimdi Vexed.NET uygulamasına adım adım obfuscation uygulayacağız. Dotfuscator Community Edition, her bir uygulama için kullanılacak obfucation seçeneklerini tanımlayan bir konfigurasyon dosyası kullanır. Dotfuscator aynı zamanda kullanılacak konfigurasyon dosyasını oluşturmak ve düzenlemek için bir görsel arabirim sunar. Dotfuscator Community Edition aynı zamanda otomtize edilmiş build proseslerine entegre edilmek üzere bir komut satırı arabirimi sunar. Bahsettiğim görsel arabirimi Visual Studio 2003’ün Tools menüsünden çalıştırabilirsiniz.

Vexed obfuscation uygulaması için Dotfuscator arayüzünde üç işlem gerçekleştirmemiz gerekiyor: obfuscation uygulanacak assemblynin seçilmesi, map file lokasyonunun belirtilmesi, output dizininin belirtilmesi. Dotfuscator obfuscation uygulanacak assemblyleri trigger assemblyleri olarak adlandırmaktadır ve Trigger sekmesinden seçilirler. Bu sekmeden istediğimiz kadar assembly dosyası ekleyebilsekte bu uygulamada sadece Vexed.NET uygulamasını seçeceğiz.


Şekil 1:6 :: Map Dosyasının lokasyonunun belirtilmesi

Map dosyasının lokasyonunu Rename sekmesinin Options alt sekmesinden (Şekil 1:6) seçiyoruz. Map dosyası, orjinal ve obfuscation uygulanmamış isimler arasındaki eşleştirmelere dair bilgileri içeren önemli bir dosyadır. Bu dosyayı obfuscation uygulamasından sonra saklamamız bizim için son derece önemlidir. Bu dosyayı kaybetmemiz halinde, obfuscation uyguladığımız uygulama üzerinde çalışmamız son derece zor olacaktır. Bu nedenden dolayı Dotfuscator siz “Overwrite Map File” seçeneğini seçmediğiniz sürece önceden oluşturulmul bir map dosyasının üzerine yazmayacaktır.

Son olarak Build sekmesi obfuscation uygulanmış dosyasının kaydedileceği dizini belirteceğimiz alandır. Bu adımı da tamamladıktan sonra obfuscation uygulamasını başlatabiliriz. Bu noktada konfigurasyon dosyasını daha sonradan kullanmak üzere kaydedebilir veya doğrudan “Build” butonunu tıklayabilir veya alternatif olarak toolbarda yer alan “Play” butonunu tıklayabiliriz. Build sürecinde görüntülenecek bilgilerin miktarını Options sekmesinden Quiet veya Verbose seçenekleri ile belirleyebiliyoruz.

Build işlemi tamamlandıktan sonra sonuçları şekil 1:7’de görebildiğimiz gibi Output sekmesinden görüntüleyebiliriz. Görebildiğiniz gibi Dotfuscator Object Browser benzeri bir arayüz ile uygulamaya ait detayları görüntülemektedir. Yeni isimler orjinal isimlerin hemen altındadır. Grafikte board adlı sınıfın h olarak, init ve ToImage signaturelarına sahip iki metodun ise a olarak yeniden adlandırıldığını görebiliyoruz.

Map Dosyasını İnceliyoruz

Dotfuscator tarafından oluşturulan Map dosyası XML formatında kaydedilmiştir ve yeniden adlandırma prosesine dair bazı istatistikleri içermektedir. Aşağıdaki tablo Vexed uygulamasında yapılan yeniden adlandırmalara dair oluşan istatistikleri içermektedir.

Map dosyaları aynı zamanda incremental obfuscation yapmak için kullanılır. Bu proses önceden yapılmış bir obfuscationa ait isimleri import ederek obfuscation uygulamasına yeniden adlandırmaları önceden yapılan yeniden adlandırmalara bağlı kalarak yapması için gerekli bilgileri sağlamakta kullanılır. Eğer önceden obfuscation uygulanmış bir uygulamaya yönelik bir patch veya plug-in yayınlıyorsak, güncellemelere de orjinal uygulamadaki şekilde obfuscation uygulayabiliriz.

Obfuscation’ın Riskleri

Obfuscation, özellikle yeniden adlandırma, gelişmiş uygulamalarda oldukça dikkatli olmayı gerektirmektedir. Yeterince dikkatli olunmaması halinde uygulamanın çalışmamasına neden olabilir. Bu bölümde obfuscation uygulamalarının kullanımı sırasında karşılaşılabilecek genel problemleri ele alıyor olacağız.

İlk olarak uygulamamızın bir strongly named assembly içeriyor olması durumunda bazı ek işlemler yapmamız gerekecektir. Strongly named assemblyler runtime’ın assembly üzerinde değişiklik yapılıp yapılmadığını anlayabilmesini sağlayabilmek için dijital olarak imzalanmıştır. Signature RSA public/private key pair ile oluşturulmuş bir SHA1 hashidir. Hem imza, hem de public key assemblynin metadatasının içinde yer almaktadır. Assembly’e obfuscation uygulanmasının assembly dijital olarak imzalanmadan önce yapılmış olması gerekmektedir. Bu konu ile ilgili detaylı bilgi için .NET Framework dokumantasyonnda “delay-signed assemblies” konulu dokumanları okuyabilirsiniz. Delay-signed assemblylerin test sürecinde strong name validation’ın kapalı olması gerektiğini unutmayın.

Bununla birlikte reflection API’sının ve dinamik sınıf yüklemenin kullanımı obfuscation sürecini zorlaştıracaktır. Özelliklerin dinamik olması, çoğu obfuscation aracının kullandığı statik analiz tekniklerinin sorunla karşılaşmasına neden olabilmektedir. Örnek olarak aşağıdaki C# koduna bakalım:

public MyInterface GetNewType() {
Type type = Type.GetType( GetUserInputString(), true );
object newInstance = Activator.CreateInstance( type );
return newInstance as MyInterface;
}

Türün ismi farklı bir metoddan geliyor. GetUserInputString kullanıcıdan bir string istiyor veya bu veriyi veritabanından alıyor olabilir. Her iki durumda da isim analiz için kod içinde statik olarak saklanmadığı için orjinal assemblylerin içerdiği türlere dair bilgilere erişme imkanımız olmuyor. Bu durumda çözüm dinamik yapılara ait isimlerin yeniden adlandırılmasını önlemektir. Bu, manual konfigurasyonun ve obfuscation uygulanacak uygulama ile ilgili bilgi sahibi olmanın önem kazandığı bir noktadır. Dotfuscator Community Edition seçilen tür, metod veya alanların yeniden adlandırılmasını önlemenizi sağlayan seçenekler sunmaktadır. İsimleri kendiniz seçebileceğiniz gibi yeniden adlandırmayı önlemeye yönelik kuralları regular expressionlar kullanarak yazma imkanınız da vardır. Örneğin tüm public metodları yeniden adlandırmadan muaf tutabilirsiniz.

Obfuscationda en sık karşılaştığımız sorunlardan biri de kullanıcılara destek verme aşamasında çıkanlardır Aşağıda obfuscation uygulanmış bir uygulamanın verdiği exception mesajı yer almaktadır.

System.Exception: A serious error has occurred
at cv.a()
at cv..ctor(Hashtable A_0)
at ar.a(di A_0)
at ae.a(String[] A_0)

Malesef ortaya destek vermek için sorun ile ilgili yeterli miktarda bilgi veren bir hata mesajı çıkmıyor. İşin güzel yanı, oluşturulan map dosyası ile oluşan exception’daki obfuscation uygulanmış ifadeleri orijinal haline çevirebilecek olmamız. Ancak bazen oluşan exceptionın orjinal ifadelere erişmemize yeterli olacak kadar bilgi içermeyebileceğini hesaba katmamız gerekmektedir. Örneğin yukarıdaki mesajda return typeların yer almadığına dikkat edelim. Gelişmiş bir overload induction renaming algoritması ile obfuscate edilmiş uygulamalarda, sadece return türü farklı olan metodlar aynı şekilde isimlendirilebilirler ve dolayısıyla exception mesajları kafa karıştırıcı olabilir. Dotfuscator Professional Edition, bu tür mesajları orijinal metoda dönüştürmeyi sağlayan bir araç içermektedir.

Sonuç olarak ILDASM veya diğer decompiler araçları ile kolayca kodlarına erişilebilecek olan .NET uygulamaları sadece bir kaç dakika içinde güvenli bir hale getirebilirsiniz ve Visual Studio ile gelen Dotfuscator Community Edition bunun için oldukça iyi bir başlangıç noktasıdır.

Kaynaklar:
Microsoft Developers Network
Dotfuscator Documentation

#Hanefi

Reklamlar
Kategoriler:Diğerleri Etiketler:,
  1. Henüz yorum yapılmamış.
  1. No trackbacks yet.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

%d blogcu bunu beğendi: