Linux Komut Satırından İkili Dosyaların İçine Nasıl Bakılır

Yayınlanan: 2022-01-29
Dizüstü bilgisayarda yeşil metin satırları olan stilize bir Linux terminali.
fatmawati achmad zaenuri/Shutterstock

Gizem dosyan var mı? Linux file komutu, ne tür bir dosya olduğunu size hızlı bir şekilde söyleyecektir. Yine de ikili bir dosyaysa, onun hakkında daha fazla bilgi edinebilirsiniz. file , onu analiz etmenize yardımcı olacak bir sürü ahır arkadaşına sahiptir. Size bu araçlardan bazılarını nasıl kullanacağınızı göstereceğiz.

Dosya Türlerini Tanımlama

Dosyalar genellikle, yazılım paketlerinin hangi tür dosya olduğunu ve içindeki verilerin neyi temsil ettiğini belirlemesine izin veren özelliklere sahiptir. PNG dosyasını MP3 müzik çalarda açmaya çalışmak mantıklı olmaz, bu nedenle bir dosyanın bir tür kimlik taşıması hem kullanışlı hem de pragmatiktir.

Bu, dosyanın en başında birkaç imza baytı olabilir. Bu, bir dosyanın biçimi ve içeriği hakkında açık olmasını sağlar. Bazen dosya türü, dosya mimarisi olarak bilinen, verinin kendi iç organizasyonunun ayırt edici bir yönünden çıkarılır.

Windows gibi bazı işletim sistemleri tamamen bir dosyanın uzantısı tarafından yönlendirilir. Bunu saf veya güvenilir olarak adlandırabilirsiniz, ancak Windows, DOCX uzantılı herhangi bir dosyanın gerçekten bir DOCX kelime işlem dosyası olduğunu varsayar. Yakında göreceğiniz gibi Linux öyle değil. Kanıt istiyor ve onu bulmak için dosyanın içine bakıyor.

Burada açıklanan araçlar, bu makaleyi araştırmak için kullandığımız Manjaro 20, Fedora 21 ve Ubuntu 20.04 dağıtımlarında zaten yüklüydü. file komutunu kullanarak incelememize başlayalım.

Dosya Komutunu Kullanmak

Geçerli dizinimizde farklı dosya türlerinden oluşan bir koleksiyonumuz var. Belge, kaynak kodu, yürütülebilir dosya ve metin dosyalarının bir karışımıdır.

Reklamcılık

ls komutu bize dizinde ne olduğunu gösterecek ve -hl (insan tarafından okunabilir boyutlar, uzun liste) seçeneği bize her dosyanın boyutunu gösterecektir:

 ls -hl 

Bunlardan birkaçı üzerinde file deneyelim ve ne elde ettiğimizi görelim:

 dosya build_instructions.odt
 dosya build_instructions.pdf
 COBOL_Report_Apr60.djvu dosyası 

Üç dosya biçimi doğru bir şekilde tanımlanmıştır. Mümkün olduğunda, file bize biraz daha bilgi verir. PDF dosyasının sürüm 1.5 formatında olduğu bildiriliyor.

ODT dosyasını XYZ'nin keyfi değerine sahip bir uzantıya sahip olacak şekilde yeniden adlandırsak bile, dosya hem Files dosya tarayıcısında hem de file kullanılarak komut satırında doğru bir şekilde tanımlanır.

OpenDocument dosyası, uzantısı XYZ olmasına rağmen, Dosyalar dosya tarayıcısında doğru bir şekilde tanımlandı.

Files dosya tarayıcısında doğru simge verilir. Komut satırında file , uzantıyı yok sayar ve türünü belirlemek için dosyanın içine bakar:

 dosya build_instructions.xyz 

Reklamcılık

Görüntü ve müzik dosyaları gibi ortamlarda file kullanmak, genellikle biçimleri, kodlamaları, çözünürlükleri vb. hakkında bilgi verir:

 dosya ekran görüntüsü.png
 dosya ekran görüntüsü.jpg
 dosya Pachelbel_Canon_In_D.mp3 

