این سوال که شما در مورد فرق Import Address Table و Bound Import Table پرسیدید، در حقیقت این مسئله مربوط به Speed Optimization در کامپایلرها و لینکر سیستم‌عامل می‌شود. 

شما اگر خودتان یک کامپایلر ساده نوشته باشید، یا در مورد کامپایلرها مطالعه کرده باشد، مخصوصا بخش بهینه‌سازی یا Optimization سرعت اجرای برنامه، با این نوع مباحث آشنایی دارید.

در حالت کلی Import Address Table یک جدول حاوی آدرس توابعی است که در برنامه یا همان پروسه اجرایی ما فراخوانی و مورد استفاده قرار گرفته‌اند. 

آدرس‌های درون این جدول هم در زمان اجرا توسط دینامیک لودر سیستم‌عامل محاسبه می‌شوند اما آدرس‌های درون جدول Bound Import در واقع به صورت استاتیک توسط لینکر زمان کامپایل برنامه مشخص می‌شوند.

آدرس‌های درون Bound Import هم با این تصور توسط کامپایلر محاسبه می‌شوند که مثلا کتابخانه Milad.dll در بیس آدرس 20000  لود خواهد شد و پس تابع MPrint هم به نسبت این بیس آدرس در حافظه در آدرس 20300 قرار خواهد گرفت. 

حال اگر مثلا Milad.dll در بیس آدرس پیش فرض لود شود، دیگر نیاز نیست دینامیک لودر به صورت پویا جایگاه آدرس توابع در حافظه را محاسبه و جدولIAT  را پر کند، از همین جدول برای دسترسی به توابع استفاده خواهد شد که سرعت اجرای برنامه را افزایش خواهد داد (به دلیل اینکه تاخیر لودر برای ریزالو آدرس‌ها دیگر وجود ندارد). 

اینم سوال خوبی بود که یکی از دوستان پرسید که اگر مثلا کتابخانه‌ای به روزرسانی شد و آفست‌ها و آدرس‌ها دچار تغییر شدند، برنامه (لودر) چطور می‌تواند با استفاده از جدول Bound Import که به صورت استاتیک مقادیر آن مشخص می‌شوند، آدرس‌ توابعی که دچار تغییر شده‌اند را ریزالو کند.

به شکل خیلی ساده ای این کار صورت خواهد گرفت. شما وقتی استراکچر Image_Bound_Import_Descriptor را مورد بررسی قرار بدهید، متوجه خواهید شد که این استراکچر دارای سه مولفه اصلی TimeDateStamp، OffsetModuleName و ForwarderRef است که البته ساختار آن را در عکس زیر مشاهده کنید. 

لودر خیلی راحت می تواند با بررسی TimeDateStamp کتابخانه پویا این مورد را بررسی کند که آیا کتابخانه دچار تغییر و به‌روزرسانی شده است یا خیر. 

اگر TimeDateStamp کتابخانه تغییر کرده باشد جدول Import Address Table به صورت عادی توسط دینامیک لودر پر خواهد شد. این مولفه TimeDateStamp برای خوشگلی نیست، از منظر سیستم کاربرد زیاد دارد.

اگر هم کتابخانه تغییری نکرده باشد، از همان آدرس‌های استاتیک تولید شده توسط لینکر در زمان کامپایل استفاده می‌شود. کلا تو ویندوز و مکینتاش همه چیز تو در تو هست. آدم سر درد می‌گیره. 😤👹👺

با این حال، اساسا این مبحث Binding یا همین Bound Import در سامانه‌های عامل مدرن کاملا بی معنا است که من صرفا برای آشنایی با مبحث آن را توضیح دادم. چون روی تمامی سامانه‌های عامل مدرن مانند ویندوز، لینوکس و مکینتاش ما یک ویژگی امنیتی داریم به نام ASLR یا همان Address Space Layout Randomisation که هر فایلی یا ماژولی بر روی حافظه بارگزاری شود، ساختار آن را در حافظه دستکاری می‌کند. لذا آدرس‌ها دینامیک و غیرقابل پیش‌بینی هستند که این در تضاد با مبحث Bound Import است.

الان عموما برای بهبود بهینگی اجرای یک برنامه از Delay Load یا همان Lazy Linking استفاده می‌شود که هر تابع که مورد نیاز برنامه است، در زمان نیاز کتابخانه آن در حافظه بارگزاری شود و تابع درون آن اجرا شود که این موجب بهینه شدن استفاده برنامه از فضای حافظه می‌شود. خلاصه مبحث بهینه‌سازی کلا داستان زیاد دارد و بهتر است کتاب‌های این حوزه را مطالعه کنید. 


@miladkahsarialhadi

@miladkahsarialhadi