নির্দিষ্ট প্রক্রিয়াটি 32- বা 64-বিট হয় তা নির্ধারণ করুন


14

একটি 2.6.x বা নতুন লিনাক্স কার্নেল এবং বিদ্যমান ইউজারল্যান্ড দেওয়া হয়েছে যা ELF32 এবং ELF64 বাইনারি উভয়ই চালাতে সক্ষম (যেমন ভাল অতীত আমি কীভাবে জানতে পারি যে আমার সিপিইউ লিনাক্সের অধীনে 64 বিট অপারেটিং সিস্টেমকে সমর্থন করে? ) আমি প্রদত্ত প্রক্রিয়াটি কীভাবে নির্ধারণ করতে পারি ( পিআইডি দ্বারা) 32- বা 64-বিট মোডে চলছে?

নিষ্পাপ সমাধানটি চালানো হবে:

file -L /proc/pid/exe | grep -o 'ELF ..-bit [LM]SB'

কিন্তু সেই তথ্যটি কি /procনির্ভর করেই সরাসরি প্রকাশ করা হয় libmagic?

উত্তর:


21

আপনি ELF সনাক্তকরণ নিজেকে সীমিত করতে চান, আপনি পড়তে পারেন ELF হেডারের এর /proc/$PID/exeনিজের। এটি বেশ তুচ্ছ: যদি ফাইলে 5 ম বাইট 1 হয় তবে এটি 32-বিট বাইনারি হয়। যদি এটি 2 হয় তবে এটি 64-বিট। স্যানিটি যুক্ত করার জন্য:

  1. যদি প্রথম 5 বাইট হয় 0x7f, "ELF", 1: এটি 32 বিট ইএলএফ বাইনারি।
  2. যদি প্রথম 5 বাইট হয় 0x7f, "ELF", 2: এটি একটি 64 বিট ইএলএফ বাইনারি।
  3. অন্যথায়: এটি অনির্বাচিত।

আপনি এটিও ব্যবহার করতে পারেন objdumpতবে এটি আপনার libmagicনির্ভরতা কেড়ে নেয় এবং এটির সাথে এটি প্রতিস্থাপন করে libelf

অন্য উপায় : আপনি /proc/$PID/auxvফাইলটি বিশ্লেষণ করতে পারেন । মতে proc(5):

এটিতে কার্যকর সময় প্রক্রিয়ায় প্রেরিত ইএলএফ ইন্টারপ্রেটার তথ্যের সামগ্রী রয়েছে। ফর্ম্যাটটি হ'ল একটি স্বাক্ষরযুক্ত লম্বা আইডি প্লাস প্রতিটি প্রবেশের জন্য একটি স্বাক্ষরযুক্ত দীর্ঘ মান long শেষ এন্ট্রিটিতে দুটি শূন্য রয়েছে।

unsigned longকীগুলির অর্থ /usr/include/linux/auxvec.h। আপনি চান AT_PLATFORM, যা 0x00000f। সে সম্পর্কে আমাকে উদ্ধৃতি দেবেন না, তবে এটি char *প্ল্যাটফর্মের স্ট্রিংয়ের বিবরণ পেতে মানটি ব্যাখ্যা করা উচিত বলে মনে হয় ।

আপনি এই স্ট্যাকওভারফ্লো প্রশ্নটি দরকারী মনে করতে পারেন।

তবুও অন্য উপায় : আপনি কার্যকর করতে হবে এমন man ldতথ্য ডাম্প করার জন্য ডায়নামিক লিঙ্কারকে ( ) নির্দেশ করতে পারেন । এটি স্ট্যান্ডার্ড আউটপুটে ডিকোডড এউএক্সভি কাঠামো প্রিন্ট করে। সতর্কতা: এটি হ্যাক, তবে এটি কার্যকর।

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)it ডাউনসাইড: 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৪ বিট। অন্যথায়, এটি 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৪-বিট এক হয় তবে সর্বোচ্চ ঠিকানাটি এর চেয়ে দীর্ঘ হবে। নবম বর্ণটি হেক্স ডিজিটের হবে।

