موضوع مقاله: کتابخانه پیوند پویا | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # کتابخانه پیوند پویا | مقدمه: کتابخانه پیوند پویا (یا DLL)یک فرمت استاندارد پیاده‌سازی شده توسط مایکروسافت از مفهوم کتابخانه‌های مشترک در سیستم عامل‌های مایکروسافت ویندوز و OS / 2 است. | ## بخش 1: کتابخانه پیوند پویا | این کتابخانه‌ها معمولاً دارای فایل‌های DLL، OCX (برای کتابخانه‌های حاوی کنترل‌های اکتیو ایکس) یا DRV (برای رانندگان سیستم میراث) هستند. به عبارت دیگر برنامه نویسان می‌توانند توابعی مورد نیاز خود که در فایل‌های DLL قرار دارند را به برنامه خود لینک کنند و از آن استفاده کنند. از این فایل‌ها می‌توان در چندین برنامه به صورت همزمان هم استفاده کرد و در نتیجه این کار باعث افزایش کارایی برنامه نویسان و استاندارد درسیستم عامل می‌شود. پس زمینهٔ DLL اولین نسخه‌های مایکروسافت ویندوز، برنامه هارا در یک فضای آدرس واحد، باهم اجرا می‌کرد. هر برنامه برای این درست شده بود تا به این صورت همکاری کند که CPU را به برنامه‌های دیگر هم برساند (yield کند)، تا رابط کاربری گرافیکی (GUI) بتواند چند کا را با هم انجام دهد و حداکثر پاسخگویی را داشته باشد. این لایه‌های اضافی در بالای DOS باید در همه برنامه‌های در حال اجرای ویندوز به اشتراک گذاشته می‌شد، نه فقط برای فعال کردن ویندوز برای کار در یک ماشین با کمتر از یک مگابایت RAM، بلکه برای فعال کردن برنامه‌ها برای همکاری با یکدیگر. کد در GDI نیاز داشت تا دستورات رسم را به یکسری عملیات در دستگاه‌های خاص ترجمه کند. هنگام طراحی به یک چاپگر، درخواست API باید به درخواست‌هایی به یک چاپگر تبدیل می‌شد. اگر چه می‌توانست امکان‌پذیر باشد که پشتیبانی سخت‌افزاری برای مجموعه محدودی از دستگاه‌ها (مانند صفحه نمایش رنگی گرافیک آداپتور، پرینتر لیزریجت چاپگر فرمان زبان) فراهم شود، مایکروسافت رویکردی متفاوت انتخاب کرد. GDI با بارگیری قطعات مختلفی از کد، به نام " درایور دستگاه "، برای کار با دستگاه‌های خروجی مختلف کار می‌کرد. در یک کتابخانه «استاتیک» معمولی (که مشترک(shared) نباشد)، به سادگی بخش‌های کد به برنامهٔ فراخوانی شده اضافه می‌شوند، زمانی که فایل اجرایی آن در مرحله «اتصال» ساخته شده‌است؛ اگر دو برنامه با یک تابع را صدا بزنند، آن تابع در هر دو برنامه، در مرحله اتصال هر دو، گنجانده می‌شود. برنامه‌هایی که این پرونده را فراخوانی می‌کنند در زمان اجرا، با سیستم عامل (یا، در مورد نسخه‌های اولیه ویندوز، OS-extension)، با اتصال به آن، مرتبط می‌شوند. برای نسخه‌های اولیه ویندوز (۱٫۰ تا ۳٫۱۱)، DLLها پایه و اساس کل رابط‌های کاربری گرافیکی (GUI) بودند. مفهوم ساخت سیستم عامل از مجموعه ای از کتابخانه‌های بارگذاری شده به صورت پویا، یک مفهوم اصلی ویندوز است که ادامه می‌یابد. DLLها مزایای استاندارد کتابخانه‌های به اشتراک گذاشته شده، مانند ماژولار بودن را فراهم می‌کنند. ماژولار بودن اجازه می‌دهد تا تغییرات در کد و داده‌ها در یک DLL خود درج و پر شده‌ای که توسط تعدادی نرم‌افزار مختلف بدون ایجاد هیچ تغییری در خود نرم‌افزارها به اشتراک گذاشته شده‌است، صورت گیرد. یک رابط واحد ممکن است توسعه یابد، که اجازه می‌دهد که ماژول‌های قدیمی و جدید به‌طور یکپارچه با هم در زمان اجرا متحد شوند و تبدیل شوند به برنامه‌های از قبل وجود داشته، بدون هیچ گونه تغییری در خود نرم‌افزار. در ویندوز x.1، 2.x و 3.x، تمام نرم‌افزارهای ویندوز یک فضای آدرس حافظه را به اشتراک می‌گذاشتند. از آن پس، تمام برنامه‌هایی که از کتابخانه استفاده می‌کردند می‌توانستند به آن دسترسی پیدا کنند. این می‌تواند به عنوان یک شکل غیرمستقیم ارتباطات بین فرایند مورد استفاده قرار گیرد، یا می‌تواند به‌طور تصادفی برنامه‌های مختلف را فاسد کند. با معرفی کتابخانه‌های ۳۲ بیتی در ویندوز ۹۵، هر فرایند در فضای آدرس خود اجرا می‌شود. در حالی که کد DLL ممکن است به اشتراک گذاشته شود، داده‌ها خصوصی هستند مگر اینکه داده‌های به اشتراک گذاشته شده، به‌طور صریح از سوی کتابخانه درخواست شوند. با توجه به این موضوع، نوارهای بزرگی از کتابخانه‌های ۱۶ بیتی از ویندوز ۹۵، ویندوز ۹۸ و ویندوز می ساخته شد که عملکرد ریز پردازنده‌های پنتیوم پرو را در هنگام شروع محدود کرد و در نهایت ثبات و مقیاس پذیری نسخه‌های مبتنی بر DOS را محدود کرد. اگر چه DLLها هسته معماری ویندوز هستند، اما آن‌ها دارای نقایص متعددی هستند که به‌طور کلی " جهنم دی‌ال‌ال " نامیده می‌شود. ، مایکروسافت NET چارچوب را رواج می‌دهد، به عنوان یک راه حل برای مشکلات DLL hell، اگر چه آن‌ها در حال حاضر راه حل‌های مبتنی بر مجازی سازی را مانند مایکروسافت مجازی کامپیوتر و مایکروسافت برنامه مجازی سازی رواج می‌دهند و آن به دلیل انعطاف‌پذیری بالاتر بین برنامه‌های کاربردی است. | ## بخش 2: کتابخانه پیوند پویا | ویژگی‌های DLL از آنجائیکه DLLها اساساً همان EXEها هستند، انتخاب آن برای تولید به عنوان بخشی از روند پیوند برای وضوح است، به این دلیل که ممکن است توابع و داده‌ها را از هر دوی آن‌ها بفرستد. امکان اجرای مستقیم DLL وجود ندارد، زیرا برای سیستم عامل نیاز به یک EXE است، تا بتواند آن را از هر نقطه ورود بارگذاری کند. DLLها مکانیسم لازم برای کد و داده مشترک را فراهم می‌کنند و با اینکار اجازه می‌دهند یک توسعه دهندهٔ کد/دادهٔ مشترک، بدون اینکه نیاز داشته باشد تا برنامه‌ها پیوند دوباره بخورند یا مجدداً کامپایل شوند، عملکرد خود را ارتقا دهد. از نقطه نظر توسعه نرم‌افزار، ویندوز و OS / 2 می‌توانند به عنوان مجموعه ای از DLLهایی که به روز رسانی شده‌اند، باشند که اجازه می‌دهد برنامه‌های کاربردی برای یک نسخه از سیستم عامل بدر یک نسخه دیگر آن نیز کار کند. DLLها در فضای حافظه در فرایند فراخوانی اجرا می‌شوند و با مجوزهای دسترسی برابر، که بدین معناست که در استفاده، آن‌ها کم هزینه هستند، اما همچنین به این معناست که اگر DLL هر گونه مشکلی داشته باشد، هیچ حفاظتی در فراخوانی EXE وجود ندارد. هر بخش مجموعه ای از ویژگی‌های خاص خود را دارد، از قبیل قابل خواندن و نوشتن، اجرایی بودن (برای کد) یا غیرقابل اجرایی بودن (برای داده‌ها) و غیره. کد در DLL معمولاً در میان تمام فرایندهای که از DLL استفاده می‌کنند به اشتراک گذاشته می‌شود؛ یعنی، آن‌ها یک مکان را در حافظه فیزیکی اشغال می‌کنند و در فضای صفحه فضایی نمی‌گیرند. اگر حافظه فیزیکی اشغال شده توسط یک بخش کد بخواهد بازسازی شود، محتویات آن حذف می‌شود و بعد از آن به‌طور مستقیم از فایل DLL به صورت مجدد بارگیری می‌شود. برخلاف بخش‌های کد، بخش داده‌های یک DLL معمولاً خصوصی هستند؛ یعنی هر فرایندی که از DLL استفاده می‌کند، یک کپی مخصوص از تمام داده‌های DLL دارد. به صورت اختیاری، بخش‌های داده می‌توانند به اشتراک گذاشته شوند، به این ترتیب می‌توان اجازه داد ارتباطات فرایند از طریق این فضای حافظهٔ به اشتراک گذاشته شده، صورت گیرند. به هر جهت، به دلیل اینکه محدودیت‌های کاربر برای استفاده از حافظه DLL مشترک اعمال نمی‌شود، این یک سوراخ امنیتی ایجاد می‌کند؛ یعنی یک فرایند می‌تواند داده‌های مشترک را خراب کند، که احتمالاً باعث می‌شود همه فرایندهای به اشتراک گذاری غیرمعمول رفتار کنند. به عنوان مثال، فرایندی که تحت یک حساب مهمان انجام می‌شود، می‌تواند به این ترتیب فرایند دیگری را که تحت یک حساب کاربری مجاز است خراب کند. اگر یک DLL با برخی بسته‌بندی‌های اجرایی خاص فشرده شود (به عنوان مثال UPX)، تمام بخش‌های کد آن به عنوان خواندن و نوشتن مشخص شده‌اند و به اشتراک گذاشته نمی‌شوند. بخش‌های خواندن و نوشتن کد، شبیه به بخش‌های داده‌های خصوصی، برای هر فرایند خصوصی هستند؛ بنابراین، DLLها با بخش‌های داده مشترک، اگر آن‌ها برای این در نظر گرفته شده باشند که به‌طور همزمان توسط چندین برنامه استفاده شوند، نباید فشرده شوند؛ چرا که هر نمونه از برنامه باید یک کپی خود از DLL را حمل کند که در نتیجه افزایش مصرف حافظه خواهد بود. فراخوانی کتابخانه‌ها همانند کتابخانه‌های استاتیک، کتابخانه‌های دخیل شده برای DLLها با فرمت فایل lib مشخص می‌شوند. پیوستن به کتابخانه‌های پویا معمولاً با اتصال به یک کتابخانه وارد شده و دخیل شده به آن رسیدگی می‌شود؛ هنگام ساختن یا متصل شدن برای ایجاد یک فایل اجرایی. سپس فایل اجرایی ساخته شده، حاوی یک جدول آدرس‌های دخیل (IAT) است که توسط آن تمام فراخوانی‌های عملکرد DLL ارجاع می‌شود. در زمان اجرا، IAT با آدرس‌های مناسب پر می‌شود که مستقیماً به یک تابع در DLL ای که جداگانه بارگذاری شده، اشاره می‌کند. رفع نماد و الزام آن هر تابعی که توسط یک DLL صادر می‌شود، توسط یک عدد ترتیبی و به صورت اختیاری، با یک نام شناسایی می‌شود. ترتیب آن نشان دهنده موقعیت نشانگر آدرس تابع در جدول آدرس‌های دخیل DLL یا همان IAT است. برای اکثر توابع API ویندوزها، فقط نام‌ها در نسخه‌های مختلف ویندوز حفظ می‌شوند؛ آن اعداد ترتیبی در معرض تغییر هستند؛ بنابراین، یکنفر نمی‌تواند با اعتماد کامل توابع API ویندوز را با اعدادش وارد کند. فراخوانی توابع با اعدادشان، تنها عملکرد آن را به مقدار خیلی کمی بهتر می‌کند در مقایسه با فراخوانی آن‌ها با نامشان: جداول صادر کردن DLLها با نامشان ترتیب بندی شده‌اند؛ بنابراین از جستجو باینری می‌توان برای پیدا کردن یک تابع استفاده کرد. سپس فهرست نام پیدا شده در این جستجو، مورد استفاده قرار می‌گیرد تا عدد آن را در جدول اعداد صادره رپیدا کند. در ویندوز ۱۶ بیتی، جدول نام طبقه‌بندی نشده بود، بنابراین هزینهٔ جستجوی نام بسیار قابل توجه بود. همچنین ممکن است که یک فایل اجرایی را به یک نسخه خاص از یک DLL متصل کنیم، این کار برای این است که آدرس‌های توابع فراخوانی شده در زمان کامپایل حل و فصل شوند. | ## بخش 3: کتابخانه پیوند پویا | برای توابع فراخوانی شدهٔ محدود، لینکر نشانهٔ زمانی و مجموع مقابله‌های DLL که فراخوانی در آن محدود است را ذخیره می‌کند. در زمان اجرا، ویندوز بررسی می‌کند که آیا همان نسخه از کتابخانه در حال استفاده است یا خیر، اگر اینطور بود، ویندوز از پردازش توابع فراخوانی شده جلوگیری می‌کند. در غیر این صورت، اگر کتابخانه با آن کتابخانه ای که به آن محدود شده بود متفاوت بود، ویندوز به‌طور عادی فراخوانده شده‌ها را پردازش می‌کند. فایل‌های اجرایی محدود شده به نحوی سریعتر بارگذاری می‌شوند اگر که در همان محیطی که برای کامپایل شدن آن‌ها بوده، اجرا شوند و دقیقاً در همان زمان اگر در محیطهای متفاوتی اجرا می‌شوند؛ بنابراین هیچ محدودیتی برای اتصال به فراخوانی شده‌ها وجود ندارد. به عنوان مثال، تمام برنامه‌های ویندوز استاندارد به DLLهای سیستم مربوط به آن نسخه از ویندوز محدود می‌شوند. یک فرصت خوب برای اتصال توابع فراخوانده شدهٔ یک نرم‌افزار به محیط هدف خود، در طول نصب نرم‌افزار است. این کار کتابخانه‌ها را تا ارسال نسخهٔ بعدی سیستم عامل محدود می‌کند؛ ولی مجموع مقابله‌های برنامهٔ اجرایی را تغییر می‌دهد؛ بنابراین چیزی نیست که بتوان با برنامه‌های امضا شده یا برنامه‌هایی که توسط یک ابزار مدیریت پیکربندی که از مجموع مقابله‌ها استفاده می‌کند (مانند چک‌های MD5) برای مدیریت نسخه‌های فایل انجام داد. همان‌طور که نسخه‌های جدید ویندوز دیگر آدرس‌های ثابت برای هر کتابخانه بارگذاری شده (به دلایل امنیتی) ندارند، فرصت و ارزش اتصال یک فایل اجرایی در حال کاهش است. فرایند پیوند صریح در زمان اجرا در هر زبانی که اشاره گرها به توابع را پشتیبانی می کند، یکی است. بارگیری تأخیری به‌طور معمول، یک نرم‌افزار که در مقابله با یک کتابخانه DLL مرتبط شده، اگر DLL پیدا نشود، شروع به کار نمی‌کند؛ زیرا ویندوز برنامه را اجرا نخواهد کرد مگر آنکه بتواند تمام DLLهایی را که ممکن است برنامه به آن نیاز داشته باشد، پیدا کند. با این حال یک برنامه ممکن است در مقابله با یک کتابخانه DLL مرتبط شود تا بخواهد بارگذاری کتابخانه پویا را به تأخیر بیندازد. اگر DLL را نتوان یافت یا بارگذاری کرد، یا تابع فراخوانده شده وجود نداشت، برنامه یک استثنا(Exception) ایجاد می‌کند که ممکن است پیدا شود و به درستی به آن رسیدگی شود. اگر برنامه به استثنائی رسیدگی نکند، توسط سیستم عامل به دام افتاده‌است که برنامه را با یک پیام خطا خاتمه می‌دهد. مکانیزم بارگیری تأخیر دار نیز قلاب‌های اطلاع‌رسانی را فراهم می‌کند که اجازه می‌دهد برنامه پردازش‌های اضافی یا خطا در هنگام بارگذاری را هنگامی که DLL و/یا هر گونه تابع DLL ای فراخوانده شده باشد، انجام دهد. این اجازه می‌دهد تا کاربر یک DLL استاندارد ویندوز را با استفاده از ویژوال بیسیک (نسخه ۶ یا پایین‌تر) ایجاد کند که می‌تواند از طریق بیانیه "اعلام(Declare)" اشاره شود. C و ++ C مایکروسافت ویژوال سی + +(MSVC) چند پسوند را برای استاندارد C ++ فراهم می‌کند که اجازه می‌دهد توابع به عنوان وارد شده یا صادر شده به‌طور مستقیم در کد سی ++مشخص شوند؛ این‌ها توسط کامپایلرهای ویندوز C و C ++، از جمله نسخه‌های ویندوز GCC بکار رفته‌است. توجه داشته باشید هنگامی که توابع C از C ++ قابل دسترسی است، آن‌ها همچنین باید به عنوان "extern "C در کد C ++ اعلام شوند تا کامپایلر را مطلع کنند که پیوند C باید استفاده شود. فایل LIB برای اتصال در مقابل یک DLL در زمان کامپایل استفاده می‌شود؛ برای پیوند زمان اجرا لازم نیست. سپس برنامه‌ها می‌توانند از DLLها با جستجو کردن GUID آن‌ها استفاده کنند تا مکان آن را پیدا کنند یا یک نمونه از شی COM را بسازند که به‌طور غیرمستقیم کلاس مشخص‌کنندهٔ آن و رابط مشخص‌کنندهٔ آن را استفاده کنند. مثال‌های برنامه‌نویسی استفاده از ایمپورتهای DLL مثال‌های زیر نشان می‌دهد که چگونه از خاصیت‌های خاص زبان استفاده کنید تا نمادهایی برای پیوند در مقابل یک DLL در زمان کامپایل اضافه کنید. زبان سی هشدار: کد زیر آسیب‌پذیر است؛ آن را با راهنمایی مایکروسافت برای بارگذاری ایمن کتابخانه مطابقت ندارد. این مکانیسم‌ها برای تعیین مکان و نسخه آن فایل‌ها و همچنین توضیح زبان مستقل و قابل خواندن در ماشین از رابط فراهم می‌کند. این اجازه می‌دهد که اشیاء COM برای پیاده‌سازی پشتی‌های قدرتمند به قسمت‌های جلویی GUI ساده مانند ویژوال بیسیک و ASP. در آگوست ۲۰۱۰، بعد از آنکه امنیت ACROS دوباره آن را کشف کرد و بعد از چندین صدها برنامه آسیب‌پذیر شد، آن را در سراسر جهان تبلیغ کرد. | ## جمع‌بندی | برنامه‌هایی که از مکان‌های ناامن اجرا می‌شوند، یعنی پوشه‌های قابل خواندن کاربر مانند دانلودها یا پوشه Temp، تقریباً همیشه به این آسیب‌پذیری حساس هستند.