You are on page 1of 16

‫دانشکده مهندسی کامپیوتر‬

‫گروه مهندسی نرم افزار‬

‫عنوان پروژه‪:‬‬

‫بررسی ساختار فایل های ‪PE‬‬

‫پیش نویس اول پروژه کالسی شماره ‪ 3‬درس کامپایلر پیشرفته‬

‫دانشجویان‪:‬‬

‫مرتضی ذاکری‬

‫استاد‪:‬‬

‫دکتر سعید پارسا‬

‫پاییز ‪1395‬‬
‫‪ ‬فهرست‬

‫فهرست مطالب‬

‫‪ 1‬مقدمه ‪1 ...........................................................................................‬‬

‫‪ 2‬ساختار کلی‪1 ..........................................................................................................‬‬

‫‪4 ............................................................................. DOS HEADER‬‬


‫‪4 .......................................................................... PE FILE HEADER‬‬
‫‪4 ....................................................................... OPTIONAL HEADER‬‬
‫‪2‬ـ‪3‬ـ‪4 ................................................................... DATA DIRECTORY 1‬‬
‫‪5 ............................................................................ SECTION TABLE‬‬
‫‪ SECTION‬ها ‪5 .................................................................................‬‬
‫‪2‬ـ‪5‬ـ‪ 1‬برخی از ‪SECTION‬های رایج ‪5 ..........................................................‬‬

‫‪ 3‬مطالعه موردی فایل ‪ PE‬یک برنامه ساده ‪7 ..........................................................‬‬

‫معرفی برنامه ‪7 .................................................................................‬‬


‫کد برنامه و فایل اجرایی ‪7 .....................................................................‬‬
‫برنامه نویسی نمایش ساختار فایل ‪9 ..................................................... PE‬‬
‫بررسی فایل اجرایی برنامه اعداد اول ‪10 .....................................................‬‬
‫تفاوت نسخه های ‪ 32‬بیتی و ‪ 64‬بیتی فایل های ‪12 .................................. PE‬‬
‫نتیجه گیری ‪13 ...............................................................................‬‬

‫‪ 4‬منابع و ماخذ ‪13 ..............................................................................................‬‬

‫ب‬
‫‪ ‬فهرست‬

‫فهرست شکل ها‬

‫شکل ‪1-2‬ساختار کلی فایل ‪2 ....................................................................... PE‬‬


‫شکل ‪ 2-2‬ساختار فایل ‪ PE‬با جزئیات بیش تر ‪3 .......................................................‬‬
‫شکل ‪ 3-2‬نمایش ‪ HEX‬از یک فایل ‪6 .............................................................. PE‬‬
‫شکل ‪ 1-3‬کد برنامه تعیین عدد اول ‪8 ...................................................................‬‬
‫شکل ‪ 2-3‬ساختار فایل ‪ PE‬در ابزار ‪10 .............................................. NIKPEVIEWER‬‬
‫شکل ‪ 3-3‬بخش ‪11 .................................................................... DOS HEADER‬‬
‫شکل ‪ 4-3‬نمایش دودویی بخش ‪11 .................................................. DOS HEADER‬‬
‫شکل ‪ 5-3‬پیدا کردن ثابت های رشته ای برنامه در فایل دودویی ‪12 .................................‬‬

‫ت‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪ 1‬مقدمه‬

‫فایل ‪ PE‬یا ‪ Portable Executable‬قالب فایلی ا ست که در سی ستم ها عامل ویندوز به کار می‬
‫رود (در هر دو نسخه ‪ 32‬و ‪ 64‬بیتی)‪ PE .‬قالب استاندارد شده ای برای فایل هایی با پسوند های‬
‫رایج زیر است‪:‬‬

‫… ‪.exe, .dll, .obj, .acm, .ax, .cpl, .drv, .efi,‬‬

