ساختار فایل PE قسمت ۲ – Section ها

در قسمت قبلی مجموعه ساختار فایل های PE ، به بررسی بخش DOS HEADER & DOS STUB و NT HEADERS در فایل های PE پرداختیم . در این قسمت به بررسی Section های یک فایل PE خواهیم پرداخت .

همانطور که در قسمت قبلی اشاره شد ، یک فایل PE به طور کلی تشکیل شده از بخش های زیر است :

PE File Structure

همانطور که در تصویر بالا مشاهده میکنیم در یک فایل PE پس از بخش NT HEADERS ، بخش مربوط به Section ها قرار میگیرد که خود شامل دو بخش Section Table و Sections است . 

Section در فارسی از نظر لغوی به معنای “بخش” است . در تعریف Section اینگونه میتوان گفت که هر فایل PE شامل چندین بخش (Section) است که داده های آن داخل Section هایش ذخیره شده اند . در واقع Section ها یک روش دسته بندی و جداسازی اطلاعات مختلف از یکدیگر در فایل های PE است . ما در فایل های PE بخش ها یا Section های مختلفی داریم که داخل هر کدام از آن ها یک سری اطلاعات خاص ذخیره میشود و هر Section یک اسم دارد . برای مثال ما در فایل های اجرایی PE یک Section به نام “text.” داریم که کد های اجرایی فایل PE داخل این Section ذخیره میشود . همینطور یک Section به نام “data.” داریم که داده های مقدار دهی شده درون آن ذخیره میشوند . 

در فایل های PE اجرایی چندین Section پیشفرض و با اهداف مشخص وجود دارد که در ادامه آن ها را معرفی میکنیم. نمونه هایی از این Section های پیشفرض همان text. و data. بودند که معرفی کردیم . 

Section Table

هر Section در فایل PE دارای یک Header است که اطلاعاتی مثل اسم آن Section , اندازه اش ، آدرس اش و … داخل Header مربوط به آن نوشته شده است . در ساختار فایل PE بخشی وجود دارد به نام Section Table که در این بخش Header های تمام Section های موجود در فایل PE , به ترتیب در آن قرار میگیرند . به عبارتی به ازای هر Section در فایل PE ، یک Header در بخش Section Table وجود دارد . 

در فایل winnt.h یک ساختار مخصوص Section Header به نام IMAGE_SECTION_HEADER تعریف شده است . به شکلی میتوان گفت بخش Section Table در فایل های PE یک آرایه ای از ساختار IMAGE_SECTION_HEADER است که تعداد اعضای آن برابر مقدار فیلد NumberOfSections در FileHeader است که در قسمت قبلی توضیح دادیم . این ساختار به شکل زیر تعریف شده است :

