کتابخانه پیوند پویا

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به ناوبری پرش به جستجو
Dynamic link library
File:Dll png.png
پسوند فایل .dll
نوع مدیا اینترنت application/vnd.microsoft.portable-executable
نوع همگن تشخیص‌دهنده com.microsoft.windows-dynamic-link-library
عدد جادویی MZ
توسعه‌دهنده Microsoft
کاربرد برای Shared library

کتابخانه پیوند پویا (یا DLL )یک فرمت استاندارد پیاده سازی شده توسط مایکروسافت از مفهوم کتابخانه های مشترک در سیستم عامل های مایکروسافت ویندوز و OS / 2 است. این کتابخانه ها معمولا دارای فایل های DLL ، OCX (برای کتابخانه های حاوی کنترل های اکتیو ایکس ) یا DRV (برای رانندگان سیستم میراث) هستند. فرمت های فایل DLL ها همانند فایل های ویندوز EXE است - یعنی قابل اجرا و قابل حمل (یا PE) برای ویندوزهای 32 بیتی و 64 بیتی و NE)New Executable) برای ویندوزهای 16 بیتی . همانند EXE ها، DLL ها می توانند شامل کد ، داده ها و منابع در هر ترکیبی از آنها باشند.

فایلهای داده با فرمت فایل DLL، اما با پسوندهای فایلی مختلف که احتمالا هم فقط شامل بخش منابع باشند ، میتوانند منابع DLL نامیده شوند. نمونه هایی از چنین DLL شامل آیکون کتابخانه هاست که گاهی اوقات دارای پسوندICLو فایل های فونت، که دارای پسوندهای FON و FOT هستند، میشود.[۱]

پس زمینه ی 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 " نامیده می شود.[۲] از تاریخ ۲۰۱۵، مایکروسافت 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 مرتبط شود تا بخواهد بارگذاری کتابخانه پویا را به تاخیر بیاندازد.[۳] در این حالت سیستم عامل سعی نمی کند زمانی که برنامه شروع می شود DLL را پیدا کند یا آنرا بارگذاری کند؛ در عوض، زمانی که یکی از توابع آن فراخوانده می شود یک خرده در نرم افزار بوسیله همان لینکر در نرم افزار اضافه شده است که سعی می کند DLL را از طریق LoadLibrary و GetProcAddress پیدا کند و آنرا بارگذاری کند. اگر DLL را نتوان یافت یا بارگذاری کرد، یا تابع فراخوانده شده وجود نداشت، برنامه یک استثنا(Exception) ایجاد می کند که ممکن است پیدا شود و به درستی به آن رسیدگی شود. اگر برنامه به استثنائی رسیدگی نکند، توسط سیستم عامل به دام افتاده است که برنامه را با یک پیام خطا خاتمه می دهد.

مکانیزم بارگیری تاخیر دار نیز قلاب های اطلاع رسانی را فراهم می کند که اجازه می دهد برنامه پردازش های اضافی و یا خطا در هنگام بارگذاری را هنگامی که DLL و/یا هر گونه تابع DLL ای فراخوانده شده باشد، انجام دهد .

ملاحظات کامپایلر و زبان[ویرایش]

دلفی[۴][ویرایش]

در یک فایل منبع، به جای کلمه ی کلیدی 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 را ایجاد کنید، با این حال روش[۵] های مورد نیاز ایجاد شده که به کاربران اجازه می دهد تا به صراحت به لینکر بگوید که یک DEF. اضافه کند که نام هر تابع و موقعیت و عدد آنرا تعریف کند. این اجازه می دهد تا کاربر یک DLL استاندارد ویندوز را با استفاده از ویژوال بیسیک (نسخه 6 یا پایین تر) ایجاد کند که می تواند از طریق بیانیه "اعلام(Declare)" اشاره شود.

C و ++ C[ویرایش]

مایکروسافت ویژوال سی + +(MSVC) چند پسوند را برای استاندارد C ++ فراهم میکند که اجازه می دهد توابع به عنوان وارد شده یا صادر شده به طور مستقیم در کد سی ++مشخص شوند؛ این ها توسط کامپایلرهای ویندوز C و C ++، از جمله نسخه های ویندوز GCC بکار رفته است. این پسوند ها از ویژگی __declspec قبل از اعلان تابع استفاده می کنند. توجه داشته باشید هنگامی که توابع C از C ++ قابل دسترسی است، آنها همچنین باید به عنوان "extern "C در کد C ++ اعلام شوند تا کامپایلر را مطلع کنند که پیوند C باید استفاده شود.[۶]