‫در واقع ‪ PE‬داده ســاختاری اســت شــامل االالعات از برای ماژول بارکننده برنامه در‬
‫سی ستم عامل که نهایتا فایل را برای اجرا شدن در حافظه قرار می دهد‪ .‬قبل از ابداع این قالب‪،‬‬
‫قالبی به نا ‪ COFF‬وجود داشت که در سیستم های ‪ Windows NT‬استفاده می شد‪.‬‬

‫‪ 2‬ساختار کلی‬

‫اساسا فایل ‪ PE‬از دو بخش تقسیم شده است که هریک دارای زیر بخش های مختلفی می باشد‪.‬‬
‫بخش اول ‪ Header‬و بخش دیگر ‪ Section‬نا دارد‪ .‬شــکل ‪ 1-2‬بخش های اصــلی و زیر بخش‬
‫های درون هریک را به صورت گرافیکی نشان می دهد‪.‬‬

‫‪1‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪PE‬‬ ‫شکل ‪1-2‬ساختار کلی فایل‬

‫در شکل ‪ 2-2‬جزئیات بیش تری را می توان مشاهده کرد‪.‬‬

‫‪2‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫شکل ‪ 2-2‬ساختار فایل ‪ PE‬با جزئیات بیش تر‬

‫‪3‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪DOS Header‬‬

‫‪ DOS Header‬یا ‪ 64 DOS MZ Header‬بایت اول هر فایل ‪ PE‬را ت شکیل می دهد‪ .‬این ق سمت‬
‫تو سط بارکننده ‪ DOS‬برر سی می شود و در صورتی که معتبر با شد برنامه ‪ DOS STUB‬اجرا می‬
‫شـــود‪ .‬اما هنگامی که فایل ‪ PE‬حاوی برنامه ‪ Win32‬باشـــد‪ ،‬در بخش ‪ DOS Header‬پرش به‬
‫ابتدای ‪ PE File Header‬انجا شده و ‪ DOS STUB‬نیز حاوی کد چاپ پیا زیر می شود‪.‬‬

‫"‪"This program cannot run in DOS mode‬‬

‫بنابراین هنگامی که فایل ‪ PE‬در محیط ‪ DOS‬اجرا شـــود‪ ،‬با ورود بخش حاوی برنامه کوچک‬
‫‪ DOS STUB‬پیا فوق به کاربر نمایش داده می شود‪.‬‬

‫‪PE File Header‬‬

‫شـــا مل االال عاتی مان ند نوع پرداز نده‪ ،‬ت عداد کل ‪ Section‬های فا یل ‪ PE‬جاری‪ ،‬مهر ز مان‬
‫(‪ )TimeStamp‬و غیره است‪ .‬آغاز این قسمت با فیلد موسو به ‪ PE Signature‬است که محتوی‬
‫کد اسکی ‪ 45 00‬یا همان عبارت ‪ PE 00‬می باشد‪.‬‬

‫‪Optional Header‬‬

‫علی رقم وجود واژه اختیاری در نا این ق سمت‪ ،‬االالعات مهمی در آن قرار می گیرند‪ .‬چند قلم‬
‫از این االالعات عبارتند از‪ MajorLinkerVersion :‬و ‪ MinorLinkerVersion‬شماره نسخه برنامه‬
‫‪ Linker‬که این فایل را ایجاد کرده اســـت‪ SizeOfCode .‬اندازه همه ‪ Section‬های حاوی کد‬
‫برنامه‪ AddressOfEntryPoint .‬آدرســـی که بار کننده اجرا را از آنجا آغاز می کند‪ .‬این فیلد‬
‫حاوی ادرس مجازی ن سبی یه همان ‪ RVA‬می با شد که به محلی در بخش ‪ .text‬ا شاره می کند‬
‫و ‪. ...‬‬

‫‪2‬ـ‪3‬ـ‪Data Directory 1‬‬

‫یک زیر بخش مهم در ‪ Optional Header‬فیلدی تحت عنوان ‪ Data Directory‬اســـت‪ .‬این‬
‫بخش در واقع آرایه ای از ساختارهای ‪ IMAGE_DATA_DIRECTORY‬ا ست‪ .‬هر ساختار آدرس‬