typedef struct _IMAGE_SECTION_HEADER {
  BYTE  Name[IMAGE_SIZEOF_SHORT_NAME];
  union {
    DWORD PhysicalAddress;
    DWORD VirtualSize;
  } Misc;
  DWORD VirtualAddress;
  DWORD SizeOfRawData;
  DWORD PointerToRawData;
  DWORD PointerToRelocations;
  DWORD PointerToLinenumbers;
  WORD  NumberOfRelocations;
  WORD  NumberOfLinenumbers;
  DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

به بررسی فیلد های این ساختار میپردازیم .

Name : یک آرایه ۸ بایتی است که اسم Section در آن ذخیره میشود . اگر اسم Section کمتر از ۸ بایت باشد ، ادامه آرایه با صفر پر میشود در غیر این صورت اگر اسم Section دقیقا ۸ بایت باشد ، در کل این آرایه بدونه هیچ صفری در آخر آن نوشته میشود . دقت کنید اسامی بیشتر از ۸ بایت برای Section ها در فایل های اجرایی امروزی پشتیبانی نمیشود . 

PhysicalAddress و VirtualSize : همانطور که میبینید این دو مورد عضوی از یک union به نام Misc هستند . به عبارتی هر دو اینها دو اسم متفاوت هستند برای یک عضو . این عضو اندازه کل Section وقتی در حافظه بارگذاری میشود را به واحد بایت ذخیره میکند .

VirtualAddress : حاوی RVA اولین بایت این Section وقتی در حافظه بارگذاری میشود . 

SizeOfRawData : اندازه داده های مقداردهی شده (Initialized Data) داخل این Section روی دیسک در واحد بایت . این مقدار باید مضرب صحیحی از عضو FileAlignment در ساختار OptionalHeader باشد که در قسمت قبلی توضیح دادیم . اگر Section فقط حاوی داده های مقداردهی نشده (UnInitialized Data) باشد ، مقدار این فیلد صفر خواهد بود. 

به تفاوت میان فیلد های VirtualSize و SizeOfRawData دقت کنید . اولی اندازه Section وقتی در حافظه بارگذاری میشود را مشخص میکند ولی دومی اندازه داده های Section داخل فایل روی دیسک (و نه حافظه) . گاهی اوقات میتواند اندازه SizeOfRawData کوچک تر از VirtualSize باشد . در این صورت وقتی Section در حافظه بارگذاری میشود ، ادامه ی داده های Section با صفر پر میشود تا نهایتا اندازه آن به عددی که در فیلد VirtualSize مشخص شده است برسد .

PointerToRawData : آدرس شروع Section روی دیسک (offset) . این مقدار باید مضرب صحیحی از FileAlignment در OptionalHeader باشد .

PointerToRelocations , PointerToLineNumbers , NumberOfRelocations, NumberOfLineNumbers : در فایل های اجرایی امروزی برابر صفر خواهند بود .

Characteristics : این فیلد ویژگی های Section مثل اینکه آیا این Section حاوی کد اجرایی است یا نه. آیا حاوی داده مقدار دهی شده / مقدار دهی نشده است یا اینکه آیا این Section قابل اشتراک گذاری در حافظه است یا نه و خیلی ویژگی های دیگر که میتوانید مقادیر مختلف آن را از لینک زیر که مرجع اصلی است مطالعه کنید :

https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_section_header

 

Section های خاص در فایل PE

در فایل های PE میتوان به شکل دلخواه Section هایی با ویژگی های دلخواه تعریف کرد اما همانطور که پیش تر اشاره شد ، یکسری از Section ها در فایل های PE معنا های خاص دارند . این Section ها حاوی اطلاعاتی هستند که مورد نیاز Loader ویندوز هست تا بتواند از این فایل استفاده کند . طبق گفته مرجع اصلی ، خاص بودن این Section ها از طریق ویژگی های آن ها (فیلد Characteristics در Section Header) ، اسم Section یا اینکه مثلا یک جایی در OptionalHeader به داده های آن Section اشاره شده باشد مشخص میشود . برای مثال Section با نام text. حاوی کد های اجرایی فایل PE است . اگر یادتان باشد در OptionalHeader که قسمت قبلی معرفی کردیم فیلدی وجود داشت به نام AddressOfEntryPoint که به نقطه شروع کد های اجرایی فایل اشاره میکرد . این نقطه شروع در text. خواهد بود و از این جهت این یک Section خاص است .

در چند مورد از مرسوم ترین Section های خاص در فایل های PE را معرفی میکنیم :

text. : حاوی کد های اجرایی فایل PE

bss. : حاوی داده های مقدار دهی نشده (Uninitialized Data) 

data. : حاوی داده های مقدار دهی شده (Initialized Data)

edata. : اطلاعات مربوط به توابعی که این فایل PE صادر (Export) میکند در این Section ذخیره میشوند . (در مورد Export ها در قسمت های بعدی صحبت خواهد شد)

idata. : اطلاعات مربوط به توابعی که این فایل PE وارد (Import) میکند در این Section ذخیره میشود . (این بخش نیز در قسمت های بعدی توضیح داده میشود‌) 

rdata. : حاوی اطلاعات مقدار دهی شده فقط خواندنی (Read-Only)

برای مطالعه لیست کامل Section های خاص به مرجع رسمی مراجعه کنید .

بررسی Section های فایل های PE در PE-BEAR 

اگر یک فایل PE را در نرم افزار PE-BEAR که در قسمت قبلی معرفی شد باز کنیم ، این نرم افزار این قابلیت را دارد تا تمام Section های فایل به همراه ویژگی های آن Section ها را به ما نمایش دهد .  مثل قسمت قبلی فایل calc.exe را در ویندوز داخل نرم افزار PE-BEAR باز میکنیم و به تب Section Hdrs مراجعه میکنیم . همانطور که میبینید لیست تمام Section های داخل فایل به همراه اطلاعات مربوط به آن Section مثل آدرس شروع آن در حافظه ، اندازه آن ، ویژگی های آن و … به ما نمایش داده میشود :

جالب است بدانید نرم افزار PE-BEAR حتی به ما اجازه میدهد Section به یک فایل PE اضافه کنیم که برای مقاصد خاصی میتواند کاربردی باشد . در پست های آینده نمونه ای از کاربرد این موضوع را خواهیم داشت .

مارا دنبال کنید

پست های مرتبط

مطالعه این پست ها رو از دست ندین!

ساختار فایل PE قسمت ۵ – Relocation ها

مشکل از آنجایی شروع میشود که ویندوز ، همیشه فایل های PE را در آن آدرسی از حافظه که انتظار میرود بارگذاری نمیکند و در این صورت خیلی از چیز ها بهم میریزد ! در این بخش از ساختار فایل PE به بررسی Relocation ها در فایل PE میپردازیم . اینکه اصلا Relocation به چه معناست و در فایل PE چگونه پیاده سازی میشود .

بیشتر بخوانید

ساختار فایل PE قسمت ۴ – واردات (Imports)

در قسمت قبلی صادرات فایل های PE را بررسی کردیم . قطعا وقتی بحث صادرات را داریم ، از طرفی واردات را هم خواهیم داشت . فایل های PE در ویندوز میتوانند توابع صادراتی فایل های دیگر را وارد (Import) کرده و از آن ها استفاده کنند. این رفتار مستلزم این است که خود فایل های PE دیگر که از صادرات آن ها استفاده میکنیم نیز در حافظه بارگذاری شوند که این کار وظیفه ی Loader ویندوز است .

بیشتر بخوانید

ساختار فایل PE قسمت ۳ – صادرات (Exports)

در سیستم عامل ویندوز ، فایل های PE میتوانند توابعی را صادر (export) کنند تا فایل های PE دیگر از طریق وارد (import) کردن ، از آن ها استفاده کنند . این رفتار را اغلب در فایل های DLL مشاهده میکنیم ولی در واقعیت هر فایل PE حتی فایل های اجرایی میتوانند export هایی داشته باشند .

بیشتر بخوانید

نظرات

سوالات و نظراتتون رو با ما به اشتراک بذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *