Soru:
Makine kodundaki hangi ipuçları beni onu oluşturmak için kullanılan derleyiciye yönlendirebilir?
WilliamKF
2013-03-20 01:01:49 UTC
view on stackexchange narkive permalink

Bir uygulamanın makine koduna baktığımda, oluşturulan makine kodundan onu oluşturmak için hangi derleyicinin (ve muhtemelen sürümün) kullanıldığını gösteren ipuçları ve kalıplar var mı?

Bir uygulama oluşturmak için kullanılan derleyiciyi bilmek, oluşturulan nesneden kaynak kodun ne olabileceğine daha etkili bir şekilde geri dönmeme yardımcı olur mu ve yardımcı olursa, nasıl olur?

"Oluşturulan nesneden kaynak kodun ne olabileceğine daha etkili bir şekilde geri mühendislik yapmama yardım et" dediğinizde, amacınız kodu yeniden derlemek mi yoksa kodun işlevselliğini anlamak mı?
Kodu tamamen yeniden derlemek mümkün mü? Mümkünse, aksi halde en azından işlevselliği anlamak için derlemeyi çözmeyi söyleyebilirim.
Yedi yanıtlar:
Andrew
2013-03-20 01:46:22 UTC
view on stackexchange narkive permalink

Bu alanda bazı akademik araştırmalar var, istediğiniz anahtar kelimeler 'araç zinciri kaynağı'dır. Nate Rosenblum'un bu konuda oldukça iyi bir makalesi vardı, bu makaleyi okuyalı epey oldu, ancak bu bilgiyi oluşturmak için birçok tekniği kullanabilirsiniz. Bazılarının makine öğrenimini kullandığını ve diğerlerinin derleyici davranışı hakkında büyük bir sezgisel tarama veya aksiyom yığını kullanabileceğini düşünüyorum.

Bunu kurmak sınırlı fayda sağlar IMO. Bir kötü amaçlı yazılım grubu veya tehdit aktörü hakkında istihbarat elde etmeye çalıştığınız düşmanca bir durumda faydalı olabilir, ancak bu tür bilgilerin gizlenebileceğini veya yok edilebileceğini de unutmayın. Bu bilgilerin olası kullanımlarından biri, bazı ikili yazılımların, o şirkete özgü imza bilgilerine sahip bir derleyici içeren bazı şirketlerin SDK'sı kullanılarak derlendiğini tespit etmek olabilir. Araç zinciri kaynağının oluşturulması, SDK'nızı satın alan birinin, örneğin kötü amaçlı yazılım üreterek bir lisansı veya sözleşmeyi ihlal ettiğine dair bir durum oluşturmanıza yardımcı olabilir.

Davranış farklılıklarına bir örnek parametre yazmaktır. Yığına bir değer yerleştirmenin iki yolu vardır, biri 'push' kullanarak ve diğeri hedef işlenen olarak esp tabanlı bir adresle mov kullanarak. Böylece bir derleyici bunu yapabilir:

 push eaxpush ebx 

Ve bir başkası bunu yapabilir:

 mov [esp + foo], eaxmov [esp + foo + 4], ebx 

Ve yaparlar. Genel olarak, MSVC ilk örneği, GCC ikinci örneği yapıyor, en azından şu anda çok sınırlı test / gözlemlerde ...

Mike
2013-03-20 01:46:15 UTC
view on stackexchange narkive permalink

Makine koduna bakarken, tipik olarak, üretilen ikili kod bir şekilde düzeltilmediği sürece izlenebilecek bir "iz" vardır. Örneğin, hexedit gibi bir araç alırsanız, Linux kutumda gcc -Wall merhaba.c standart seçenekleriyle GCC'yi kullanarak küçük bir "merhaba dünya" uygulaması oluşturdum. kod> makine kodunda yapım bilgilerini içeren bir bölüm olduğunu görebilirsiniz:

enter image description here

Orada açıkça görebilirsiniz evet, bunu GCC sürüm 4.6.3. Diğer derleyiciler, başka tür imzalara sahip olacaktır Microsoft'un "zengin" imzası.

Dosyayı çıkardıktan sonra nasıl görüneceği ilginç ...
Soru özellikle makine koduyla ilgiliydi. OP'nin onaltılık bir düzenleyici veya "objdump" kullanmak ve sormadan önce önemsiz dizgeleri aramak gibi temel yöntemleri denediğini umabiliriz. Bu durumda, bu bir cevap olmaz. Ama elbette, bir şekilde olmasaydı, konuyla alakalı olurdu. ;-)
@underscore_d - "Umut ederdi" ', gerçekten de olur. Sadece OP'nin bunu bildiğini ummamıza gerek olmadığından emin oluyordum. Çok fazla varsayımda bulunmamayı seviyorum!
Igor Skochinsky
2013-03-20 02:29:37 UTC
view on stackexchange narkive permalink

Recon'da bunun için bir yaklaşımı anlatan "Packer Genetics: The Selfish Code" başlıklı bir sunum vardı. Derlenmiş programlardan en yaygın kod dizilerini çıkarmak için bazı istatistikler kullandılar ve bunu paket açmanın sonunu tespit etmek için kullandılar, ancak bu yaklaşım, belirli derleyicileri tanımlamak için kolayca kullanılabilir.

15. slayta bakın: http://blog.zynamics.com/2010/07/16/recon-slides-packer-genetics-the-selfish-code-bochspython/

Slaytlar bir şekilde kesilmiş görünüyor Sanırım gerçek sunumda daha fazla bilgi vardı.

Remko
2013-03-20 19:53:24 UTC
view on stackexchange narkive permalink

Bir uygulama oluşturmak için kullanılan derleyiciyi bilmek, oluşturulan nesneden kaynak kodun ne olabileceğine daha etkili bir şekilde geri dönmeme yardımcı olur mu ve yardımcı olursa nasıl olur?

Kullanılan derleyiciyi bilmenin şu nedenlerden dolayı çok önemli bir adım olduğunu düşünüyorum:

  1. Hedefi analiz etmek için uygun araçları seçmenize yardımcı olur.
  2. Çalışma zamanının bilinmesi analiz için önemlidir, örneğin Delphi'de TFileStream dosyaları okumak / yazmak için yaygın olarak kullanılan bir nesnedir. Bu nesnenin vtable'ını bilmek, bir ofsetin okunup / yazılmadığını / arandığını vb. Anlamama yardımcı olur.

1'i bir örnekle açıklamak için: IDR gibi bir araç Delphi hedefi için IDA Pro'dan daha uygun olabilir. Ya da en azından onunla IDA'daki sembolleri geliştiren bir MAP dosyası / IDC betiği oluşturabiliriz. Ancak Visual Basic'te yazılmış bir hedef için VB Decompiler vb. Kullanılabilir.

waliedassar
2013-04-17 11:57:13 UTC
view on stackexchange narkive permalink

Derleyici sürümünü tam anlamıyla bağlayıcı sürümü yerine derleyici sürümünü kastetmediğiniz sürece, derleyici sürümünü belirlemek için yapmanız gereken ilk şey, yürütülebilir dosyanın PE başlığının "MajorLinkerVersion" ve "MinorLinkerVersion" alanlarını incelemektir. , DLL veya SYS. Aşağıdaki listeye bakın.

Major Minor

0x5 0x0 (5.0) Borland C ++ / MS Linker 5.0

0x6 0x0 (6.0) Microsoft VIsual Studio 6

0x7 0xA (7.10) Microsoft VIsual Studio 2003

0x8 0x0 (8.0) Microsoft VIsual Studio 2005

0x9 0x0 (9.0) Microsoft VIsual Studio 2008

0xA 0x0 (10.0) Microsoft VIsual Studio 2010

0x2 0x15 (2.21) MinGw

0x2 0x19 (2.0.0.25) Borland Delphi (bağlayıcı 2.0.0.25)

Maalesef paketleyiciler ve koruyucular, kendi değerlerini yazmak ve / veya orijinal derleyiciyi tahmin etme sürecini sertleştirmek için bu değerlerin üzerine yazma eğilimindedir.

Ayrıca, çalıştırılabilir bir dosyanın kaynak dizini, belirli bağlayıcı bilgilerini aramak için iyi bir yerdir. Örneğin. "DVCLAL" adlı bir kaynağa sahip olan RT_RCDATA, Borland C ++ veya Delphi'nin bir işaretidir ve MSVC ile oluşturulmuş bir yürütülebilir dosya olması durumunda "RT_MANIFEST", bağlantılı olduğu çalışma zamanı DLL'sinin özel sürümü ve dolayısıyla derleyici sürümü hakkında bize bilgi verebilir.

Ayrıca, "TimeDateStamp" alanı 0x2A425E19 olarak ayarlanmış bir yürütülebilir dosya, Delphi ile oluşturulduğunun bir işaretidir.

Şimdi, derleyiciyi derleme kodundan belirlemek istiyorsanız, ardından işareti MSVC derleyici sürümünün yeni sürümlerinden biri, yığın çerezini oluşturan işlevi giriş noktasında görüyor.

Giriş noktasında bir JMP talimatı ve ardından "fb: C ++ Hook" bir Borland C ++ işareti vb.

