উত্তর:
dlopen
কোনও সিস্টেম কল নয়, এটি libdl লাইব্রেরিতে একটি লাইব্রেরি ফাংশন । কেবলমাত্র সিস্টেম কলগুলি প্রদর্শিত হবে strace
।
লিনাক্স এবং অন্যান্য অনেক প্ল্যাটফর্মে (বিশেষত যারা এক্সিকিউটেবলের জন্য ইএলএফ ফর্ম্যাট ব্যবহার করেন) dlopen
লক্ষ্যবস্তু লাইব্রেরিটি open()
এটির সাথে ম্যাপ করে মেমরির মাধ্যমে ম্যাপ করে প্রয়োগ করা হয় mmap()
। mmap()
সত্যিই এখানে সমালোচনামূলক অংশ, এটি প্রক্রিয়াটির ঠিকানা জায়গাতে গ্রন্থাগারকে অন্তর্ভুক্ত করে, তাই সিপিইউ তার কোডটি কার্যকর করতে পারে। তবে open()
ফাইলটি করার আগে আপনার mmap()
এটি করতে হবে!
ld-linux
এবং execve
সিস্টেম কলের অংশ হিসাবে কার্নেল দ্বারা ম্যাপ করা হয়েছে ।
dlopen ভাগ করা লাইব্রেরিগুলির সাথে তাদের ভাবার সাথে কিছুই করার নেই। ভাগ করা বস্তুটি লোড করার দুটি পদ্ধতি রয়েছে:
main
ডেকে আনা হবে এবং অ্যাপ্লিকেশনটির প্রক্রিয়া স্থান সেট আপ করবে যাতে অ্যাপ্লিকেশনটি গ্রন্থাগারের কাজগুলি সন্ধান করতে পারে। এর open()
মধ্যে লুব্রির আইএন জড়িত করা এবং তারপরে mmap()
এটি যুক্ত করা, তারপরে কিছু অনুসন্ধান সারণী স্থাপন করা।libdl
, যেখান থেকে আপনি (প্রথম পদ্ধতিটি ব্যবহার করে) কল করতে পারেন dlopen()
এবংdlsym()
ফাংশন। ড্লোপেনের সাহায্যে আপনি লাইব্রেরিতে একটি হ্যান্ডেল পাবেন যা আপনি পরে কোনও নির্দিষ্ট ফাংশনের ফাংশন পয়েন্টারটি পেতে dlsym দিয়ে ব্যবহার করতে পারেন। প্রথম পদ্ধতির চেয়ে প্রোগ্রামারটির জন্য এই পদ্ধতিটি আরও জটিল (যেহেতু আপনাকে নিজেরাই লিঙ্কারটি স্বয়ংক্রিয়ভাবে করতে হবে তার পরিবর্তে আপনাকে ম্যানুয়ালি সেটআপ করতে হবে), এবং এটি আরও ভঙ্গুর (যেহেতু আপনি সংকলনটি পান না) - প্রথম পরীক্ষার সাথে সাথে আপনি সঠিক যুক্তির ধরণগুলির সাথে ফাংশনগুলি কল করছেন কিনা তা যাচাই করে দেখবে) তবে সুবিধাটি হ'ল রানটাইমের সময় কোন ভাগ করা বস্তুটি লোড করা হবে (বা এমনকি এটি মোটেও লোড করা হবে কিনা) তা আপনি সিদ্ধান্ত নিতে পারেন এটি একটি ইন্টারফেস প্লাগইন টাইপ কার্যকারিতা জন্য বোঝানো। পরিশেষে, ড্লোপেন ইন্টারফেসটি অন্য উপায়ের চেয়ে কম পোর্টেবলও হয়, কারণ এর যান্ত্রিকগুলি ডায়নামিক লিঙ্কারের সঠিক প্রয়োগের উপর নির্ভর করে (অতএব লিবিটোলেরlibltdl
, যা এই পার্থক্যগুলি বিমূর্ত করার চেষ্টা করে)।বর্তমানে, বেশিরভাগ অপারেটিং সিস্টেমগুলি সানোস -৪.০ দ্বারা শিরোনামে 1987 সালের শেষে ভাগ করা লাইব্রেরিগুলির জন্য পদ্ধতিটি ব্যবহার করে। এই পদ্ধতিটি এমএমএপ () এর মাধ্যমে ম্যাপিং মেমোরিয়ের উপর ভিত্তি করে।
১৯৯০ এর দশকের গোড়ার দিকে, সান এমনকি ফ্রিবিএসডি লোকদের জন্য পুরানো a.out ভিত্তিক কোড (তৎকালীন সোলারিস ইতিমধ্যে ইএলএফ ভিত্তিক ছিল) দান করেছিলেন এবং এই কোডটি পরে আরও অনেক সিস্টেমে (লিনাক্স সহ) হস্তান্তর করা হয়েছিল , প্ল্যাটফর্মগুলির মধ্যে কেন কোনও বড় পার্থক্য নেই তা আপনি বুঝতে পারেন।
ltrace -S
একটি সর্বনিম্ন উদাহরণ বিশ্লেষণ দেখায় যে mmap
glibc 2.23 ব্যবহার করা হয়
গ্লিবসি ২.২৩ এ, উবুন্টু ১.0.০৪, latrace -S
একটি ন্যূনতম প্রোগ্রামে চলছে যা এর সাথে ব্যবহার dlopen
করে:
ltrace -S ./dlopen.out
শো:
dlopen("libcirosantilli_ab.so", 1 <unfinished ...>
SYS_open("./x86_64/libcirosantilli_ab.so", 524288, 06267650550) = -2
SYS_open("./libcirosantilli_ab.so", 524288, 06267650550) = 3
SYS_read(3, "\177ELF\002\001\001", 832) = 832
SYS_brk(0) = 0x244c000
SYS_brk(0x246d000) = 0x246d000
SYS_fstat(3, 0x7fff42f9ce30) = 0
SYS_getcwd("/home/ciro/bak/git/cpp-cheat"..., 128) = 54
SYS_mmap(0, 0x201028, 5, 2050) = 0x7f1c323fe000
SYS_mprotect(0x7f1c323ff000, 2093056, 0) = 0
SYS_mmap(0x7f1c325fe000, 8192, 3, 2066) = 0x7f1c325fe000
SYS_close(3) = 0
SYS_mprotect(0x7f1c325fe000, 4096, 1) = 0
সুতরাং আমরা অবিলম্বে দেখতে পাই যে dlopen
কল open
+ mmap
।
দুর্দান্ত ltrace
সরঞ্জাম দুটি গ্রন্থাগার কল এবং সিস্টেম কল উভয়ই সনাক্ত করে এবং তাই এই ক্ষেত্রে কী চলছে তা পরীক্ষা করার জন্য এটি নিখুঁত।
একটি নিবিড় বিশ্লেষণ দেখায় যে open
ফাইল বর্ণনাকারী 3
(স্টিডিনের পরে পরের ফ্রিটি, আউট এবং এরর) রিটার্ন দেয় ।
read
তারপরে সেই ফাইল বর্ণনাকারী ব্যবহার করে, তবে কেন চার্জের মধ্যে mmap
যুক্তি সীমাবদ্ধ তা করণীয় এবং আমরা দেখতে পাচ্ছি না যে 5 তম আর্গুমেন্ট হওয়ায় সেখানে কোন এফডি ব্যবহৃত হয়েছিল । strace
প্রত্যাশিত হিসাবে 3
একটিকে নিশ্চিত করে এবং মহাবিশ্বের ক্রম পুনঃস্থাপন করা হয়।
সাহসী আত্মারাও গ্লিবিসি কোডে প্রবেশ করতে পারে, তবে আমি mmap
দ্রুত গ্রেপ করার পরেও খুঁজে পাইনি এবং আমি অলস।
গিটহাবে বিল্ড বয়লারপ্লেট সহ এই সর্বনিম্ন উদাহরণের সাথে পরীক্ষিত ।
strace
সিস্টেম কল সম্পর্কিত প্রতিবেদন (যেমন কার্নেল দ্বারা সরাসরি প্রয়োগ করা হয়)। ডায়নামিক লাইব্রেরিগুলি কোনও কার্নেল ফাংশন নয়; dlopen
সি লাইব্রেরির অংশ, কার্নেল নয়। dlopen
উইল কলটি প্রয়োগ করা open
(যা একটি সিস্টেম কল) লাইব্রেরির ফাইলটি খুলতে যাতে এটি পড়তে পারে।
ltrace
।
ltrace -S
এটি বিশ্লেষণে নিখুঁত কারণ এটি সাইককলগুলিও