यदि आप खुद को ELF डिटेक्शन तक सीमित रखना चाहते हैं, तो आप खुद का ELF हेडर पढ़ सकते हैं /proc/$PID/exe
। यह काफी तुच्छ है: यदि फ़ाइल में 5 वीं बाइट 1 है, तो यह 32-बिट बाइनरी है। यदि यह 2 है, तो यह 64-बिट है। अतिरिक्त संन्यास जाँच के लिए:
- यदि पहले 5 बाइट्स हैं
0x7f, "ELF", 1
: यह एक 32 बिट ईएलएफ बाइनरी है।
- यदि पहले 5 बाइट्स हैं
0x7f, "ELF", 2
: यह 64 बिट ईएलएफ बाइनरी है।
- अन्यथा: यह अनिर्णायक है।
आप भी उपयोग कर सकते हैं objdump
, लेकिन यह आपकी libmagic
निर्भरता को दूर ले जाता है और इसे एक के साथ बदल देता है libelf
।
दूसरा तरीका : आप /proc/$PID/auxv
फ़ाइल को पार्स भी कर सकते हैं । के अनुसार proc(5)
:
इसमें ईएलएफ दुभाषिया जानकारी शामिल है जो प्रक्रिया के समय निष्पादित की जाती है। प्रारूप एक अहस्ताक्षरित लंबी ID है और प्रत्येक प्रविष्टि के लिए एक अहस्ताक्षरित लंबी मान है। अंतिम प्रविष्टि में दो शून्य हैं।
unsigned long
कुंजियों के अर्थ में हैं /usr/include/linux/auxvec.h
। तुम चाहते हो AT_PLATFORM
, जो है 0x00000f
। उस पर मुझे उद्धृत न करें, लेकिन ऐसा लगता है कि मूल्य को char *
प्लेटफॉर्म के स्ट्रिंग विवरण को प्राप्त करने के लिए व्याख्या किया जाना चाहिए ।
आपको यह StackOverflow प्रश्न उपयोगी लग सकता है।
फिर भी एक और तरीका : आप गतिशील लिंकर ( man ld
) को निष्पादन योग्य के बारे में जानकारी डंप करने का निर्देश दे सकते हैं । यह मानक आउटपुट को डिकोड किए गए AUXV संरचना को प्रिंट करता है। चेतावनी: यह एक हैक है, लेकिन यह काम करता है।
LD_SHOW_AUXV=1 ldd /proc/$SOME_PID/exe | grep AT_PLATFORM | tail -1
यह कुछ इस तरह दिखाएगा:
AT_PLATFORM: x86_64
मैंने इसे 32-बिट बाइनरी पर आज़माया और इसके i686
बजाय मिला ।
यह कैसे काम करता है: LD_SHOW_AUXV=1
निष्पादन योग्य चलाने से पहले डीकोड किए गए एयूएक्सवी संरचना को डंप करने के लिए डायनामिक लिंकर को निर्देश देता है। जब तक आप वास्तव में अपने जीवन दिलचस्प बनाने के लिए चाहते हैं, तो आप से बचना चाहते हैं वास्तव में चल रहा निष्पादन कहा। लोड करने और गतिशील रूप से लिंक करने का एक तरीका वास्तव में अपने main()
फ़ंक्शन को कॉल किए बिना ldd(1)
उस पर चलना है। नकारात्मक पक्ष: LD_SHOW_AUXV
शेल द्वारा सक्षम किया गया है, इसलिए आपको इसके लिए AUXV संरचनाओं के डंप मिलेंगे: सबस्क्रिप्शन ldd
, और आपका लक्ष्य बाइनरी। तो हम grep
AT_PLATFORM के लिए, लेकिन केवल अंतिम पंक्ति रखते हैं।
पार्सिंग ऑक्सव : यदि आप auxv
संरचना को खुद को पार्स करते हैं (डायनेमिक लोडर पर निर्भर नहीं), तो इसमें थोड़ी गड़बड़ी है : संरचना auxv
उस प्रक्रिया के नियम का पालन करती है, इसलिए sizeof(unsigned long)
32-बिट प्रक्रियाओं के लिए 4 और 64 के लिए 8 होगी -बिट प्रक्रियाएं। यह काम हम अपने लिए कर सकते हैं। 32-बिट सिस्टम पर काम करने के लिए, सभी कुंजी कोड 0xffffffff
कम या ज्यादा होने चाहिए । 64-बिट सिस्टम पर, सबसे महत्वपूर्ण 32 बिट्स शून्य होगा। इंटेल मशीन थोड़े एंडियन हैं, इसलिए ये 32 बिट्स मेमोरी में कम से कम महत्वपूर्ण हैं।
जैसे, आपको बस इतना करना है:
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.
मैप्स फ़ाइल को पार्स करना : यह गिल्स ने सुझाया था, लेकिन काफी काम नहीं किया। यहाँ एक संशोधित संस्करण है जो करता है। यह /proc/$PID/maps
फ़ाइल को पढ़ने पर निर्भर करता है । यदि फ़ाइल 64-बिट पतों को सूचीबद्ध करती है, तो प्रक्रिया 64 बिट्स है। अन्यथा, यह 32 बिट्स है। समस्या यह है कि कर्नेल 4 के समूहों में हेक्स पतों से अग्रणी जीरो को अलग करके आउटपुट को सरल करेगा, इसलिए लंबाई हैक काफी काम नहीं कर सकता है। awk
बचाव के लिए:
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
यह प्रक्रिया के अंतिम मेमोरी मैप के शुरुआती पते की जांच करके काम करता है। वे की तरह सूचीबद्ध हैं 12345678-deadbeef
। इसलिए, यदि प्रक्रिया एक 32-बिट है, तो वह पता आठ हेक्स अंक लंबा होगा, और नौवां एक हाइमेन होगा। यदि यह 64-बिट वाला है, तो उच्चतम पता इससे अधिक लंबा होगा। नौवां वर्ण हेक्स अंक होगा।
ध्यान रखें: पहले और आखिरी तरीकों को लिनक्स कर्नेल 2.6.0 या नए की जरूरत है, क्योंकि auxv
फ़ाइल पहले नहीं थी।
/proc/[pid]/auxv
: "ईएलएफ दुभाषिया जानकारी निष्पादन समय पर प्रक्रिया के लिए पारित कर दिया। प्रारूप एक अहस्ताक्षरित लंबी आईडी है और प्रत्येक प्रविष्टि के लिए एक अहस्ताक्षरित लंबी कीमत है" (man proc
)।