‫‪4‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫مجازی ن سبی‪ ،‬یک ساختار داده مهم در فایل ‪ PE‬همچون جدول آدرس واردات فایل ( ‪import‬‬

‫‪ )address table‬را ارائه می دهد‪.‬‬

‫‪Section Table‬‬

‫بین بخش ‪ PE Header‬و ‪ Section‬ها این قســمت قرار گرفته اســت‪ Section Table .‬در واقع‬
‫‪1‬‬
‫شــبیه یک دفترچه تلفن اســت که االالعاتی راجع به هر ‪ Section‬موجود در تصــویر حافظه‬
‫برنامه را در بردارد‪ Section .‬ها بر ا ساس ادرس شروع مجازی خود در حافظه مرتب می شوند‬
‫نه عناوینشان‪.‬‬

‫‪ Section‬ها‬

‫تعداد و نا ‪Section‬ها در فایل های ‪ PE‬می تواند مختلف باشــد‪ .‬اما برای هر ‪ Section‬االالعات‬
‫یکســانی باید نگاهداری گردد‪ .‬فایل ‪ EXE‬در مورد ‪Section‬هایش االالعات نظیر آدرس فیزیکی‪،‬‬
‫آدرس مجازی‪ ،‬اندازه االالعات و نوع دســترســی های موجود از قبیل خواندن‪ ،‬نوشــتن و اجرا را‬
‫نگهداری می کند‪.‬‬

‫‪2‬ـ‪5‬ـ‪ 1‬برخی از ‪Section‬های رایج‬

‫در این ق سمت تعدادی از ‪Section‬هایی را که در فایل های ‪ .exe‬و ‪ .obj‬وجود دارند معرفی می‬
‫کنیم‪ .‬معموا عنوان هر ‪ Section‬با یک نط قه آغاز می شـــود ولی الزامی برای این کار وجود‬
‫ندارد‪ ،‬یعنی می تواند بدون نقطه هم باشد‪.‬‬

‫‪ .text‬این ‪ Section‬جایی است که همه کدهای برنامه که توسط کامپایلر یا اسمبلر تولید شده‬
‫است نوشته می شود‪.‬‬

‫‪ .rsrc‬شامل تما ماژول های به کار رفته در برنامه است‪.‬‬

‫‪1‬‬
‫‪Image‬‬

‫‪5‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪ .idata‬شــامل داده ها و تابع هایی اســت که از ماژول های ‪ DLL‬دیگر در این فایل درج شــده‬
‫است‪.‬‬

‫و ‪. ...‬‬

‫آن چه گفته شده تو ضیح ب سیار مخت صری از اجزای موجود در ساختار فایل ‪ PE‬بود و‬
‫وارد بسیاری از جزئیات نشدیم‪ .‬شکل ‪ 3-2‬نمایش یک فایل ‪ PE‬به صورت کد ‪ HEX‬می باشد که‬
‫بخش های گفته شده در آن م شخص شده اند‪ .‬همان الور که پیدا ست این پایین ترین سطح‬
‫نمایشی از یک برنامه و در واقع نمایش در سطح ماشین است ( صفر و یک)‪ .‬در بخش سو این‬
‫نوشتار یک فایل ‪ PE‬را در عمل بررسی می کنیم‪.‬‬

‫‪PE‬‬ ‫شکل ‪ 3-2‬نمایش ‪ HEX‬از یک فایل‬

‫‪6‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪ 3‬مطالعه موردی فایل ‪ PE‬یک برنامه ساده‬

‫معرفی برنامه‬

‫در این قســمت یک برنامه بســیار کوچک به زبان ‪ C++‬در ‪ Win32‬می نویســیم و ســپس آن را‬
‫کامپایل می کنیم تا فایل اجرایی در قالب ‪ EXE‬تولید شـــود‪ .‬در ادامه ســـاختار فایل ‪ EXE‬تولید‬
‫شده را که از قالب فایل های ‪ PE‬پیروی می کند برر سی می کنیم تا موارد شرح داده شده در‬
‫بخش ‪ 2‬این نوشتار را به صورت عملی مشاهده نماییم‪.‬‬

‫دلیل آن که خود به نوشـــتن یک برنامه مبادرت ورزیدیم این اســـت که از ســـاختار و‬


‫عملکرد بیرونی کد االالع دا شته با شیم و بتوانیم نتایج م شاهده شده را با آن چه بای ستی وجود‬
‫دا شته با شد تطابق دهیم‪ .‬به عبارت دیگر می خواهیم ساختار زمان اجرای یک برنامه کاربردی‬
‫کوچک را که قرار است توسط بارکننده های ویندوزی بارگذاری شود با آگاهی و تسلط بر نحوه‬
‫عملکرد و محتوای کد منبع و منابع مورد ا ستفاده آن‪ ،‬م شاهده و برر سی نماییم‪ .‬مینیمال بودن‬
‫برنامه این امکان را به ما می دهد تا با پیچیدگی های نا شی از بزرگ بودن برنامه مواجه ن شویم‬
‫و بر روی هدف اصلی که شناخت ساختار فایل ‪ PE‬است تمرکز داشته باشیم‪.‬‬

‫برنامه ای که در این جا نوشــته ایم در واقع یک عدد را از کنســول ورودی می خواند و‬


‫تعیین می کند که اول اســت یا خیر و در نهایت پیا مناســب صــادر می کند‪ .‬برنامه شــامل‬
‫دســتورات شــرالی‪ ،‬حلقه تکرار‪ ،‬فراخوانی تابع‪ ،‬ثابت های رشــته ای و دیگر جنبه های برنامه‬
‫نویسی است که به نحوی که بتواند خیلی خوب ما را در یک روند آموزشی مناسب هدایت کند‪.‬‬

‫کد برنامه و فایل اجرایی‬

‫کد برنامه به صورت شکل ‪ 1-3‬است‪ .‬برنامه در محیط ‪ Microsoft Visual Studio 2015‬نوشته‬
‫و کامپایل شده ا ست‪ .‬دو ن سخه اجرایی ‪ 64‬و ‪ 32‬بیتی از برنامه ایجاد کرده ایم تا بتوانیم تفاوت‬
‫های ساختار فایل های ‪ PE‬در نسخه های مختلف را بررسی کنیم‪.‬‬

‫‪7‬‬
PE ‫ بررسی ساختار فایل های‬

#include <iostream>
using namespace std;

void checkPrime(int n)
{
int flag = 1;
for (int i = 2; i*i < n && flag; i++)
{
if (!(n%i))
{
flag = 0;
}
}

if (!flag)
{
cout << "Is Not Prime!\n";
}
else
{
cout << "Is Prime!\n";
}
}

int main()
{
int n;
cout << "Enter Number: ";
cin >> n;
checkPrime(n);
system("pause");
return 0;
}

‫ کد برنامه تعیین عدد اول‬1-3 ‫شکل‬

8
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫برنامه نویسی نمایش ساختار فایل ‪PE‬‬

‫فایل ‪ PE‬یک محتوی یک کد دودویی ا ست بنابراین از نوع متنی نی ست و نمی توان با ویرا ستار‬
‫های متنی آن را گ شود و ساختار آن را م شاهده کرد‪ .‬اما می توان آن را با یک ویرای شگر فایل‬
‫های ‪ HEX‬یا همان باینری گ شود‪ .‬برنامه های ب سیاری ه ستند که برای نمایش ساختار فایل ‪PE‬‬
‫ا ستفاده می شوند و عالوه بر نمایش مقادیر دودویی اجزا را به صورت البقه بندی شده ن شان‬
‫داده و االالعات را از پیکره فایل ‪ PE‬بیرون می کشـــند‪ .‬این برنامه ها عمدتا در امکاناتی نظیر‬
‫ج ست و جو و وا سط کاربر تفاوت هایی دارند‪ .‬ما فهر ستی از برنامه ها را ت ست کردیم تا گزینه‬
‫بهتر را انتخاب کنیم؛ از جمله‪:‬‬