সচেতন হন: প্রথম এবং শেষ পদ্ধতিগুলি বাদে লিনাক্স কার্নেল ২.6.০ বা আরও নতুন প্রয়োজন, যেহেতু auxvফাইলটি আগে ছিল না।


1
হুঁ, আমি ভাবছি যদি ELF হেডারের মধ্যে হয় /proc/[pid]/auxv: "। Exec সময়ে প্রক্রিয়া প্রেরণ ELF অনুবাদক তথ্য বিন্যাস এক স্বাক্ষরবিহীন দীর্ঘ আইডি প্লাস প্রতিটি এন্ট্রির জন্য এক স্বাক্ষরবিহীন দীর্ঘ মান হল" ( man proc)।
স্বর্ণলোক

1
শিরোনাম নিজেই না। আমি কেবল hdএকটি সম্পাদনা করেছি এবং এতে যাদু সংখ্যার অভাব রয়েছে। সেখানে কিছু প্রাসঙ্গিক তথ্য থাকতে পারে তবে আমি মনে করি এটি নিজেই ইএলএফ শিরোনামের চেয়ে আরও ঘন ঘন পরিবর্তনের বিষয় হতে পারে। এটি ২.6.০ এও চালু হয়েছিল, সুতরাং এটি মোটামুটি সর্বব্যাপী নয় /proc/PID/exe। কিন্তু এটা না স্থাপত্য তথ্য নেই। আমি আমার উত্তর আপডেট করব।
অ্যালেক্সিয়স

auxv আমার প্রত্যাশার চেয়ে কৌতুকপূর্ণ হয়ে উঠেছে - sizeof(unsigned long)এটি on৪ বিট বা on 32 বিট এর 4, যার অর্থ সঠিকভাবে এটি ব্যাখ্যা করতে গেলে আপনাকে জানতে হবে প্রক্রিয়াটি 64 বিট বা 32 বিট দিয়ে শুরু হয় কিনা!
ফ্লেক্সো

তুমি একেবারেই সঠিক. এটা বেশ বিরক্তিকর। দ্রুত হিউরিস্টিক: ফাইলে যদি বাইটস 16x + y (4≤y≤7) সব শূন্য হয়, আপনি একটি 64-বিট নির্বাহযোগ্যকে দেখছেন। এটি একটি ক্লোডেজ: আমি একটু এন্ডিয়ান মেশিন ধরে নিয়েছি, এবং সমস্ত auxvকী কোডগুলি 32-বিট ফিট করে unsigned long, তাই 64-বিট বাক্সে সর্বাধিক উল্লেখযোগ্য 32-বিট শূন্য হবে।
অ্যালেক্সিয়াস 21

6

ভিতরে তাকান /proc/$pid/maps। ঠিকানার ব্যাপ্তিগুলি 32-বিট ঠিকানা (8 হেক্সাডেসিমাল ডিজিট) বা 64-বিট ঠিকানা (16 হেক্সাডেসিমাল অঙ্ক) এর বেশি। এটি কোনও ধরণের এক্সিকিউটেবলের পক্ষে কাজ করে, তা কোনও ফর্ম্যাটই নয়। আপনি কেবল একই ব্যবহারকারী হিসাবে চলমান প্রক্রিয়াগুলি সম্পর্কে তথ্য পেতে পারেন (যদি না আপনি মূল হন)।

if ! [ -e /proc/$pid/maps ]; then
  echo No such process
elif grep -q '^........[^-]' /proc/$pid/maps; then
  echo 64-bit
elif grep -q . /proc/$pid/maps; then
  echo 32-bit
else
  echo Insufficient permissions
fi

