مسئله‌ای که من در مورد Import Name Table، Import Ordinal Table و Import Address Table توضیح دادم، خیلی هم درست و دقیق بود. اینکه تو برخی از گروه‌ها مطالب کانال بنده را اشتراک می‌گذارید و اشکال می‌گیرید، بجای این کار به خود من پیام بدهید تا جواب شما را کامل بدهم. 

اولا من فقط قصد داشتم کانسپت مسئله (اهمیت جداول IAT و INT و IOT) را توضیح بدهم که وقتی شما در دیزاسمبلری مانند IDA یا یک دیباگری مانند LLDB یک اینستراکش مانند call ds:20304050 مشاهده می‌کنید، این آدرس 20304050  به این سادگی‌ها توسط دینامیک لودر سیستم‌عامل تولید نشده است.

در پس‌زمینه سامانه‌عامل کلی اتفاق رخ می‌دهد که وقتی شما تابعی را فراخوانی می‌کنید، سیستم‌عامل بتواند جایگاه بلاک کد تابع را در فضای آدرس پروسه (Process Address Space) پیدا کند و دستورات تابع را یک به یک اجرا و در نهایت به مسیر تابع Caller بازگشت کند.

اما این شناسایی آدرس توابع به چه صورت رخ می‌دهد؟ اولا که شما وقتی در محیط ویندوز کار می‌کنید باید با دو مفهوم RVA و VA یا همان Relative Virtual Address و Virtual Address آشنا شوید. 

این دو مفهوم در محیط ویندوز با هم تفاوت دارند و ویندوز رویکرد آن استفاده از RVA است. یعنی یک آدرس را به عنوان بیس انتخاب می‌کند که در فایل فرمت PE فیلد ImageBase حاوی این آدرس بیس است و مابقی چیزها مانند سکشن‌ها، دیرکتوری‌ها، تیبل‌ها و مسائل دیگر را به نسبت این آدرس معرفی یا پاسخگویی می‌کند. 

یعنی وقتی شما مشاهده می‌کنید آدرس بیس یک ایمج 100000000 است و آدرس نسبی سکشن RDATA به عنوان مثال 2030 است، در اصل سکشن RDATA در هنگام ترسیم (Map) به درون حافظه (Memory) در آدرس 100002030 قرار دارد که در نهایت به آدرس 100002030 آدرس مجازی یا همان Virtual Address سکشن RDATA در حافظه گویند. این اولین نکته است.

دومین مسئله این است که چطور دینامیک لودر ویندوز می‌تواند آدرس توابع را در حالت زمان اجرا یا همان Runtime به صورت بلادرنگ یا همان Real-Time ریزالو کند؟ 

ما در فایل فرمت PE سیستم عامل ویندوز چندین دیرکتوری بسیار مهم داریم که اطلاعات بسیار مهمی را در بر می‌گیرند، یکی از این دیرکتوری‌ها در حقیقت دیرکتوری Import Directory است که یک بازتعریف از استراکچر Image_Import_Descriptor است که به صورت آرایه برای هر DLL تعریف می‌شود.

این استراکچر چندین مولفه مهم دارد که به عنوان Original First Thunk، First Thunk و Name شناسایی می‌شوند (مهم‌ترین اعضا این سه تا هستند) که در حقیقت عضو Original First Thunk به جدول Import Name Table و عضو First Thunk به جدول Import Address Table، و مولفه Name هم به نام کتابخانه DLL که توابع در آن قرار دارند، اشاره می‌کنند.

جدول Import Name Table حاول نام توابعی می‌شود که از یک DLL به برنامه فراخوانی شده‌اند و جدول Import Address Table هم حاوی آدرس متناظر با نام توابع در جدول INT است. 

مثلا اگر تابع Milad در جدول INT در اندیس 5 شناسایی شود، لودر به اندیس شماره 5 جدول ENT یا همان Export Name Table کتابخانه DLL می‌رود که در آنجا آدرس اصلی تابع Milad قرار دارد. آن آدرس را بر می دارد و در جدول IAT پروسه قرار می‌دهد. با این روند برنامه می‌تواند آدرس تابع Milad را با رجوع به جدول IAT شناسایی و آن را فراخوانی کند. 

به عنوان مثال در تصویر بالا مشاهده میکنید، مقدار فیلد ImageBase پروسه MathClient ما برابر با 400000 است و آدرس نسبی جدول IAT ما (تصویر پایین) در آدرس 3000 است که اگر آن را با آدرس ImageBase جمع کنیم، مقدار آن برابر با 4003000 می‌شود.

اگر هم بخواهیم به قسمت جدول IAT توابع وارد شده از کتابخانه MathLibrary برویم، باید ببینیم فیلد FT این کتابخانه در دیرکتوری Import پروسه ما شامل چه RVA می‌شود که آن را با ImageBase جمع کنیم و مستقیم وارد جدول این کتابخانه شویم. همانطور که در تصویر زیر مشاهده می‌کنید مقدار آدرس نسبی این جدول 3064  است.

حال اگر برنامه را در دیباگر WinDBG بارگزاری کنیم و در پنجره مموری به این آدرس (MathClient+3064) برویم مقادیر موجود در این جدول را مشاهده خواهید کرد که قبل از اجرای برنامه در این فیلدها مقادیر هینت‌های توابع وجود دارد (تصویر پایین).

بعد که برنامه را اجرا کنیم، مشاهده خواهید کرد که به جای مقادیر هینت‌ها لودر آدرس توابع فراخوانی شده از کتابخانه MathLibrary را در این جدول قرار می‌دهد (تصویر بالا) که حال شما می‌توانید با دستور ln و آدرس فیلدهای درون جدول IAT سیگنیچر یا نام توابع را مشاهده کنید (تصویر پایین).

خلاصه اینکه خیلی داستان پیچیده‌تر از آن چیزی است که شما فکر می‌کنید. من هم واقعا توانایی توضیح تمامی این مباحث را به صورت نوشتاری ندارم، چون نوشتن واقعا کار سختی است. همین الان هم کلی از جزئیات را حوصله نکردم توضیح بدهم. 


@miladkahsarialhadi