‫… ‪PE Explorer, PEBrowse64, NikPEViewer, x64/32dbg,‬‬

‫کلیه اجزای موجود در فایل های ‪ PE‬توســط ســاختارهای برنامه نویســی زبان ‪C/C++‬‬
‫تعریف می شوند‪ .‬برای نمونه بخش ‪ DOS Header‬به صورت زیر در زبان ‪ C‬تعریف می شود‪ ،‬این‬
‫ساختار در داخل فایل سرایند ‪ WINNT.H‬وجود دارد‪.‬‬

‫‪typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header‬‬


‫;‪USHORT e_magic‬‬ ‫‪// Magic number‬‬
‫;‪USHORT e_cblp‬‬ ‫‪// Bytes on last page of file‬‬
‫;‪USHORT e_cp‬‬ ‫***‬
‫‪// Pages in file‬‬
‫;‪USHORT e_crlc‬‬ ‫‪// Relocations‬‬
‫;‪USHORT e_cparhdr‬‬ ‫‪// Size of header in paragraphs‬‬
‫;‪USHORT e_minalloc‬‬ ‫‪// Minimum extra paragraphs needed‬‬
‫;‪USHORT e_maxalloc‬‬ ‫‪// Maximum extra paragraphs needed‬‬
‫;‪USHORT e_ss‬‬ ‫‪// Initial (relative) SS value‬‬
‫;‪USHORT e_sp‬‬ ‫‪// Initial SP value‬‬
‫;‪USHORT e_csum‬‬ ‫‪// Checksum‬‬
‫;‪USHORT e_ip‬‬ ‫‪// Initial IP value‬‬
‫;‪USHORT e_cs‬‬ ‫‪// Initial (relative) CS value‬‬
‫;‪USHORT e_lfarlc‬‬ ‫‪// File address of relocation table‬‬
‫;‪USHORT e_ovno‬‬ ‫‪// Overlay number‬‬
‫;]‪USHORT e_res[4‬‬ ‫‪// Reserved words‬‬
‫;‪USHORT e_oemid‬‬ ‫)‪// OEM identifier (for e_oeminfo‬‬
‫;‪USHORT e_oeminfo‬‬ ‫‪// OEM information; e_oemid specific‬‬
‫;]‪USHORT e_res2[10‬‬ ‫‪// Reserved words‬‬
‫‪LONG‬‬ ‫;‪e_lfanew‬‬ ‫‪// File address of new exe header‬‬
‫;‪} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER‬‬

‫بدیهی ا ست که ‪ API‬ویندوز توابعی را برای کار با این داده ساختار ها تدارک دیده ا ست‪ .‬برنامه‬
‫های نمایش ســاختار ‪ PE‬که در باا به برخی از آن ها اشــاره شــد‪ ،‬از چنین توابعی اســتفاده می‬

‫‪9‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫کنند‪ .‬بنابراین نو شتن یک برنامه که بتواند نمایش صحیحی از فایل ‪ PE‬ارایه دهد کار ساده ای‬
‫است‪.‬‬

‫بررسی فایل اجرایی برنامه اعداد اول‬

‫فایل با عنوان ‪ SimplePE_x86.exe‬را توســط ‪ NikPEViewer‬باز می کنیم (شــکل زیر)‪ .‬همان‬


‫الور که پیداست‪ ،‬پنجره های زیر هر کدا بخش مجزایی از ساختار را نشان می دهند‪.‬‬

‫‪NikPEViewer‬‬ ‫شکل ‪ 2-3‬ساختار فایل ‪ PE‬در ابزار‬

‫بخش ‪ DOS MZ Header‬خالی است و تنها یک دستور پرش به ‪ F8‬که ابتدای ‪PE File Header‬‬
‫ا ست دارد‪ .‬االالعات شکل ‪ 3-3‬از شکل ‪ 4-3‬که معادل دودویی آن ا ست بیرون ک شیده شده‬
‫است‪.‬‬

‫‪10‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫‪DOS Header‬‬ ‫شکل ‪ 3-3‬بخش‬

‫‪DOS Header‬‬ ‫شکل ‪ 4-3‬نمایش دودویی بخش‬

‫به همین ترتیب می توان سایر ق سمت های بخش دو این نو شتار را م شاهده کرد‪ .‬به‬
‫عنوان مثال کد برنامه در ‪ .text‬و ثابت های رشــته ای در ‪ .rdata‬تعریف شــده اند‪ .‬هنگامی که‬
‫برنامه اجرا می شــود‪ ،‬پیا "‪ "Enter Number:‬روی کنســول به نمایش در می آید‪ .‬می خواهیم‬
‫محل این پیا را در فایل باینری بیابیم‪ .‬در منوی سمت چپ روی ‪ .rdata‬دوبار کلیک می کنیم‬
‫تا محدوده مربوط به این ‪ Section‬در کد باینری یافت شــود‪ .‬حال این محدوده را مشــاهده می‬
‫کنیم‪.‬‬

‫چنان چه مشــاهده می شــود کلیه ثابت های رشــته ای برنامه در قالب کد اســکی و به‬
‫صــورت متوالی ذخیره شــده اند‪ .‬ادرس محل ذخیره موجودیت غیر فعال (کد برنامه) نیز در این‬
‫قسمت وجود دارد‪.‬‬

‫‪11‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫شکل ‪ 5-3‬پیدا کردن ثابت های رشته ای برنامه در فایل دودویی‬

‫تفاوت نسخه های ‪ 32‬بیتی و ‪ 64‬بیتی فایل های ‪PE‬‬

‫قالب فایل های اجرایی در ویندوزهای ‪ 64‬بیتی (‪ )x64‬نیز مانند ویندوز ‪ 32‬بیتی (‪ )x86‬همان‬
‫قالب فایل ‪ PE‬است‪ ،‬اما تفاوت هایی دارد‪ .‬در این جا کشف این تفاوت ها یک نسخه ‪ 64‬بیتی از‬
‫برنامه بررسی اعداد اول که در قسمت قبل دیدیم را ایجاد می کنیم‪ .‬سپس آن را در محیط ابزار‬
‫‪ NikPEViewer‬باز می کنیم‪.‬‬

‫اولین تفاوت در حجم ن سخه های ‪ 32‬بیتی و ‪64‬بیتی ا ست‪ .‬ن سخه ‪ 64‬بیتی ما حدودا‬
‫‪ 1‬کیلوبایت از نسخه ‪ 32‬بیتی‪ ،‬بزرگتر است (‪ 13‬کیلوبایت در مقابل ‪ 12‬کیلوبایت)‪.‬‬

‫‪12‬‬
‫‪ ‬بررسی ساختار فایل های ‪PE‬‬

‫آف ست شروع ‪ PE Header File‬متفاوت ا ست (‪ .)0x00000100‬آدرس های مجازی ‪64‬‬


‫بیتی هستند‪ .‬به الور کلی اندازه ‪Section‬ها و مقدار ‪ RVA‬ها نیز متفاوت است‪.‬‬

‫نتیجه گیری‬

‫از ابزار ‪ NikPEViewer‬تفاوت های بیش تری را نمی توان تشــخیص داد‪ .‬با اســتفاده از‬
‫ابزار ‪ IDA Pro‬مشاهده می شود از آن جایی که برنامه از نوع ‪ Win32‬می باشد لذا در نسخه ‪64‬‬
‫بیتی نیز همچنان از ثبات های ‪ 32‬بیتی اســتفاده شــده اســت و از این لحاظ مزیتی ندارد‪ .‬می‬
‫توان این نتیجه را گرفت که با وجود تفاوت های جزیی ساختار کلی همان ساختار ‪ PE‬ا ست و‬
‫در واقع برای به حداکثر ر سانی قابلیت حمل این فایل ها تفاوت ا سا سی در آن ها ایجاد ن شده‬
‫است‪.‬‬

‫‪ 4‬منابع و ماخذ‬

‫‪13‬‬

You might also like