আপনার যদি এই ফাইলটি অ্যাক্সেস করার অনুমতি নেই তবে আমি মনে করি একমাত্র উপায় হ'ল নির্বাহী বিশ্লেষণ করার চেষ্টা করা। (আপনি যখন সর্বদা পড়তে পারেন /proc/$pid/statতবে বিভিন্ন ব্যবহারকারী হিসাবে চলমান প্রক্রিয়াগুলির জন্য প্রদর্শিত ক্ষেত্রগুলির কোনওটিই প্রক্রিয়াটির বিট আকার প্রকাশ করে না)) আপনি প্রক্রিয়াটির সম্পাদনযোগ্য ps -o comm=, এবং এটিতে সন্ধানের বিষয়ে ভাল অনুমান করতে পারেন PATH- তবে সাবধান থাকুন যে প্রক্রিয়াটি অন্যরকম দিয়ে চালু করা PATHহতে পারে, বা এটি আবার লিখতে পারে argv[0]। তারপরে আপনি এক্সিকিউটেবল বিশ্লেষণ করতে পারেন - আপনি যদি ইএলএফ ধরে নিতে রাজি হন তবে 5 তম বাইটটি দেখুন


আমি আপনার রেসিপি পরীক্ষা করেছি এবং এটি ব্যর্থ হয়েছে। ওপেনসুসি 12.2, x86-64, কার্নেল 3.4.63-2.44- ডিফল্ট, / বিন / ব্যাশ। বাইনারি এবং প্রথম হিপগুলির জন্য / proc / $ পিড / মানচিত্রের লাইনগুলি 32-বিট স্টাইলে লেখা হয়, তবে অন্য সমস্তগুলি 64-বিট শৈলীতে থাকে। সম্ভবত তারা "% 08x" ব্যবহার করে মুদ্রিত হয় তবে যাইহোক এই রেসিপিটি সামঞ্জস্য করা হবে।
নেট

আমি যে সমস্ত বাক্স দিয়ে চেষ্টা করেছি সেগুলিতে আমি 8, 12 এবং 16-পাখির মানগুলির মিশ্রণ পাচ্ছি। উত্সটি পরীক্ষা না করে, আমার অনুমান যে কার্নেলটি মুদ্রিত প্রতিটি লাইনের জন্য অ্যাড্রেস রেঞ্জের চেয়ে 16-বিটের বৃহত্তর একাধিকের সাথে প্যাডিং সামঞ্জস্য করে, তাই আপনাকে হেক্স অক্ষরের দীর্ঘতম সিকোয়েন্সটি খুঁজে বের করতে হবে, তারপরে চেক করুন।
অ্যালেক্সিয়াস

কিন্তু, vsyscallমানচিত্রটি সর্বদা সর্বোচ্চ হিসাবে, আপনি কেবল পরিবর্তিত headহয়ে পালাতে পারেন tail- যা দুঃখের বিষয়, প্র্যাক বাস্তবায়িত হয়নি বলে কাজ করবে না seek(2), সুতরাং এটি কিছুটা কুরুচিপূর্ণ হতে হবে, যেমনawk /proc/self/maps -- 'END { print substr($1, 0, 9); }'
অ্যালেক্সিয়ো

@ নেট প্রকৃতপক্ষে, আমি বোকামির সাথে ভিসস্কল এবং স্ট্যাক লাইনগুলিতে তাকিয়েছিলাম এবং কার্যকরকারীদের ম্যাপিংয়ের দিকে মনোযোগ দিই নি। ধন্যবাদ, আমি কোনও 32-বিট লাইনের সন্ধানের জন্য আপডেট করেছি। মমত্ববোধ, এটি কৃপণ, তবে এটি সবচেয়ে নির্ভরযোগ্য (কমপক্ষে এটি x86- এ নিশ্চিত-আগুন, আমি স্পার্ক এবং আর্মের মতো অন্যান্য দ্বৈত স্থাপত্যগুলির সাথে পরীক্ষা করিনি) n't
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.