کتابخانه پیوند پویا
کتابخانه پیوند پویا (یا DLL )یک فرمت استاندارد پیادهسازی شده توسط مایکروسافت از مفهوم کتابخانه های مشترک در سیستم عامل های مایکروسافت ویندوز و OS / 2 است. این کتابخانهها معمولاً دارای فایل های DLL
، OCX
(برای کتابخانههای حاوی کنترلهای اکتیو ایکس ) یا DRV
(برای رانندگان سیستم میراث) هستند. فرمتهای فایل DLLها همانند فایلهای ویندوز EXE است - یعنی قابل اجرا و قابل حمل (یا PE) برای ویندوزهای 32 بیتی و 64 بیتی و NE)New Executable) برای ویندوزهای 16 بیتی . همانند EXEها، DLLها میتوانند شامل کد، داده ها و منابع در هر ترکیبی از آنها باشند.
پسوند(های) نام پرونده | .dll |
---|---|
نوع رسانهٔ اینترنتی | application/vnd.microsoft.portable-executable |
شناسانه نوع یکسان | com.microsoft.windows-dynamic-link-library |
عدد جادویی | MZ |
توسعهدهنده | Microsoft |
دربرگیرنده | Shared library |
فایلهای داده با فرمت فایل DLL، اما با پسوندهای فایلی مختلف که احتمالاً هم فقط شامل بخش منابع باشند، میتوانند منابع DLL نامیده شوند. نمونههایی از چنین DLL شامل آیکون کتابخانه هاست که گاهی اوقات دارای پسوندICL
و فایلهای فونت، که دارای پسوندهای FON
و FOT
هستند، میشود.[1]
پس زمینه ی DLL
اولین نسخههای مایکروسافت ویندوز، برنامه هارا در یک فضای آدرس واحد، باهم اجرا میکرد. هر برنامه برای این درست شده بود تا به این صورت همکاری کند که CPU را به برنامههای دیگر هم برساند (yield کند)، تا رابط کاربری گرافیکی (GUI) بتواند چند کا را با هم انجام دهد و حداکثر پاسخگویی را داشته باشد. تمام عملیات سیستم عامل توسط سیستم عامل پایه ارائه شدهاست: MS-DOS . تمام خدمات سطح بالا توسط کتابخانههای ویندوز، همان "DLL"ها، ارائه شدهاست. API طراحی، رابط گرافیکی دستگاه (GDI)، در یک DLL با نام GDI.
EXE
پیادهسازی شدهاست، رابط کاربر در USER.
EXE
. این لایههای اضافی در بالای DOS باید در همه برنامههای در حال اجرای ویندوز به اشتراک گذاشته میشد، نه فقط برای فعال کردن ویندوز برای کار در یک ماشین با کمتر از یک مگابایت RAM، بلکه برای فعال کردن برنامهها برای همکاری با یکدیگر. کد در GDI نیاز داشت تا دستورات رسم را به یکسری عملیات در دستگاههای خاص ترجمه کند. در صفحه نمایش، باید پیکسلها را در بافر فریم مورد استفاده قرار میداد. هنگام طراحی به یک چاپگر، درخواست API باید به درخواستهایی به یک چاپگر تبدیل میشد. اگر چه میتوانست امکانپذیر باشد که پشتیبانی سخت افزاری برای مجموعه محدودی از دستگاهها (مانند صفحه نمایش رنگی گرافیک آداپتور، پرینتر لیزریجت چاپگر فرمان زبان ) فراهم شود، مایکروسافت رویکردی متفاوت انتخاب کرد. GDI با بارگیری قطعات مختلفی از کد، به نام " درایور دستگاه "، برای کار با دستگاههای خروجی مختلف کار میکرد.
همان مفهوم معماری که GDI را قادر ساخت تا دستگاهای درایور مختلف بار شوند، همان است که به ویندوز شل (windows shell) اجازه داد تا برنامههای مختلف ویندوز را بارگذاری کند و برای این برنامهها که بتوانند APIها را از کتابخانههای مشترک USER و GDI فراخوانی کنند. آن مفهوم "پیوند پویا" نام داشت.
در یک کتابخانه "استاتیک" معمولی (که مشترک(shared) نباشد)، به سادگی بخشهای کد به برنامهٔ فراخوانی شده اضافه میشوند، زمانی که فایل اجرایی آن در مرحله "اتصال" ساخته شدهاست؛ اگر دو برنامه با یک تابع را صدا بزنند، آن تابع در هر دو برنامه، در مرحله اتصال هر دو، گنجانده میشود. با پیوند پویا، کد مشترک، در یک فایل جداگانه قرار میگیرد. برنامههایی که این پرونده را فراخوانی میکنند در زمان اجرا، با سیستم عامل (یا، در مورد نسخههای اولیه ویندوز، OS-extension)، با اتصال به آن، مرتبط میشوند.
برای نسخههای اولیه ویندوز (1.0 تا 3.11)، DLLها پایه و اساس کل رابطهای کاربری گرافیکی (GUI) بودند. به همین ترتیب، درایورهای نمایش صرفاً فقط DLLهایی با پسوند DRV بودند که برنامههای پیادهسازی شدهٔ سفارشی از همان طراحی API را از طریق یک دستگاه درایور متحد رابط (DDI) فراهم میکرد و "رسم (GDI)" و " USER) GUI)" همان APIها صرفاً یکسری فراخوانی تابع بودند که توسط GDI و USER و سیستم DLLها با پسوند .EXE صادر شدند.
مفهوم ساخت سیستم عامل از مجموعه ای از کتابخانههای بارگذاری شده به صورت پویا، یک مفهوم اصلی ویندوز است که تا تاریخ ۲۰۱۵ ادامه می یابد. DLLها مزایای استاندارد کتابخانه های به اشتراک گذاشته شده، مانند ماژولار بودن را فراهم میکنند. ماژولار بودن اجازه میدهد تا تغییرات در کد و دادهها در یک DLL خود درج و پر شده ای که توسط تعدادی نرمافزار مختلف بدون ایجاد هیچ تغییری در خود نرمافزارها به اشتراک گذاشته شدهاست، صورت گیرد.
یکی دیگر از مزایای ماژولار بودن استفاده از رابطهای عمومی برای پلاگ-اینها است. یک رابط واحد ممکن است توسعه یابد، که اجازه میدهد که ماژولهای قدیمی و جدید بهطور یکپارچه با هم در زمان اجرا متحد شوند و تبدیل شوند به برنامههای از قبل وجود داشته، بدون هیچ گونه تغییری در خود نرمافزار. این مفهوم توسعه پویا به بیشترین حد خود، با مدل Object Component، پایهٔ ActiveX، رسیده است.
در ویندوز x.1، 2.x و 3.x، تمام نرمافزارهای ویندوز یک فضای آدرس حافظه را به اشتراک میگذاشتند. یک DLL فقط یک بار به این فضای آدرس بارگذاری شد. از آن پس، تمام برنامههایی که از کتابخانه استفاده میکردند میتوانستند به آن دسترسی پیدا کنند. دادههای کتابخانه در همه برنامهها به اشتراک گذاشته شدهاست. این میتواند به عنوان یک شکل غیرمستقیم ارتباطات بین فرایند مورد استفاده قرار گیرد، یا میتواند بهطور تصادفی برنامههای مختلف را فاسد کند. با معرفی کتابخانههای 32 بیتی در ویندوز 95، هر فرایند در فضای آدرس خود اجرا میشود. در حالی که کد DLL ممکن است به اشتراک گذاشته شود، دادهها خصوصی هستند مگر اینکه دادههای به اشتراک گذاشته شده، بهطور صریح از سوی کتابخانه درخواست شوند. با توجه به این موضوع، نوارهای بزرگی از کتابخانههای 16 بیتی از ویندوز 95، ویندوز 98 و ویندوز می ساخته شد که عملکرد ریز پردازندههای Pentium Pro را در هنگام شروع محدود کرد و در نهایت ثبات و مقیاس پذیری نسخههای مبتنی بر DOS را محدود کرد.
اگر چه DLLها هسته معماری ویندوز هستند، اما آنها دارای نقایص متعددی هستند که بهطور کلی " DLL hell " نامیده میشود.[2] تا تاریخ ۲۰۱۵، مایکروسافت NET چارچوب را رواج میدهد، به عنوان یک راه حل برای مشکلات DLL hell، اگر چه آنها در حال حاضر راه حلهای مبتنی بر مجازی سازی را مانند مایکروسافت مجازی کامپیوتر و مایکروسافت برنامه مجازی سازی رواج میدهند و آن به دلیل انعطافپذیری بالاتر بین برنامههای کاربردی است. راه حل جبران جایگزین برای DLL hell، اجرای اسمبلی کنار هم قرار گرفتهاست .
ویژگی های DLL
از آنجائیکه DLLها اساساً همان EXEها هستند، انتخاب آن برای تولید به عنوان بخشی از روند پیوند برای وضوح است، به این دلیل که ممکن است توابع و دادهها را از هر دوی آنها بفرستد.
امکان اجرای مستقیم DLL وجود ندارد، زیرا برای سیستم عامل نیاز به یک EXE است، تا بتواند آن را از هر نقطه ورود بارگذاری کند. از این رو، وجود امکانات مانند "RUNDLL. EXE" یا "RUNDLL32.EXE" که نقطه ورود و حداقل چارچوب را برای DLLها فراهم میکند که دارای قابلیت کافی برای اجرا بدون پشتیبانی زیاد است.
DLLها مکانیسم لازم برای کد و داده مشترک را فراهم میکنند و با اینکار اجازه میدهند یک توسعه دهندهٔ کد/دادهٔ مشترک، بدون اینکه نیاز داشته باشد تا برنامهها پیوند دوباره بخورند یا مجدداً کامپایل شوند، عملکرد خود را ارتقا دهد. از نقطه نظر توسعه نرمافزار، ویندوز و OS / 2 میتوانند به عنوان مجموعه ای از DLLهایی که به روز رسانی شده اند، باشند که اجازه میدهد برنامههای کاربردی برای یک نسخه از سیستم عامل بدر یک نسخه دیگر آن نیز کار کند. در صورتی که فروشنده OS مطمئن شدهاست که رابط و قابلیت هر دو سازگار هستند.
DLLها در فضای حافظه در فرایند فراخوانی اجرا میشوند و با مجوزهای دسترسی برابر، که بدین معناست که در استفاده، آنها کم هزینه هستند، اما همچنین به این معناست که اگر DLL هر گونه مشکلی داشته باشد، هیچ حفاظتی در فراخوانی EXE وجود ندارد.
مدیریت حافظه
در ویندوز API، فایلهای DLL به بخشهایی سازماندهی شدهاند. هر بخش مجموعه ای از ویژگیهای خاص خود را دارد، از قبیل قابل خواندن و نوشتن، اجرایی بودن (برای کد) یا غیرقابل اجرایی بودن (برای داده ها) و غیره.
کد در DLL معمولاً در میان تمام فرایندهای که از DLL استفاده میکنند به اشتراک گذاشته میشود؛ یعنی، آنها یک مکان را در حافظه فیزیکی اشغال میکنند و در فضای صفحه فضایی نمیگیرند. اگر حافظه فیزیکی اشغال شده توسط یک بخش کد بخواهد بازسازی شود، محتویات آن حذف میشود و بعد از آن بهطور مستقیم از فایل DLL به صورت مجدد بارگیری میشود.
برخلاف بخشهای کد، بخش دادههای یک DLL معمولاً خصوصی هستند؛ یعنی هر فرایندی که از DLL استفاده میکند، یک کپی مخصوص از تمام دادههای DLL دارد. به صورت اختیاری، بخشهای داده میتوانند به اشتراک گذاشته شوند، به این ترتیب میتوان اجازه داد ارتباطات فرایند از طریق این فضای حافظهٔ به اشتراک گذاشته شده، صورت گیرند. به هر جهت، به دلیل اینکه محدودیتهای کاربر برای استفاده از حافظه DLL مشترک اعمال نمیشود، این یک سوراخ امنیتی ایجاد میکند؛ یعنی یک فرایند میتواند دادههای مشترک را خراب کند، که احتمالاً باعث میشود همه فرایندهای به اشتراک گذاری غیرمعمول رفتار کنند. به عنوان مثال، فرایندی که تحت یک حساب مهمان انجام میشود، میتواند به این ترتیب فرایند دیگری را که تحت یک حساب کاربری مجاز است خراب کند. این یک دلیل مهم برای جلوگیری از استفاده از بخشهای مشترک در DLLها است.
اگر یک DLL با برخی بسته بندیهای اجرایی خاص فشرده شود (به عنوان مثال UPX)، تمام بخشهای کد آن به عنوان خواندن و نوشتن مشخص شدهاند و به اشتراک گذاشته نمیشوند. بخشهای خواندن و نوشتن کد، شبیه به بخشهای دادههای خصوصی، برای هر فرایند خصوصی هستند. بنابراین، DLLها با بخشهای داده مشترک، اگر آنها برای این در نظر گرفته شده باشند که بهطور همزمان توسط چندین برنامه استفاده شوند، نباید فشرده شوند؛ چرا که هر نمونه از برنامه باید یک کپی خود از DLL را حمل کند که در نتیجه افزایش مصرف حافظه خواهد بود.
فراخوانی کتابخانه ها
همانند کتابخانههای استاتیک، کتابخانههای دخیل شده برای DLLها با فرمت فایل lib مشخص میشوند. به عنوان مثال، kernel32.dll، کتابخانه پویا اولیه برای توابع پایه ویندوز مانند ایجاد فایل و مدیریت حافظه، از طریق kernel32.lib مرتبط شده.
پیوستن به کتابخانههای پویا معمولاً با اتصال به یک کتابخانه وارد شده و دخیل شده به آن رسیدگی میشود؛ هنگام ساختن یا متصل شدن برای ایجاد یک فایل اجرایی. سپس فایل اجرایی ساخته شده، حاوی یک جدول آدرسهای دخیل (IAT) است که توسط آن تمام فراخوانیهای عملکرد DLL ارجاع میشود. (هر تابع اشاره شده DLL دارای ورودی خود در IAT است). در زمان اجرا، IAT با آدرسهای مناسب پر میشود که مستقیماً به یک تابع در DLL ای که جداگانه بارگذاری شده، اشاره میکند.
رفع نماد و الزام آن
هر تابعی که توسط یک DLL صادر میشود، توسط یک عدد ترتیبی و به صورت اختیاری، با یک نام شناسایی میشود. به همین ترتیب، توابع را میتوان از یک DLL یا به ترتیب یا با نام وارد کرد. ترتیب آن نشان دهنده موقعیت نشانگر آدرس تابع در جدول آدرسهای دخیل DLL یا همان IAT است. معمول است که توابع داخلی فقط به ترتیب صادر شوند نه با نام. برای اکثر توابع API ویندوزها، فقط نامها در نسخههای مختلف ویندوز حفظ میشوند؛ آن اعداد ترتیبی در معرض تغییر هستند. بنابراین، یکنفر نمیتواند با اعتماد کامل توابع API ویندوز را با اعدادش وارد کند.
فراخوانی توابع با اعدادشان، تنها عملکرد آن را به مقدار خیلی کمی بهتر میکند در مقایسه با فراخوانی آنها با نامشان: جداول صادر کردن DLLها با نامشان ترتیب بندی شده اند؛ بنابراین از جستجو باینری میتوان برای پیدا کردن یک تابع استفاده کرد. سپس فهرست نام پیدا شده در این جستجو، مورد استفاده قرار میگیرد تا عدد آن را در جدول اعداد صادره رپیدا کند. در ویندوز 16 بیتی، جدول نام طبقهبندی نشده بود، بنابراین هزینهٔ جستجوی نام بسیار قابل توجه بود.
همچنین ممکن است که یک فایل اجرایی را به یک نسخه خاص از یک DLL متصل کنیم، این کار برای این است که آدرسهای توابع فراخوانی شده در زمان کامپایل حل و فصل شوند. برای توابع فراخوانی شدهٔ محدود، لینکر نشانهٔ زمانی و مجموع مقابلههای DLL که فراخوانی در آن محدود است را ذخیره میکند. در زمان اجرا، ویندوز بررسی میکند که آیا همان نسخه از کتابخانه در حال استفاده است یا خیر، اگر اینطور بود، ویندوز از پردازش توابع فراخوانی شده جلوگیری میکند. در غیر این صورت، اگر کتابخانه با آن کتابخانه ای که به آن محدود شده بود متفاوت بود، ویندوز بهطور عادی فراخوانده شدهها را پردازش میکند.
فایلهای اجرایی محدود شده به نحوی سریعتر بارگذاری میشوند اگر که در همان محیطی که برای کامپایل شدن آنها بوده، اجرا شوند و دقیقاً در همان زمان اگر در محیطهای متفاوتی اجرا میشوند. بنابراین هیچ محدودیتی برای اتصال به فراخوانی شدهها وجود ندارد. به عنوان مثال، تمام برنامههای ویندوز استاندارد به DLLهای سیستم مربوط به آن نسخه از ویندوز محدود میشوند. یک فرصت خوب برای اتصال توابع فراخوانده شدهٔ یک نرمافزار به محیط هدف خود، در طول نصب نرمافزار است. این کار کتابخانهها را تا ارسال نسخهٔ بعدی سیستم عامل محدود میکند؛ ولی مجموع مقابلههای برنامهٔ اجرایی را تغییر میدهد. بنابراین چیزی نیست که بتوان با برنامههای امضا شده یا برنامههایی که توسط یک ابزار مدیریت پیکربندی که از مجموع مقابلهها استفاده میکند(مانند چکهای MD5 ) برای مدیریت نسخههای فایل انجام داد. همانطور که نسخههای جدید ویندوز دیگر آدرسهای ثابت برای هر کتابخانه بارگذاری شده (به دلایل امنیتی) ندارند، فرصت و ارزش اتصال یک فایل اجرایی در حال کاهش است.
پیوند صریح در زمان اجرا
فایلهای DLL ممکن است بهطور صریح در زمان اجرا بارگذاری شوند، یک فرایند به نام "Run-time dynamic linking" یا پیوندهای زمان اجرا توسط ماکروسافت، با استفاده از تابع LoadLibrary
(یا LoadLibraryEx
). تابع GetProcAddress
برای جستجوی علامتهای صادر شده بر اساس نام و FreeLibrary
برای این است که DLL را بارگیری یا خالی کند. این توابع مشابه هستند با dlopen
، dlsym
و dlclose
در POSIX API استاندارد.
فرایند پیوند صریح در زمان اجرا در هر زبانی که اشاره گرها به توابع را پشتیبانی می کند، یکی است. البته از آنجا که به API ویندوز بستگی دارد، نه به جای ساختارهای زبان.
بارگیری تاخیری
بهطور معمول، یک نرمافزار که در مقابله با یک کتابخانه DLL مرتبط شده، اگر DLL پیدا نشود، شروع به کار نمیکند؛ زیرا ویندوز برنامه را اجرا نخواهد کرد مگر آنکه بتواند تمام DLLهایی را که ممکن است برنامه به آن نیاز داشته باشد، پیدا کند. با این حال یک برنامه ممکن است در مقابله با یک کتابخانه DLL مرتبط شود تا بخواهد بارگذاری کتابخانه پویا را به تأخیر بیندازد.[3] در این حالت سیستم عامل سعی نمیکند زمانی که برنامه شروع میشود DLL را پیدا کند یا آن را بارگذاری کند؛ در عوض، زمانی که یکی از توابع آن فراخوانده میشود یک خرده در نرمافزار به وسیلهٔ همان لینکر در نرمافزار اضافه شدهاست که سعی میکند DLL را از طریق LoadLibrary و GetProcAddress پیدا کند و آن را بارگذاری کند. اگر DLL را نتوان یافت یا بارگذاری کرد، یا تابع فراخوانده شده وجود نداشت، برنامه یک استثنا(Exception) ایجاد میکند که ممکن است پیدا شود و به درستی به آن رسیدگی شود. اگر برنامه به استثنائی رسیدگی نکند، توسط سیستم عامل به دام افتاده است که برنامه را با یک پیام خطا خاتمه میدهد.
مکانیزم بارگیری تأخیر دار نیز قلابهای اطلاع رسانی را فراهم میکند که اجازه میدهد برنامه پردازشهای اضافی و یا خطا در هنگام بارگذاری را هنگامی که DLL و/یا هر گونه تابع DLL ای فراخوانده شده باشد، انجام دهد .
ملاحظات کامپایلر و زبان
دلفی[4]
در یک فایل منبع، به جای کلمهٔ کلیدی program
، library
استفاده میشود. در پایان فایل، توابع مورد نظر صادر شده در بند exports
ذکر شدهاند.
دلفی برای دسترسی به توابع از DLLها نیاز به فایلهای LIB
ندارد برای پیوند به یک DLL، کلمه کلیدی external
در اعلامیه عملکرد برای نشان دادن نام DLL استفاده میشود، به دنبال آن name
برای نامگذاری نماد (اگر متفاوت است) یا index
برای شناسایی شاخص آن.
مایکروسافت ویژوال بیسیک Microsoft Visual Basic
در ویژوال بیسیک(VB) تنها پیوند در زمان اجرا پشتیبانی میشود. اما علاوه بر استفاده از LoadLibrary
و GetProcAddress
توابع API، اعلامیه(declare کردن) از توابع فراخوانده شده مجاز است.
هنگام وارد کردن توابع DLL از طریق اعلانها، VB یک خطای زمانی اجرا میکند اگر فایل DLL
را پیدا نکند. توسعه دهنده میتواند خطا را دریافت و به درستی به آن رسیدگی کند.
هنگام ایجاد DLLها در VB، آن IDE تنها به شما اجازه میدهد تا DLLهای ActiveX را ایجاد کنید، با این حال روش[5]های مورد نیاز ایجاد شده که به کاربران اجازه میدهد تا به صراحت به لینکر بگوید که یک DEF. اضافه کند که نام هر تابع و موقعیت و عدد آن را تعریف کند. این اجازه میدهد تا کاربر یک DLL استاندارد ویندوز را با استفاده از ویژوال بیسیک (نسخه 6 یا پایین تر) ایجاد کند که میتواند از طریق بیانیه "اعلام(Declare)" اشاره شود.
C و ++ C
مایکروسافت ویژوال سی + +(MSVC) چند پسوند را برای استاندارد C ++ فراهم میکند که اجازه میدهد توابع به عنوان وارد شده یا صادر شده بهطور مستقیم در کد سی ++مشخص شوند؛ اینها توسط کامپایلرهای ویندوز C و C ++، از جمله نسخههای ویندوز GCC بکار رفته است. این پسوندها از ویژگی __declspec
قبل از اعلان تابع استفاده میکنند. توجه داشته باشید هنگامی که توابع C از C ++ قابل دسترسی است، آنها همچنین باید به عنوان "extern "C
در کد C ++ اعلام شوند تا کامپایلر را مطلع کنند که پیوند C باید استفاده شود.[6]
علاوه بر مشخص کردن توابع وارد شده یا صادر شده با استفاده از ویژگیهای __declspec
، آنها ممکن است در قسمت IMPORT یا EXPORTS از بخش DEF
مورد استفاده در پروژه ذکر شده باشند. فایل DEF
به جای کامپایلر، توسط لینکر پردازش شدهاست و بنابراین مختص C++ نیست.
تدوین DLL هر دو فایل DLL
و LIB
را تولید میکند. فایل LIB
برای اتصال در مقابل یک DLL در زمان کامپایل استفاده میشود؛ برای پیوند زمان اجرا لازم نیست. مگر اینکه DLL شما یک مدل از شی کامپوننت - Component Object Model باشد، آنوقت فایل DLL
باید یا در یکی از دایرکتوریهایی که در متغیر محدودهٔ PATH فهرست شده باشد، یا در دایرکتوری سیستم پیش فرض و یا در همان دایرکتوری به عنوان برنامه ای که در حال استفاده از آن است، قرار بگیرد. DLLهای COM سرور با استفاده از regsvr32.exe ثبت میشوند که موقعیت مکانی DLL و شناسه جهانی آن ( GUID ) را در رجیستری قرار میدهد. سپس برنامهها میتوانند از DLLها با جستجو کردن GUID آنها استفاده کنند تا مکان آن را پیدا کنند یا یک نمونه از شی COM را بسازند که بهطور غیرمستقیم کلاس مشخصکنندهٔ آن و رابط مشخصکنندهٔ آن را استفاده کنند.
مثال های برنامه نویسی
استفاده از ایمپورتهای DLL
مثالهای زیر نشان میدهد که چگونه از خاصیتهای خاص زبان استفاده کنید تا نمادهایی برای پیوند در مقابل یک DLL در زمان کامپایل اضافه کنید.
زبان دلفی
{$APPTYPE CONSOLE}
program Example;
// import function that adds two numbers
function AddNumbers(a, b : Double): Double; StdCall; external 'Example.dll';
// main program
var
R: Double;
begin
R := AddNumbers(1, 2);
Writeln('The result was: ', R);
end.
زبان سی از این که فایل پروژه Example.lib را اضافه کرده باشید، اطمینان حاصل کنید. (فرض کنید مثال Example.dll تولید شدهاست) در پروژه (اضافه کردن گزینه موجود برای پروژه!) قبل از یک پیوند استاتیک. Example.lib این فایل به صورت خودکار توسط کامپایلر در هنگام کامپایل DLL تولید میشود. با اجرا نکردن بخش بالا، برنامه خطای پیوند میدهد؛ زیرا لینکر نمیداند کجا تعریف AddNumbers را پیدا کند. شما همچنین باید DLL Example.dll را در جایی که فایل exe با کد زیر تولید میشود، کپی کنید.
#include <windows.h>
#include <stdio.h>
// Import function that adds two numbers
extern "C" __declspec(dllimport) double AddNumbers(double a, double b);
int main(int argc, char *argv[])
{
double result = AddNumbers(1, 2);
printf("The result was: %f\n", result);
return 0;
}
استفاده از پیوند صریح زمان اجرا
مثالهای زیر نشان میدهد که چگونه از بارگذاری زمان اجرا و امکانات پیوند با استفاده از محدودیتهای زبان خاص API ویندوز، استفاده کنید.
مایکروسافت ویژوال بیسیک
هشدار: کد زیر آسیبپذیر است، با راهنمای مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد
Option Explicit
Declare Function AddNumbers Lib "Example.dll" _
(ByVal a As Double, ByVal b As Double) As Double
Sub Main()
Dim Result As Double
Result = AddNumbers(1, 2)
Debug.Print "The result was: " & Result
End Sub
زبان دلفی
هشدار: کد زیر آسیبپذیر است، با راهنمای مایکروسافت برای بارگذاری امن کتابخانه مطابقت ندارد!
program Example;
{$APPTYPE CONSOLE}
uses Windows;
var
AddNumbers:function (a, b: integer): Double; StdCall;
LibHandle:HMODULE;
begin
LibHandle := LoadLibrary('example.dll');
if LibHandle <> 0 then
AddNumbers := GetProcAddress(LibHandle, 'AddNumbers');
if Assigned(AddNumbers) then
Writeln( '1 + 2 = ', AddNumbers( 1, 2 ) );
Readln;
end.
زبان سی
هشدار: کد زیر آسیبپذیر است؛ آن را با راهنمایی مایکروسافت برای بارگذاری ایمن کتابخانه مطابقت ندارد.
#include <windows.h>
#include <stdio.h>
// DLL function signature
typedef double (*importFunction)(double, double);
int main(int argc, char **argv)
{
importFunction addNumbers;
double result;
HINSTANCE hinstLib;
// Load DLL file
hinstLib = LoadLibrary(TEXT("Example.dll"));
if (hinstLib == NULL) {
printf("ERROR: unable to load DLL\n");
return 1;
}
// Get function pointer
addNumbers = (importFunction) GetProcAddress(hinstLib, "AddNumbers");
if (addNumbers == NULL) {
printf("ERROR: unable to find DLL function\n");
FreeLibrary(hinstLib);
return 1;
}
// Call function.
result = addNumbers(1, 2);
// Unload DLL file
FreeLibrary(hinstLib);
// Display result
printf("The result was: %f\n", result);
return 0;
}
زبان پایتون
هشدار: کد زیر آسیبپذیر است؛ با راهنمایی مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد!
import ctypes
my_dll = ctypes.cdll.LoadLibrary("Example.dll")
# The following "restype" method specification is needed to make
# Python understand what type is returned by the function.
my_dll.AddNumbers.restype = ctypes.c_double
p = my_dll.AddNumbers(ctypes.c_double(1.0), ctypes.c_double(2.0))
print "The result was:", p
مدل Object Component (COM) یک استاندارد باینری را برای میزبانی پیادهسازی اشیا در DLL و EXE تعیین میکند. این مکانیسمها برای تعیین مکان و نسخه آن فایلها و همچنین توضیح زبان مستقل و قابل خواندن در ماشین از رابط فراهم میکند. میزبان COM اجزای در یک DLL سبک تر است و به آنها اجازه میدهد که منابع را با فرایند مشتری به اشتراک بگذارند. این اجازه میدهد که اشیاء COM برای پیادهسازی پشتیهای قدرتمند به قسمتهای جلویی GUI ساده مانند ویژوال بیسیک و ASP. آنها همچنین میتوانند از زبان اسکریپتی برنامهریزی شوند.[7]
با توجه به آسیب پذیری که معمولاً به عنوان ربودن DLL شناخته میشود، DLL spoofing، DLL preloading یا کاوش باینری، بسیاری از برنامهها DLL مخرب موجود در همان فولدر را به عنوان یک فایل داده باز شده توسط این برنامهها اجرا میکنند.[8][9][10][11] این آسیبپذیری توسط Georgi Guninski در سال 2000 کشف شد.[12] در آگوست 2010، بعد از آنکه امنیت ACROS دوباره آن را کشف کرد و بعد از چندین صدها برنامه آسیبپذیر شد، آن را در سراسر جهان تبلیغ کرد.[13] برنامههایی که از مکانهای ناامن اجرا میشوند، یعنی پوشههای قابل خواندن کاربر مانند دانلودها یا پوشه Temp، تقریباً همیشه به این آسیبپذیری حساس هستند.[14][15][16][17][18][19][20]
همچنین نگاه کنید
- Dependency Walker، یک ابزار است که توابع صادره و واردهٔ فایلهای DLL و EXE را نشان میدهد
- کتابخانه پویا
- کتابخانه (محاسبات)
- لینک (محاسبات)
- لودر (محاسبات)
- Moricons.dll
- فایل شیء
- کتابخانه به اشتراک گذاشته شده
- کتابخانه استاتیک
- ِDLL hell
پیوند به بیرون
- dllexport، dllimport در MSDN
- کتابخانه های دینامیک لینک در MSDN
- امنیت کتابخانه دینامیک لینک در MSDN
- سفارش جستجوی کتابخانه دینامیک لینک در MSDN
- مشاور امنیت مایکروسافت: بارگذاری کتابخانه ناامن می تواند اجازه اجرای کد را بدهد
- DLL چیست؟ در سایت پشتیبانی مایکروسافت
- توابع کتابخانه دینامیک لینک در MSDN
- خصوصیات فرمت فایل اجرایی قابل حمل و عمومی مشترک مایکروسافت
- مشخصات مایکروسافت برای فایل های DLL
- مسمومیت با بمباران فرش و دایرکتوری
- MS09-014: رفع آسیب پذیری بمب فرش سافاری
- اطلاعات بیشتر در مورد DLL پیش بارگذاری بردار حمله از راه دور
- یک بروزرسانی بر روی بردار حمله دور افتاده DLL-preloading
- بار کتابخانه به طور ایمن
منابع
- هارت، جانسون. ویندوز سیستم برنامه نویسی نسخه سوم . Addison-Wesley، 2005. شابک ۰−۳۲۱−۲۵۶۱۹−۰
- رکتور، برنت و همکاران Win32 برنامه نویسی . Addison-Wesley Developers Press، 1997. شابک ۰−۲۰۱−۶۳۴۹۲−۹ ISBN 0-201-63492-9 . <references group="" responsive="">
- Microsoft Corporation. "Creating a Resource-Only DLL". Microsoft Developer Network Library.
- "The End of DLL Hell". Microsoft Corporation. Archived from the original on 2008-05-06. Retrieved 2009-07-11.
- "Linker Support for Delay-Loaded DLLs". Microsoft Corporation. Retrieved 2009-07-11.
- "دلفی (زبان برنامهنویسی)". ویکیپدیا، دانشنامهٔ آزاد. 2018-11-04.
- Petrusha, Ron (2005-04-26). "Creating a Windows DLL with Visual Basic". O'Reilly Media. Retrieved 2009-07-11.
- MSDN ، با استفاده از extern برای مشخص کردن پیوند
- Satran, Michael. "Component Object Model (COM)". msdn.microsoft.com.
- "DLL Preloading Attacks". msdn.com. Retrieved 25 March 2018.
- "More information about the DLL Preloading remote attack vector". technet.com. Archived from the original on 1 January 2016. Retrieved 25 March 2018.
- "An update on the DLL-preloading remote attack vector". technet.com. Archived from the original on 5 January 2016. Retrieved 25 March 2018.
- "Double clicking on MS Office documents from Windows Explorer may execute arbitrary programs in some cases". www.guninski.com. Retrieved 25 March 2018.
- "Binary Planting - The Official Web Site of a Forgotten Vulnerability . ACROS Security". www.binaryplanting.com. Retrieved 25 March 2018.
- "Dev to Mozilla: Please dump ancient Windows install processes". theregister.co.uk. Retrieved 25 March 2018.
- "Gpg4win - Security Advisory Gpg4win 2015-11-25". www.gpg4win.org. Retrieved 25 March 2018.
- "McAfee KB - McAfee Security Bulletin: Security patch for several McAfee installers and uninstallers (CVE-2015-8991, CVE-2015-8992, and CVE-2015-8993) (TS102462)". service.mcafee.com. Retrieved 25 March 2018.
- "fsc-2015-4 - F-Secure Labs". www.f-secure.com. Archived from the original on 31 July 2017. Retrieved 25 March 2018.
- "ScanNow DLL Search Order Hijacking Vulnerability and Deprecation". rapid7.com. 21 December 2015. Retrieved 25 March 2018.
- Team, VeraCrypt. "oss-sec: CVE-2016-1281: TrueCrypt and VeraCrypt Windows installers allow arbitrary code execution with elevation of privilege". seclists.org. Retrieved 25 March 2018.