علاوه بر مشخص کردن توابع وارد شده یا صادر شده با استفاده از ویژگی های __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 در زمان کامپایل اضافه کنید.

زبان دلفی

 1 {$APPTYPE CONSOLE}
 2 
 3 program Example;
 4 
 5 // import function that adds two numbers
 6 function AddNumbers(a, b : Double): Double; StdCall; external 'Example.dll';
 7 
 8 // main program
 9 var
10    R: Double;
11 
12 begin
13   R := AddNumbers(1, 2);
14   Writeln('The result was: ', R);
15 end.

زبان سی از این که فایل پروژه Example.lib را اضافه کرده باشید، اطمینان حاصل کنید. (فرض کنید مثال Example.dll تولید شده است) در پروژه (اضافه کردن گزینه موجود برای پروژه!) قبل از یک پیوند استاتیک. Example.lib این فایل به صورت خودکار توسط کامپایلر در هنگام کامپایل DLL تولید می شود. با اجرا نکردن بخش بالا، برنامه خطای پیوند میدهد؛ زیرا لینکر نمی داند کجا تعریف AddNumbers را پیدا کند. شما همچنین باید DLL Example.dll را در جایی که فایل exe با کد زیر تولید می شود، کپی کنید.

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 // Import function that adds two numbers
 5 extern "C" __declspec(dllimport) double AddNumbers(double a, double b);
 6 
 7 int main(int argc, char *argv[])
 8 {
 9     double result = AddNumbers(1, 2);
10     printf("The result was: %f\n", result);
11     return 0;
12 }

استفاده از پیوند صریح زمان اجرا[ویرایش]

مثال های زیر نشان می دهد که چگونه از بارگذاری زمان اجرا و امکانات پیوند با استفاده از محدودیت های زبان خاص API ویندوز، استفاده کنید.

مایکروسافت ویژوال بیسیک[ویرایش]

هشدار: کد زیر آسيبپذير است، با راهنمای مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد

1 Option Explicit
2 Declare Function AddNumbers Lib "Example.dll" _
3 (ByVal a As Double, ByVal b As Double) As Double
4 
5 Sub Main()
6 	Dim Result As Double
7 	Result = AddNumbers(1, 2)
8 	Debug.Print "The result was: " & Result
9 End Sub

زبان دلفی[ویرایش]

هشدار: کد زیر آسيبپذير است، با راهنماي مایکروسافت برای بارگذاری امن کتابخانه مطابقت ندارد!

 1 program Example;
 2   {$APPTYPE CONSOLE}
 3   uses Windows;
 4   var
 5   AddNumbers:function (a, b: integer): Double; StdCall;
 6   LibHandle:HMODULE;
 7 begin
 8   LibHandle := LoadLibrary('example.dll');
 9   if LibHandle <> 0 then
10     AddNumbers := GetProcAddress(LibHandle, 'AddNumbers');
11   if Assigned(AddNumbers) then
12     Writeln( '1 + 2 = ', AddNumbers( 1, 2 ) );
13   Readln;
14 end.

زبان سی[ویرایش]

هشدار: کد زیر آسیب پذیر است؛ آن را با راهنمایی مایکروسافت برای بارگذاری ایمن کتابخانه مطابقت ندارد.

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 // DLL function signature
 5 typedef double (*importFunction)(double, double);
 6 
 7 int main(int argc, char **argv)
 8 {
 9 	importFunction addNumbers;
10 	double result;
11 	HINSTANCE hinstLib;
12 
13 	// Load DLL file
14 	hinstLib = LoadLibrary(TEXT("Example.dll"));
15 	if (hinstLib == NULL) {
16 		printf("ERROR: unable to load DLL\n");
17 		return 1;
18 	}
19 
20 	// Get function pointer
21 	addNumbers = (importFunction) GetProcAddress(hinstLib, "AddNumbers");
22 	if (addNumbers == NULL) {
23 		printf("ERROR: unable to find DLL function\n");
24 		FreeLibrary(hinstLib);
25 		return 1;
26 	}
27 
28 	// Call function.
29 	result = addNumbers(1, 2);
30 
31 	// Unload DLL file
32 	FreeLibrary(hinstLib);
33 
34 	// Display result
35 	printf("The result was: %f\n", result);
36 
37 	return 0;
38 }

