Http : //www.linuxj Journal.com/content/e এম্বেডিং- ফাইল- এক্সেকটেটেবল- aka- hello- world- version- 5967 থেকে :
আমার সম্প্রতি এক্সিকিউটেবলের মধ্যে একটি ফাইল এম্বেড করার প্রয়োজন হয়েছিল। যেহেতু আমি কমান্ড লাইনে জিসিসি, এট আল দিয়ে কাজ করছি না এবং কোনও অভিনব আরএডি সরঞ্জামের সাথে নয় যা এই সমস্ত ঘটনাকে যাদু করে তোলে তা কীভাবে এটি করা যায় তা তাত্ক্ষণিকভাবে আমার কাছে স্পষ্ট ছিল না। নেটে অনুসন্ধানের একটি বিটটি কার্যকরভাবে এটি কার্যকর করার শেষের দিকে বিড়াল দেওয়ার জন্য একটি হ্যাক পেয়েছিল এবং তারপরে এটি যেটি সম্পর্কে আমি জানতে চাই না সেগুলি গুচ্ছ তথ্যের উপর ভিত্তি করে কোথায় তা নির্ধারণকারী। দেখে মনে হয়েছিল এর চেয়ে ভাল উপায় হওয়া উচিত ...
এবং আছে, এটি উদ্ধারের জন্য অবজকপি। cজকপিটি অবজেক্ট ফাইল বা এক্সিকিউটেবলকে এক ফর্ম্যাট থেকে অন্য রূপান্তর করে। এটি যে ফর্ম্যাটগুলি বোঝে তার মধ্যে একটি হ'ল "বাইনারি", যা মূলত এমন কোনও ফাইল যা এটি বোঝে অন্য ফর্ম্যাটগুলির মধ্যে একটিতে নেই। সুতরাং আপনি সম্ভবত ধারণাটি কল্পনা করেছেন: যে ফাইলটিকে আমরা কোনও অবজেক্ট ফাইলে এম্বেড করতে চাই তা রূপান্তর করুন, তবে এটি কেবল আমাদের বাকী কোডের সাথে যুক্ত করা যেতে পারে।
ধরা যাক আমাদের একটি ফাইলের নাম ডেটা রয়েছে t টেক্সট যা আমরা আমাদের এক্সিকিউটেবল এম্বেড করতে চাই:
# cat data.txt
Hello world
এটিকে আমাদের প্রোগ্রামের সাথে লিঙ্ক করতে পারে এমন একটি অবজেক্ট ফাইলে রূপান্তর করতে আমরা একটি ".o" ফাইল তৈরি করতে কেবল অবজকপি ব্যবহার করি:
# objcopy --input binary \
--output elf32-i386 \
--binary-architecture i386 data.txt data.o
এটি অবজকপিটিকে বলেছে যে আমাদের ইনপুট ফাইলটি "বাইনারি" ফর্ম্যাটে রয়েছে, আমাদের আউটপুট ফাইলটি "এলএফ 32-আই 386" ফর্ম্যাটে থাকতে হবে (x86 এ অবজেক্ট ফাইলগুলি)। --Binary - আর্কিটেকচার বিকল্পটি অ্যাজবকপিটিকে বলে যে আউটপুট ফাইলটি একটি x86-তে "চালানো"। এটি প্রয়োজনীয় যাতে ld x86 এর সাথে অন্য ফাইলগুলির সাথে লিঙ্ক করার জন্য ফাইলটি গ্রহণ করবে। কেউ ভাবেন যে "elf32-i386" হিসাবে আউটপুট ফর্ম্যাটটি নির্দিষ্ট করা এটি বোঝাতে পারে, তবে তা তা নয়।
এখন যেহেতু আমাদের একটি অবজেক্ট ফাইল রয়েছে কেবলমাত্র আমরা লিঙ্কারটি চালানোর সময় এটি অন্তর্ভুক্ত করা দরকার:
# gcc main.c data.o
আমরা ফলাফলটি চালানোর সময় আমরা আউটপুটটির জন্য প্রার্থনা করি:
# ./a.out
Hello world
অবশ্যই, আমি এখনও পুরো ঘটনাটি বলিনি, বা আপনাকে দেখায়নি মেন। যখন অ্যাজজকপি উপরের রূপান্তরটি করে তখন রূপান্তরিত অবজেক্ট ফাইলে এটি "লিঙ্কার" চিহ্নগুলি যুক্ত করে:
_binary_data_txt_start
_binary_data_txt_end
লিঙ্ক করার পরে, এই চিহ্নগুলি এম্বেড করা ফাইলের শুরু এবং শেষ নির্দিষ্ট করে। প্রতীক নামগুলি বাইনারি প্রিফেন্ড করে এবং ফাইলের নাম _ স্টার্ট বা _ যুক্ত করে গঠিত হয় । যদি ফাইলের নামটিতে এমন কোনও অক্ষর থাকে যা প্রতীক নামটিতে অবৈধ হতে পারে তবে সেগুলি আন্ডারস্কোরগুলিতে রূপান্তরিত হয় (যেমন ডেটা.টিএসটিএসটি ডেটা_সেক্সট হয়ে যায়)। এই চিহ্নগুলি ব্যবহার করার সময় আপনি যদি অমীমাংসিত নামগুলি পান তবে অবজেক্ট ফাইলে একটি হেক্সডাম্প-সি করুন এবং অ্যাজজকপি যে নামগুলি চয়ন করেছেন তার জন্য ডাম্পের শেষে দেখুন।
এমবেড করা ফাইলটি ব্যবহার করার কোডটি এখন যুক্তিসঙ্গতভাবে সুস্পষ্ট হওয়া উচিত:
#include <stdio.h>
extern char _binary_data_txt_start;
extern char _binary_data_txt_end;
main()
{
char* p = &_binary_data_txt_start;
while ( p != &_binary_data_txt_end ) putchar(*p++);
}
একটি গুরুত্বপূর্ণ এবং সূক্ষ্ম বিষয় লক্ষনীয় যে অবজেক্ট ফাইলে যুক্ত চিহ্নগুলি "ভেরিয়েবল" নয়। এগুলিতে কোনও ডেটা থাকে না, বরং তাদের ঠিকানাটি তাদের মান। আমি তাদের টাইপ চর হিসাবে ঘোষণা করি কারণ এটি এই উদাহরণের জন্য সুবিধাজনক: এম্বেড করা ডেটা হ'ল চরিত্রের ডেটা। যাইহোক, আপনি এগুলি কিছু হিসাবে ঘোষণা করতে পারেন, ডাটা যদি পূর্ণসংখ্যার অ্যারে হয় তবে স্ট্রাক্ট foo_bar_t যদি ডেটা foo বারগুলির কোনও অ্যারে থাকে। যদি এম্বেড করা ডেটা অভিন্ন না হয় তবে চরটি সম্ভবত সবচেয়ে সুবিধাজনক: এর ডেটাটি নিন এবং পয়েন্টারটিকে যথাযথ প্রকারে কাস্ট করুন যখন আপনি ডেটা অতিক্রম করবেন।