TL; DR: makine kodu çözücüler çok kullanışlıdır, ancak yönetilen diller için sağladıkları mucizelerin aynısını beklemeyin. Birkaç sınırlamayı belirtmek gerekirse: Sonuç genellikle yeniden derlenemez, orijinal kaynak kodundaki isimler, türler ve diğer önemli bilgilerden yoksundur, orijinal kaynak kodu eksi yorumlardan çok daha zor okunabilir ve garip bırakabilir kod çözme listesindeki işlemciye özgü yapılar.
-
Derleyici neden bu kadar popüler?
Ayrıştırıcılar çok çekici ters mühendislik araçlarıdır çünkü çok fazla işten tasarruf etme potansiyeline sahipler. Aslında, Java ve .NET gibi yönetilen diller için o kadar mantıksız bir şekilde etkilidirler ki, "Java ve .NET tersine mühendislik" neredeyse bir konu olarak mevcut değildir. Bu durum, birçok yeni başlayan kişinin aynı şeyin makine kodu için de geçerli olup olmadığını merak etmesine neden olur. Maalesef durum bu değil. Makine kodu çözücüler mevcuttur ve analistin zamanından tasarruf etmede faydalıdır. Ancak, bunlar yalnızca çok manuel bir sürece yardımcı olurlar. Bunun doğru olmasının nedeni, bayt kodu dili ve makine kodu çözücülerinin farklı zorluklarla karşı karşıya kalmasıdır.
-
Özgün değişken adlarını derlenmiş kaynakta görecek miyim? kod?
Bazı zorluklar, derleme süreci boyunca anlamsal bilgi kaybından kaynaklanır. Yönetilen diller, genellikle bir nesne içindeki alanların adları gibi değişkenlerin adlarını korur. Bu nedenle, insan analisti programcının yarattığı ve anlamlı olmasını umduğu isimlerle sunmak kolaydır. Bu, derlenmiş makine kodunu anlama hızını artırır.
Öte yandan, makine kodu programları derleyicileri, programı derlerken genellikle bu bilgilerin çoğunu yok ederler (belki de bir kısmını hata ayıklama bilgileri biçiminde geride bırakırlar). Bu nedenle, bir makine kodu çözücüsü her yönden mükemmel olsa bile, insan kavrama hızını yavaşlatan bilgilendirici olmayan değişken adları ("v11", "a0", "esi0" vb.) .
-
Derlenmiş programı yeniden derleyebilir miyim?
Bazı zorluklar programı sökmekle ilgilidir. Java ve .NET gibi bayt kodu dillerinde, derlenen nesne ile ilişkili meta veriler genellikle nesne içindeki tüm kod baytlarının konumlarını açıklayacaktır. Yani, tüm işlevler, nesnenin başlığındaki bazı tabloda bir girişe sahip olacaktır.
Öte yandan, makine dilinde, örneğin, x86 Windows demontajını, bir PDB, demonte edici, ikili içerisindeki kodun nerede olduğunu bilmez. Programın giriş noktası gibi bazı ipuçları verilmiştir. Sonuç olarak, makine kodu çözücüler, ikili kod içindeki kod konumlarını keşfetmek için kendi algoritmalarını uygulamaya zorlanır. Genellikle iki algoritma kullanırlar: doğrusal tarama (genellikle bir işlevin başlangıcını belirten bilinen bayt dizilerini arayan metin bölümünde tarama) ve özyinelemeli geçiş (sabit bir konuma yönelik bir çağrı talimatıyla karşılaşıldığında, bu konumu kod içeriyor olarak düşünün ).
Bununla birlikte, doğrusal süpürme bileşeninin başarısız olmasına neden olan işlev prologlarını değiştiren prosedürler arası kayıt tahsisi gibi derleyici optimizasyonları ve doğal olarak meydana gelen dolaylı kontrol akışı ( yani, işlev göstericisi aracılığıyla çağrı) özyinelemeli geçişin başarısız olmasına neden olur. Bu nedenle, bir makine kodu çözücüsü bunun dışında bir sorunla karşılaşmasa bile, genellikle bir programın tamamı için bir derleme oluşturamaz ve bu nedenle sonuç yeniden derlenemez.
Kod / Yukarıda açıklanan veri ayırma problemi, Durdurma Problemi gibi diğer imkansız problemlerle paylaştığı "kararsız" problemler adı verilen özel bir teorik problem kategorisine girer. Bu nedenle, orijinal ikilinin bir klonunu elde etmek için yeniden derlenebilecek çıktılar üretecek otomatik bir makine kodu çözücü bulma umudunu bırakın.
-
Şu konuda bilgi alacak mıyım? derlenmiş program tarafından kullanılan nesneler?
C ve C ++ gibi dillerin, yönetilen dillere karşı nasıl derlendiğine ilişkin zorluklar da vardır; Tür bilgilerini burada tartışacağım. Java bayt kodunda, nesneleri ayırmak için 'yeni' adında özel bir talimat vardır. Ayrılacak nesneyi tanımlayan .class dosyası meta verilerine bir referans olarak yorumlanan bir tamsayı bağımsız değişkeni alır. Bu meta veriler sırasıyla sınıfın düzenini, üyelerin adlarını ve türlerini vb. Açıklar. Bu, sınıfa yapılan referansları insan müfettişinin hoşuna gidecek şekilde derlemeyi çok kolaylaştırır.
Bir C ++ programı derlendiğinde ise, RTTI gibi hata ayıklama bilgilerinin yokluğunda, nesne oluşturma düzgün ve düzenli bir şekilde yapılmaz. Kullanıcı tanımlı bir bellek ayırıcı çağırır ve daha sonra ortaya çıkan işaretçiyi yapıcı işlevine bir argüman olarak iletir (bu da satır içi olabilir ve dolayısıyla bir işlev olmayabilir). Sınıf üyelerine erişen talimatlar sözdizimsel olarak yerel değişken referanslarından, dizi referanslarından vb. Ayırt edilemez. Ayrıca, sınıfın düzeni ikilinin herhangi bir yerinde saklanmaz. Aslında, ayıklanmış bir ikili dosyadaki veri yapılarını keşfetmenin tek yolu veri akışı analizidir. Bu nedenle, bir derleyicinin durumla başa çıkabilmek için kendi tür yeniden yapılandırmasını uygulaması gerekir. Aslında, popüler kod çözücü Hex-Rays, bu görevi çoğunlukla insan analiste bırakıyor (yine de insan için yararlı yardım sunuyor).
-
Temelde ayrıştırma olacak mı? kontrol akışı yapısı açısından orijinal kaynak koduna benziyor mu?
Bazı zorluklar derleyici optimizasyonlarının derlenmiş ikiliye uygulanmasından kaynaklanıyor. "Kuyruk birleştirme" olarak bilinen popüler optimizasyon, programın kontrol akışının, daha az agresif olan derleyicilere kıyasla bozulmasına neden olur, bu da genellikle kendini kod çözme içinde çok sayıda goto ifadesi olarak gösterir. Seyrek anahtar deyimlerinin derlenmesi benzer sorunlara neden olabilir. Öte yandan, yönetilen dillerde genellikle anahtar deyimi talimatları bulunur.
-
İşlemcinin belirsiz yönleri söz konusu olduğunda kod çözücü anlamlı çıktılar verecek mi?
Bazı zorluklar, söz konusu işlemcinin mimari özelliklerinden kaynaklanmaktadır. Örneğin, x86'daki yerleşik kayan nokta birimi bir çetin kabustu. Kayan nokta "kayıtları" yoktur, bir kayan nokta "yığını" vardır ve programın düzgün şekilde derlenebilmesi için tam olarak izlenmesi gerekir. Bunun tersine, yönetilen diller genellikle, kendileri de değişken olan kayan nokta değerleriyle başa çıkmak için özel talimatlara sahiptir. (Hex-Rays kayan nokta aritmetiğini gayet iyi idare eder.) Veya x86'da yüzlerce yasal talimat türü olduğunu düşünün; bunların çoğu, kullanıcı bunu açıkça belirtmeden normal bir derleyici tarafından asla üretilmez. içsel. Bir derleyici çözücü, yerel olarak desteklediği bu talimatlar için özel işlemler içermelidir ve bu nedenle çoğu derleyici, satır içi derleme veya (en iyi durumda) desteklemeyenler için iç bilgiler kullanarak derleyiciler tarafından en yaygın olarak oluşturulanlar için desteği içerir. >
Bunlar, makine kodu çözücüleri rahatsız eden erişilebilir zorluk örneklerinden yalnızca birkaçıdır. Öngörülebilir gelecekte sınırlamaların devam etmesini bekleyebiliriz. Bu nedenle, yönetilen dil çözümleyicileri kadar etkili sihirli bir madde aramayın.