Eğer ELF tespiti için kendinizi sınırlamak isterseniz, okuyabilir ELF başlığını arasında /proc/$PID/exe
kendine. Oldukça önemsiz: dosyadaki 5. bayt 1 ise, 32 bitlik bir ikili dosyadır. 2 ise 64 bittir. Ek sağlık kontrolü için:
- İlk 5 bayt ise
0x7f, "ELF", 1
: 32 bit ELF ikili dosyasıdır.
- İlk 5 bayt ise
0x7f, "ELF", 2
: 64 bit ELF ikilidir.
- Aksi takdirde: sonuç vermez.
Ayrıca kullanabilirsiniz objdump
, ancak bu libmagic
bağımlılığınızı ortadan kaldırır ve bir tanesiyle değiştirir libelf
.
Başka bir yol : /proc/$PID/auxv
dosyayı ayrıştırabilirsiniz . Göre proc(5)
:
Bu, işlem sırasında işleme geçirilen ELF yorumlayıcı bilgilerinin içeriğini içerir. Biçim bir imzasız uzun kimlik artı her giriş için bir imzasız uzun değerdir. Son giriş iki sıfır içerir.
unsigned long
Anahtarların anlamları içeride /usr/include/linux/auxvec.h
. Sen istiyorsun AT_PLATFORM
ki, 0x00000f
. Bu konuda bana alıntı yapma, ancak char *
platformun dize açıklamasını almak için değerin a olarak yorumlanması gerektiği anlaşılıyor .
Bu StackOverflow sorusunu yararlı bulabilirsiniz .
Yine başka bir yol : Dinamik linker'e ( man ld
) yürütülebilir dosya hakkında bilgi dökümü talimatı verebilirsiniz . Çözülmüş AUXV yapısını standart çıktıya yazdırır. Uyarı: Bu bir hack, ama işe yarıyor.
LD_SHOW_AUXV=1 ldd /proc/$SOME_PID/exe | grep AT_PLATFORM | tail -1
Bu şöyle bir şey gösterecektir:
AT_PLATFORM: x86_64
Ben 32-bit ikili bir denedim ve i686
yerine aldım .
Bu nasıl çalışır: LD_SHOW_AUXV=1
çalıştırılabilir dosyayı çalıştırmadan önce Dinamik Bağlayıcı'ya kodu çözülmüş AUXV yapısını dökmesini bildirir. Eğer sürece gerçekten hayatınızı ilginç yapmak ister, aslında kaçınmak istiyorum çalışıyor yürütülebilir söyledi. Aslında main()
işlevini çağırmadan yüklemenin ve dinamik olarak bağlamanın bir yolu ldd(1)
üzerinde çalıştırmaktır . Dezavantajı: LD_SHOW_AUXV
kabuk tarafından etkinleştirilir, böylece AUXV yapılarının dökümlerini alırsınız: alt kabuk ldd
ve hedef ikili. Biz grep
AT_PLATFORM için, ama sadece son satırı tutuyoruz.
Ayrıştırma yardımcısı : Eğer auxv
yapıyı kendiniz ayrıştırırsanız (dinamik yükleyiciye güvenmiyorsanız ), o zaman biraz bir muamma vardır: auxv
yapı açıkladığı sürecin kuralını takip eder, bu yüzden sizeof(unsigned long)
32 bit işlemler için 4 ve 64 için 8 olacaktır bit süreçleri. Bu işi bizim için yapabiliriz. Bunun 32 bit sistemlerde çalışabilmesi için tüm anahtar kodlarının 0xffffffff
veya daha azının olması gerekir . 64 bit sistemde, en önemli 32 bit sıfır olacaktır. Intel makineleri küçük endianlardır, bu nedenle bu 32 bit bellekteki en az önemli olanları takip eder.
Bu nedenle, tek yapmanız gereken:
1. Read 16 bytes from the `auxv` file.
2. Is this the end of the file?
3. Then it's a 64-bit process.
4. Done.
5. Is buf[4], buf[5], buf[6] or buf[7] non-zero?
6. Then it's a 32-bit process.
7. Done.
8. Go to 1.
Maps dosyasını ayrıştırma : Gilles tarafından önerildi, ancak işe yaramadı. İşte değiştirilmiş bir sürümü. /proc/$PID/maps
Dosyayı okumaya dayanır . Dosya 64 bit adresleri listeliyorsa, işlem 64 bittir. Aksi takdirde, 32 bittir. Sorun, çekirdeğin, 4'lü gruplar halinde onaltılık adreslerden önde gelen sıfırları sıyırarak çıktıyı basitleştireceği, böylece uzunluk kesmek oldukça işe yaramayacağıdır. awk
kurtarmak için:
if ! [ -e /proc/$pid/maps ]; then
echo "No such process"
else
case $(awk </proc/$pid/maps -- 'END { print substr($1, 0, 9); }') in
*-) echo "32 bit process";;
*[0-9A-Fa-f]) echo "64 bit process";;
*) echo "Insufficient permissions.";;
esac
fi
Bu işlemin son hafıza haritasının başlangıç adresini kontrol ederek çalışır. Onlar gibi listelenir 12345678-deadbeef
. İşlem 32 bit ise, bu adres sekiz onaltılık basamak uzunluğunda olacak ve dokuzuncu da kısa çizgi olacaktır. 64 bit bir adresse, en yüksek adres bundan daha uzun olacaktır. Dokuzuncu karakter onaltılık bir rakam olacaktır.
Dikkat edin: auxv
dosya daha önce bulunmadığından , ilk ve son yöntemler hariç tümü Linux çekirdeği 2.6.0 veya daha yenisine ihtiyaç duyar .
/proc/[pid]/auxv
: "ELF yorumlayıcı bilgileri işlem sırasında işleme geçirilir. Biçim bir işaretsiz uzun kimlik artı her giriş için bir işaretsiz uzun değerdir" (man proc
).