زبان پایتون[ویرایش]

هشدار: کد زیر آسیب پذیر است؛ با راهنمایی مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد!

 1 import ctypes
 2 
 3 my_dll = ctypes.cdll.LoadLibrary("Example.dll")
 4 
 5 # The following "restype" method specification is needed to make
 6 # Python understand what type is returned by the function.
 7 my_dll.AddNumbers.restype = ctypes.c_double
 8 
 9 p = my_dll.AddNumbers(ctypes.c_double(1.0), ctypes.c_double(2.0))
10 
11 print "The result was:", p

مدل Object Component (COM) یک استاندارد باینری را برای میزبانی پیاده سازی اشیا در DLL و EXE تعیین می کند. این مکانیسم ها برای تعیین مکان و نسخه آن فایل ها و همچنین توضیح زبان مستقل و قابل خواندن در ماشین از رابط فراهم می کند. میزبان COM اجزای در یک DLL سبک تر است و به آنها اجازه می دهد که منابع را با فرایند مشتری به اشتراک بگذارند. این اجازه می دهد که اشیاء COM برای پیاده سازی پشتی های قدرتمند به قسمت های جلویی GUI ساده مانند ویژوال بیسیک و ASP. آنها همچنین می توانند از زبان اسکریپتی برنامه ریزی شوند.[۷]

با توجه به آسیب پذیری که معمولا به عنوان ربودن DLL شناخته می شود، DLL spoofing، DLL preloading یا کاوش باینری، بسیاری از برنامه ها DLL مخرب موجود در همان فولدر را به عنوان یک فایل داده باز شده توسط این برنامه ها اجرا می کنند.[۸][۹][۱۰][۱۱] این آسیب پذیری توسط Georgi Guninski در سال 2000 کشف شد.[۱۲] در آگوست 2010، بعد از آنکه امنیت ACROS دوباره آن را کشف کرد و بعد از چندین صدها برنامه آسیب پذیر شد، آن را در سراسر جهان تبلیغ کرد.[۱۳] برنامه هایی که از مکان های ناامن اجرا می شوند، یعنی پوشه های قابل خواندن کاربر مانند دانلودها یا پوشه Temp ، تقریبا همیشه به این آسیب پذیری حساس هستند.[۱۴][۱۵][۱۶][۱۷][۱۸][۱۹][۲۰]

همچنین نگاه کنید[ویرایش]

لینک های خارجی[ویرایش]

منابع[ویرایش]

  1. Microsoft Corporation. "Creating a Resource-Only DLL". Microsoft Developer Network Library.
  2. "The End of DLL Hell". Microsoft Corporation. Archived from the original on 2008-05-06. Retrieved 2009-07-11.
  3. "Linker Support for Delay-Loaded DLLs". Microsoft Corporation. Retrieved 2009-07-11.
  4. "دلفی (زبان برنامه‌نویسی)". ویکی‌پدیا، دانشنامهٔ آزاد. 2018-11-04.
  5. Petrusha, Ron (2005-04-26). "Creating a Windows DLL with Visual Basic". O'Reilly Media. Retrieved 2009-07-11.
  6. MSDN ، با استفاده از extern برای مشخص کردن پیوند
  7. Satran, Michael. "Component Object Model (COM)". msdn.microsoft.com.
  8. "DLL Preloading Attacks". msdn.com. Retrieved 25 March 2018.
  9. "More information about the DLL Preloading remote attack vector". technet.com. Retrieved 25 March 2018.
  10. "An update on the DLL-preloading remote attack vector". technet.com. Retrieved 25 March 2018.
  11. "Double clicking on MS Office documents from Windows Explorer may execute arbitrary programs in some cases". www.guninski.com. Retrieved 25 March 2018.
  12. "Binary Planting - The Official Web Site of a Forgotten Vulnerability . ACROS Security". www.binaryplanting.com. Retrieved 25 March 2018.
  13. "Dev to Mozilla: Please dump ancient Windows install processes". theregister.co.uk. Retrieved 25 March 2018.
  14. "Gpg4win - Security Advisory Gpg4win 2015-11-25". www.gpg4win.org. Retrieved 25 March 2018.
  15. "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.
  16. "fsc-2015-4 - F-Secure Labs". www.f-secure.com. Retrieved 25 March 2018.
  17. "ScanNow DLL Search Order Hijacking Vulnerability and Deprecation". rapid7.com. 21 December 2015. Retrieved 25 March 2018.
  18. 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.