Mono nasıl büyülü?


149

C # öğreniyorum, bu yüzden şunu Hello, World!derleyen mono-cscve koşturan küçük bir C # programı hazırladım mono:

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

Ben vurduğunda fark TABiçinde bash, Hello.exeçalıştırılabilir kutlandı. Nitekim, sadece dosya ismini yükleyen bir kabuk ile çalışır!

Hello.exeolduğu değil komik bir dosya uzantısına sahip bir ELF dosyası:

$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............

MZMicrosoft Windows statik bağlantılı çalıştırılabilir anlamına gelir. Bunu bir Windows kutusuna bırakın, çalışacaktır.

Ben var wineyükledim ancak wineWindows uygulamaları için bir uyumluluk katmanı olan, yaklaşık 5x sürece çalıştırmak için gereken Hello.exeolarak monove doğrudan do yürütülmesi, bu yüzden değil wineo kadar çalışır.

Bununla monoyüklü olan bazı çekirdek modüllerinin var olduğunu varsayıyorum mono, execsistem çağrılarını / sistemlerini engelliyor ya da başlayan ikilileri yakalar 4D 5A, ancak lsmod | grep monoarkadaşlar bir hata döndürür.

Burada neler oluyor ve çekirdek bu yürütülebilir dosyanın özel olduğunu nasıl biliyor ?


Sadece benim kabuğumun büyüsü olmadığını ispatlamak için Crap Shell'i (aka sh) çalıştırmak için kullandım ve hala doğal olarak çalışıyor.


İşte programın tamamı, yorum yapanların merak ettiği için:

using System;

class Hello {
  /// <summary>
  ///   The main entry point for the application
  /// </summary>
  [STAThread]
  public static void Main(string[] args) {
    System.Console.Write("Hello, World!\n");
  }
}

4
Cevap alırken, ama biraz kafam karıştı, Komutlar gibi php hello.phpya python hello.pyda perl hello.plya da java gibi derlenmiş bir dil durumunda java helloçalıştırırsanız, orada çalıştırılabilir olmadıklarından, bir dosyayı okuyup çalıştırdıklarından da çalıştırırlar. Ancak ./hello.exebunun yerine mono hello.exekoşturursanız sorunuzu buldum ve cevabı daha makul buldum (bu durumda kesinlikle binfmt-support kullanın.
kuldeep.kamboj

@ kuldeep.kamboj Ne söylediğinizi anladığımdan emin değilim ama bir Windows çalıştırıcısının bir Linux kutusunda "yerel olarak" çalıştırılmasına şaşırdım.
kedi,

1
Aslında, söylediğim herhangi bir kod dosyası (veya derlenmiş dosya), kendi program programında, kendi program codefileprogramında, mono olarak program aracılığıyla yürütülebilmektedir , benim örneklerimde php, python, perl ve java bulunur. Mono'nun .exe dosyası dışındaki uzantılara hala kod yoluyla çalıştırıldığından şüpheleniyorum. Derlenmiş bir kod yürütüldüğü için pencerelere hiç bağlı olmamalıdır. Ancak kaynak dosyanız yalnızca Windows API gibi bazı bağımlı kodlara sahipse, o zaman açıkça bu exe dosyasını çalıştırmak için şarap gerekir.
kuldeep.kamboj

4
Bunun harika ironisinin bir kısmı /etc/magicda /usr/share/file/magic(veya benzer bir büyülü konum) bunu yapabilmek için gerekli bilgiyi içeren dosyadır.

1
@ cat, çok ilginç bir dosya (eğer favori bir dosyam olsaydı, muhtemelen benim ilk tercihim olurdu). Her türlü dosyayı tanımlamak için bilgiye sahiptir. Ancak nasıl çalıştırılacağını çözmeden önce dosyanın ilk önce ne olduğunu belirlemeniz gerekir. Dosya ve sihir böyle yapar. Benzer bir şey - Java Binary Kernel Bir süredir Linux için destek, bu yüzden yapmayı $ foo.jartercih edebilir $ java -jar foo.jar- mono için yapılanlara benzer.

Yanıtlar:


183

Bu, binfmt_misc eylemidir: çekirdeğe, bilmediği ikililerin nasıl çalıştırılacağının anlatılmasını sağlar. İçeriğine bakın /proc/sys/fs/binfmt_misc; Orada gördüğünüz dosyalar arasında, Mono ikili dosyalarının nasıl çalıştırılacağı açıklanmalıdır:

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(bir Debian sisteminde). Bu, çekirdeğe MZ( 4d5a) ile başlayan ikililerin verilmesi gerektiğini söyler run-detectors. İkincisi, ikiliyi çalıştırmak için Mono veya Şarap'ın kullanılıp kullanılmayacağını belirler.

İkili türler herhangi bir zamanda eklenebilir, kaldırılabilir, etkinleştirilebilir ve devre dışı bırakılabilir; Ayrıntılar için yukarıdaki belgelere bakın (anlambilim şaşırtıcıdır, burada kullanılan sanal dosya sistemi tamamen standart bir dosya sistemi gibi davranmaz). /proc/sys/fs/binfmt_misc/statusküresel durumu verir ve her ikili "tanımlayıcı" kendi durumunu gösterir. Bir devre dışı bırakmanın başka bir yolu binfmt_misc, eğer modül olarak inşa edilmişse, çekirdek modülünü boşaltmaktır; Bu aynı zamanda tamamen önlemek için kara listeye almanın mümkün olduğu anlamına gelir.

Bu özellik, MZ çalıştırılabilir dosyaları (Windows PE ve PE + dosyalarının yanı sıra DOS ve OS / 2 dosyalarının da dahil olduğu), Java JAR dosyaları gibi yeni ikili türlerin desteklenmesini sağlar. Ayrıca bilinen ikili türlerin de desteklenmesini sağlar Qemu'yu kullanan yeni mimariler; Böylece, uygun kütüphanelerle, ARM Linux ikili dosyalarını bir Intel işlemcide şeffaf bir şekilde çalıştırabilirsiniz!

Sorunuz, .NET anlamında da olsa, çapraz derlemeden kaynaklandı ve bununla ilgili bir uyarı ortaya çıktı binfmt_misc: Bazı derleme biçimleri, derlenmiş ikilileri çalıştırabilen bir sistemde çapraz derlemeye çalıştığınızda hatalı davranıyor. Tipik olarak, çapraz derlemenin tespit edilmesi bir ikili yapı oluşturmayı ve çalıştırmayı denemeyi içerir; çalışırsa, çapraz derleme yapmazsınız, değilse, siz (veya derleyiciniz bozulur). autoconfkomut dosyaları genellikle bu durumda yapı ve ana bilgisayar mimarilerini açıkça belirterek belirlenebilir, ancak bazen binfmt_miscgeçici olarak devre dışı bırakmanız gerekebilir ...


2
/ Proc hakkında merak edenlere , / proc / * nasıl çalışır? üzerinde Super User .
CVn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.