Michael Anderson
2013-03-20 03:35:49 UTC
view on stackexchange narkive permalink

Bir uygulama oluşturmak için kullanılan derleyiciyi bilmek, oluşturulan nesneden kaynak kodun ne olabileceğine daha etkili bir şekilde geri dönmeme yardımcı olur mu ve yardımcı olursa, nasıl olur?

Evet, yardımcı olmalı.

Daha da iyisi:

  • tam derleyici sürümü;
  • tam komut satırı parametreleri;
  • inşa ortamı (İşletim Sistemi, yama seviyesi, ...).

Fikir şudur:

  • Farklı yapıları sergileyen ve bunları derleyen birçok farklı durum (küçük küçük programlar) için test senaryoları oluşturun;

  • ortaya çıkan makine koduna bakın (desenleri fark etme).

Bu durumların çoğu, derleyicinin ana sürümüne göre genelleştirilebilir ( if ve diğer kontrol yapıları, temel dil işlevleri, ...).

Aynı program için çok farklı olan bazı derleyiciye özgü optimizasyonların olması mümkündür.

(İletişim için test senaryosu kitaplıkları olup olmadığını merak ediyorum. belirli bir derleyicinin ürettiği makine kodunun ters mühendisliğine yardımcı olmak için on / yararlı durumlar.)

Açık sözlü olduğum için üzgünüm, ancak biçimlendirmeniz üzerinde çalışmanız ve Rastgele Büyük Harflerden kurtulmanız gerekiyor. Şu anda cevabın okunması oldukça zor.
Düzenleme Bir İyileştirme miydi?
Yifan
2013-03-20 01:17:21 UTC
view on stackexchange narkive permalink

Yalnızca makine kodundan (veya Montaj kodundan) bahsederseniz, fazla bilgi yoktur. Çoğu modern derleyici benzer çıktı üretir veya çıktı farklılıkları görmek için yeterli olmaz. Gösterge verebilecek bir şey, benim deneyimlemediğim ve bir başkasının devreye girmesi gereken derleyici optimizasyonudur. Yine de ELF dosyasının tamamına sahipseniz ve semboller mevcutsa, hangi türlere dayalı olarak sonuçlar çıkarmanız mümkün olabilir. kitaplıklar bağlantılıdır (örneğin, libgcc bir fikir olabilir) veya derleyiciye özel işlevlerin adları. ELF hata ayıklama bilgisi içeriyorsa, "GCC: (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3" gibi şeyler bile görebilirsiniz. Eğer C ++ kodu ile uğraşıyorsanız, sembol ismi onu ele verebilir.

Ancak, kendinize sorduğunuz gibi, bu bilgiye neden ihtiyaç duyduğunuzu merak ediyorum. Bunu yapan derleyiciyi bilerek ne kadar yardım alacağınızı bilmiyorum. ARM ile daha fazla çalışıyorum ve bu platformla biliyorum, derleyicilerin / derleme kodunun uyması gereken bir Uygulama İkili Arayüzü var. Bu ABI, işlevlerin nasıl çağrılması gerektiği, hangi kayıtların ne için kullanılması gerektiği vb. Hakkında bilgi verir. Katı bir ABI'sı olmayan platformlar için bildiğim, işletim sistemleri genellikle geliştiricilere bu tür konular hakkında bilgi verir. Her şeye rağmen, derleyicilerin tümü uyumlu kod oluşturmalıdır, bu nedenle kodu oluşturan derleyiciyi tanımlamanın herhangi bir şekilde kullanıldığını bilmiyorum.

Bu yanıt, çıktıda neden farklılıklar olmayacağına dair bir gerekçe veya referanstan yoksundur. X86 ile kişisel deneyimim bununla çelişiyor, ancak örneklem boyutum bunun genel olarak doğru olduğunu söylemek için çok küçük. Ayrıca bu bilgiye neden ihtiyaç duyulduğunu sormak gerçekten bir cevabın parçası değil, daha çok açıklama talebidir ve soru için bir yoruma daha iyi uyacaktır.
Yapıcı eleştirileriniz için teşekkürler. Soruları cevaplamada yeniyim, bu yüzden tüm detayları anlamıyorum. Daha fazla referans bulmaya çalışacağım.
Derleyiciler arasında şaşırtıcı sayıda fark vardır, özellikle de seçim yapabileceğiniz çok sayıda farklı talimatın olduğu x86 kodunda. Anahtar deyimi uygulamaları, yığın düzeni kararları ve kayıt seçeneklerinin tümü, hangi derleyicinin kullanıldığına dair ipuçları sağlayabilir.


Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 3.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...