ساختار فایل PE قسمت ۲ – Section ها
![](https://mrpythonblog.ir/wp-content/uploads/2023/06/Binary_executable_file2.png)
در قسمت قبلی مجموعه ساختار فایل های PE ، به بررسی بخش DOS HEADER & DOS STUB و NT HEADERS در فایل های PE پرداختیم . در این قسمت به بررسی Section های یک فایل PE خواهیم پرداخت .
همانطور که در قسمت قبلی اشاره شد ، یک فایل PE به طور کلی تشکیل شده از بخش های زیر است :
همانطور که در تصویر بالا مشاهده میکنیم در یک فایل 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 اضافه کنیم که برای مقاصد خاصی میتواند کاربردی باشد . در پست های آینده نمونه ای از کاربرد این موضوع را خواهیم داشت .
علاقه مند به دنیای کامپیوتر ها ...