İlginç bir şekilde, düz metin dosyalarında bile file, file uzantısına göre değerlendirmez. Örneğin, standart düz metin içeren ancak kaynak kodu içermeyen “.c” uzantılı bir dosyanız varsa, file onu orijinal bir C kaynak kodu dosyasıyla karıştırmaz:

 dosya işlevi+headers.h
 dosya makefile
 merhaba.c dosyası 

file , başlık dosyasını (“.h”), dosyalardan oluşan bir C kaynak kodu koleksiyonunun parçası olarak doğru bir şekilde tanımlar ve makefile'ın bir komut dosyası olduğunu bilir.

Dosyayı İkili Dosyalarla Kullanma

İkili dosyalar diğerlerinden daha fazla "kara kutu" gibidir. Uygun yazılım paketi ile görüntü dosyaları görüntülenebilir, ses dosyaları oynatılabilir ve belge dosyaları açılabilir. İkili dosyalar olsa da, daha zor.

Örneğin, "merhaba" ve "wd" dosyaları ikili yürütülebilir dosyalardır. Onlar programdır. “wd.o” adlı dosya bir nesne dosyasıdır. Kaynak kodu bir derleyici tarafından derlendiğinde, bir veya daha fazla nesne dosyası oluşturulur. Bunlar, bağlayıcı için bilgilerle birlikte, tamamlanan program çalıştığında bilgisayarın sonunda yürüteceği makine kodunu içerir. Bağlayıcı, kitaplıklara yapılan işlev çağrıları için her nesne dosyasını kontrol eder. Bunları programın kullandığı tüm kitaplıklara bağlar. Bu işlemin sonucu yürütülebilir bir dosyadır.

“watch.exe” dosyası, Windows'ta çalışmak üzere çapraz derlenmiş bir ikili yürütülebilir dosyadır:

 dosya wd
 dosya wd.o
 dosya merhaba
 dosya izleme.exe 

Reklamcılık

Önce sonuncuyu alarak, file bize “watch.exe” dosyasının Microsoft Windows'taki x86 işlemci ailesi için bir PE32+ yürütülebilir, konsol programı olduğunu söyler. PE, 32 ve 64 bit sürümleri olan taşınabilir yürütülebilir biçim anlamına gelir. PE32, 32 bit sürümdür ve PE32+ 64 bit sürümdür.

Diğer üç dosyanın tümü Yürütülebilir ve Bağlanabilir Biçim (ELF) dosyaları olarak tanımlanır. Bu, yürütülebilir dosyalar ve kitaplıklar gibi paylaşılan nesne dosyaları için bir standarttır. ELF başlık formatına birazdan göz atacağız.

Gözünüze çarpan şey, iki yürütülebilir dosyanın (“wd” ve “hello”) Linux Standard Base (LSB) paylaşılan nesneleri olarak tanımlanması ve “wd.o” nesne dosyasının bir LSB yeniden yerleştirilebilir olarak tanımlanmasıdır. Yürütülebilir kelimesi yokluğunda açıktır.

Nesne dosyaları yeniden yerleştirilebilir, yani içlerindeki kod herhangi bir yerden belleğe yüklenebilir. Yürütülebilir dosyalar, bu yeteneği devralacak şekilde nesne dosyalarından bağlayıcı tarafından oluşturuldukları için paylaşılan nesneler olarak listelenir.

Bu, Adres Alanı Düzeni Rastgeleleştirme (ASMR) sisteminin yürütülebilir dosyaları kendi seçtiği adreslerde belleğe yüklemesini sağlar. Standart yürütülebilir dosyaların, belleğe nereye yüklendiklerini belirleyen, başlıklarına kodlanmış bir yükleme adresi vardır.

ASMR bir güvenlik tekniğidir. Yürütülebilir dosyaları tahmin edilebilir adreslerde belleğe yüklemek, onları saldırıya açık hale getirir. Bunun nedeni, giriş noktalarının ve işlevlerinin konumlarının her zaman saldırganlar tarafından bilinmesidir. Rastgele bir adreste konumlandırılan Konumdan Bağımsız Yürütülebilir Dosyalar (PIE) bu duyarlılığın üstesinden gelir.

Reklamcılık

Programımızı gcc derleyicisiyle derlersek ve -no-pie seçeneğini sağlarsak, geleneksel bir yürütülebilir dosya oluştururuz.

-o (çıktı dosyası) seçeneği, yürütülebilir dosyamız için bir ad vermemize izin verir:

 gcc -o merhaba -no-pie merhaba.c

file yeni yürütülebilir dosyada kullanacağız ve nelerin değiştiğini göreceğiz:

 dosya merhaba

Yürütülebilir dosyanın boyutu öncekiyle aynıdır (17 KB):

 ls -hl merhaba 

İkili artık standart bir yürütülebilir dosya olarak tanımlanır. Bunu sadece tanıtım amaçlı yapıyoruz. Uygulamaları bu şekilde derlerseniz ASMR'nin tüm avantajlarını kaybedersiniz.

Bir Yürütülebilir Dosya Neden Bu Kadar Büyük?

Örnek hello programımız 17 KB'dir, bu yüzden büyük olarak adlandırılamaz, ancak o zaman her şey görecelidir. Kaynak kodu 120 bayttır:

 kedi merhaba.c
Reklamcılık

Tek yaptığı terminal penceresine bir dize yazdırmaksa, ikili dosyayı şişiren nedir? Bir ELF başlığı olduğunu biliyoruz, ancak bu 64 bitlik bir ikili dosya için yalnızca 64 bayt uzunluğundadır. Açıkçası, başka bir şey olmalı:

 ls -hl merhaba 

İçinde ne olduğunu keşfetmek için basit bir ilk adım olarak ikiliyi strings komutuyla tarayalım. Daha less :

 dizeler merhaba | az 

İkili dosyanın içinde "Merhaba, Geek dünyası!" dışında birçok karakter dizisi vardır. kaynak kodumuzdan. Bunların çoğu, ikili dosya içindeki bölgeler için etiketler ve paylaşılan nesnelerin adları ve bağlantı bilgileridir. Bunlar, ikili dosyanın bağlı olduğu kitaplıkları ve bu kitaplıklar içindeki işlevleri içerir.

ldd komutu bize bir ikili dosyanın paylaşılan nesne bağımlılıklarını gösterir:

 merhaba 

Çıktıda üç giriş vardır ve bunlardan ikisi bir dizin yolu içerir (ilkinde yoktur):

  • linux-vdso.so: Sanal Dinamik Paylaşılan Nesne (VDSO), bir kullanıcı alanı ikili dosyası tarafından bir dizi çekirdek alanı rutinine erişilmesine izin veren bir çekirdek mekanizmasıdır. Bu, kullanıcı çekirdek modundan bir bağlam anahtarının ek yükünü önler. VDSO paylaşılan nesneleri, Yürütülebilir ve Bağlanabilir Biçim (ELF) biçimine uyar ve çalışma zamanında ikili dosyaya dinamik olarak bağlanmalarına olanak tanır. VDSO dinamik olarak tahsis edilmiştir ve ASMR'den yararlanır. VDSO yeteneği, çekirdek ASMR şemasını destekliyorsa, standart GNU C Kitaplığı tarafından sağlanır.
  • libc.so.6: GNU C Kitaplığı paylaşılan nesnesi.
  • /lib64/ld-linux-x86-64.so.2: Bu, ikili programın kullanmak istediği dinamik bağlayıcıdır. Dinamik bağlayıcı, hangi bağımlılıklara sahip olduğunu keşfetmek için ikili dosyayı sorgular. Bu paylaşılan nesneleri belleğe başlatır. İkili dosyayı çalıştıracak ve bellekteki bağımlılıkları bulup erişebilecek şekilde hazırlar. Ardından, programı başlatır.

ELF Başlığı

readelf yardımcı programını ve -h (dosya başlığı) seçeneğini kullanarak ELF başlığını inceleyebilir ve kodunu çözebiliriz:

 readelf -h merhaba 

Başlık bizim için yorumlanmıştır.

Reklamcılık

Tüm ELF ikili dosyalarının ilk baytı, 0x7F onaltılık değerine ayarlanmıştır. Sonraki üç bayt 0x45, 0x4C ve 0x46 olarak ayarlanır. İlk bayt, dosyayı bir ELF ikili dosyası olarak tanımlayan bir bayraktır. Bunu netleştirmek için, sonraki üç bayt ASCII'de “ELF” harfini heceler:

  • Sınıf: İkili dosyanın 32 veya 64 bit yürütülebilir dosya olup olmadığını gösterir (1=32, 2=64).
  • Veri: Kullanımdaki endianlığı gösterir. Endian kodlaması, çok baytlı sayıların saklanma şeklini tanımlar. Big-endian kodlamada, bir sayı önce en önemli bitleriyle birlikte depolanır. Little-endian kodlamada, sayı önce en az anlamlı bitleriyle birlikte depolanır.
  • Sürüm: ELF'nin sürümü (şu anda 1'dir).
  • OS/ABI: Kullanılan uygulama ikili arabiriminin türünü temsil eder. Bu, bir program ve paylaşılan bir kitaplık gibi iki ikili modül arasındaki arabirimi tanımlar.
  • ABI Sürümü: ABI sürümü.
  • Tür: ELF ikili dosyasının türü. Ortak değerler, ET_REL değiştirilebilen bir kaynak (bir nesne dosyası gibi) için ET_EXEC , -no -no-pie bayrağıyla derlenmiş bir yürütülebilir dosya için ET_DYN ve bir ASMR uyumlu yürütülebilir dosya için ET_DYN'dir.
  • Makine: Komut seti mimarisi. Bu, ikili dosyanın oluşturulduğu hedef platformu gösterir.
  • Sürüm: ELF'nin bu sürümü için her zaman 1'e ayarlayın.
  • Giriş Noktası Adresi: Yürütmenin başladığı ikili dosya içindeki bellek adresi.

Diğer girişler, konumlarının hesaplanabilmesi için ikili dosya içindeki bölgelerin ve bölümlerin boyutları ve sayılarıdır.

hexdump ile ikili dosyanın ilk sekiz baytına hızlı bir bakış, dosyanın ilk dört baytında imza baytını ve “ELF” dizesini gösterecektir. -C (standart) seçeneği bize baytların onaltılık değerlerinin yanı sıra ASCII gösterimini verir ve -n (sayı) seçeneği görmek istediğimiz kaç bayt olduğunu belirtmemize izin verir:

 hexdump -C -n 8 merhaba 

objdump ve Granüler Görünüm

Nitelikli ayrıntıyı görmek istiyorsanız, objdump komutunu -d (sökme) seçeneğiyle birlikte kullanabilirsiniz:

 objdump -d merhaba | az 

Bu, yürütülebilir makine kodunu demonte eder ve bunu, montaj dili eşdeğerinin yanında onaltılık bayt olarak görüntüler. Her satırdaki ilk gülenin adres konumu en solda gösterilir.

Bu, yalnızca montaj dilini okuyabiliyorsanız veya perdenin arkasında neler olduğunu merak ediyorsanız kullanışlıdır. Çok fazla çıktı var, bu yüzden onu less içine aktardık.

Derleme ve Bağlama

Bir ikiliyi derlemenin birçok yolu vardır. Örneğin, geliştirici hata ayıklama bilgilerinin dahil edilip edilmeyeceğini seçer. İkili dosyanın bağlanma şekli, içeriğinde ve boyutunda da rol oynar. İkili referanslar nesneleri harici bağımlılıklar olarak paylaşıyorsa, bağımlılıkların statik olarak bağlandığından daha küçük olacaktır.

Reklamcılık

Çoğu geliştirici, burada ele aldığımız komutları zaten biliyor. Ancak diğerleri için, ortalığı karıştırmak ve ikili kara kutunun içinde ne olduğunu görmek için bazı kolay yollar sunuyorlar.