Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the rank-math domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the woo-wallet domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the woocommerce domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the elementor-pro domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function is_feed was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function is_feed was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.0.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Function _load_textdomain_just_in_time was called incorrectly. بارگذاری ترجمه برای دامنه shokrino زودتر از حد مجاز فراخوانی شد. این معمولاً نشان‌دهندهٔ اجرای کدی در افزونه یا پوسته است که خیلی زود اجرا شده است. ترجمه‌ها باید در عملیات init یا بعد از آن بارگذاری شوند. Please see Debugging in WordPress for more information. (این پیام در نگارش 6.7.0 افزوده شده است.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131

Notice: Undefined index: secret_key in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/themes/shokrino/inc/core/functions-init.php on line 754

Deprecated: Non-static method shokrino_zg_admin_setting_bought::is_activated() should not be called statically in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/themes/shokrino/inc/core/functions-init.php on line 1486
ساختار فایل PE قسمت ۵ - Relocation ها - مستر پایتون

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


Notice: Undefined offset: 0 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 246

Notice: Undefined offset: 1 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 247

Notice: Undefined offset: 2 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 248

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

Relocation چیست ؟

همانطور که در بخش اول ساختار فایل PE (قسمت header ها) شرح داده شد ، در بخش OptionalHeader فایل های PE فیلدی به نام ImageBase موجود میباشد . این فیلد حاوی آدرسی از حافظه است که ترجیح داده شده تا فایل PE در آن بارگذاری شود . اگر در مورد ویندوز های قدیمی مثل XP صحبت کنیم ، فایل های PE معمولا در همین آدرسی که فیلد ImageBase میگوید بارگذاری میشوند مگر زمانی که آن آدرس اشغال باشد . برای مثال اگر یک فایل exe میخواهد در آدرس 0x00400000 بارگذاری شود و از بخت بد قبلا در این آدرس یک فایل PE دیگر بارگذاری شده باشد ، loader ویندوز مجبور است این فایل را در آدرسی غیر از آن چیزی که ImageBase میگوید بارگذاری کند .

این در مورد ویندوز های قدیمی است . در ویندوز های جدید (ویندوز ۷ به بعد) ، تقریبا هیچوقت یک فایل PE در آدرسی که ImageBase آن فایل میگوید بارگذاری نمیشود ! . دلیل این اتفاق وجود مکانیزم امنیتی به نام ASLR مخفف Address Space Layout Randomization است . 

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

وقتی یک سورس کد compile میشود یا به شکلی یک فایل PE حاوی کد اجرایی تولید میشود ، کد اجرایی آن فایل فرض میکند که فایل PE در همان آدرسی که در فیلد ImageBase نوشته شده ، بارگذاری شده است در نتیجه آدرس متغییر ها و مقادیری که در حافظه میخواهد به آن ها دسترسی پیدا کند را بر مبنای ImageBase بدست می آورد . تکه کد زیر را فرض کنید :

int variable = 1000;
variable++ ;

فرض کنید آدرس نسبی متغییر variable از ابتدای فایل (RVA)در حافظه برابر 0x100 است . یعنی متغییر variable به فاصله 0x100 بایت بعد از شروع فایل PE در حافظه قرار دارد . حال اگر ImageBase برابر 0x1000 باشد ، کد اجرایی این مقدار را به 0x100 اضافه میکند تا آدرس واقعی و مطلق variable در حافظه بدست بیاید که میشود 0x1100 . تا اینجا همه چیز درست پیش میرود و طبق کدی که نوشته ایم مقدار variable در آدرس 0x1100 حافظه ذخیره شده است برنامه هر کاری بخواهد میتواند با مقدار آن بکند . 

حال فرض کنید به دلیل وجود ASLR ، فایل PE در آدرسی که ImageBase گفته بود بارگذاری نشود و مثلا در آدرس 0x2000 بارگذاری شود . اینجاست که مشکل پیش می آید . کد اجرایی فرض میکند آدرس متغییر variable در حافظه برابر 0x1000 + 0x100 = 0x1100 است اما در واقع به دلیل اینکه فایل PE در آدرس 0x2000 بارگذاری شده ، آدرس جدید variable برابر با 0x2000 + 0x100 = 0x2100 میشود نه 0x1100 ! 

پس کد اجرایی اینجا دچار اشتباه میشود و به درستی حافظه را نمیشناسد . 

برای حل این مشکل ، کاری که loader ویندوز انجام میدهد این است که ابتدا اختلاف ImageBase خود فایل PE و آدرس فعلی که فایل PE در آن بارگذاری شده را حساب میکند . اسم آن را delta میگذاریم :

ImageBase = 0x1000
ActualBase = 0x2000
delta = ActualBase - ImageBase = 0x1000

حال این مقدار delta را به آدرس هایی که کد اجرایی با آن ها کار میکند اضافه میکند . برای مثال اگر کد اجرایی از آدرس 0x1100 برای دسترسی به variable استفاده میکند ، loader مقدار delta که 0x1000 است را به این آدرس در کد اجرایی اضافه میکند و کد اجرایی تغییر یافته از این به بعد از آدرس 0x2100 که آدرس صحیح variable است استفاده میکند !

به این کار یعنی اصلاح کد اجرایی و تغییر آدرس ها قبل از اجرای کد توسط loader ویندوز Relocate کردن یا Relocation میگوییم . عمل Relocation تنها زمانی نیاز است انجام شود که فایل PE  به هر دلیلی در آدرس پیشفرض ImageBase بارگذاری نشود .

بخش reloc.

بخش reloc. در فایل PE مخفف Relocations حاوی اطلاعات مربوط به Relocation ها است . loader ویندوز باید دقیقا بداند کدام قسمت کد اجرایی فایل نیاز به اصلاح دارد . باید بداند کدام آدرس ها را باید تغییر دهد و این تغییر دادن چگونه باید باشد . همه ی این اطلاعات در بخش reloc. فایل مشخص شده است .

به طور کلی بخش reloc. تشکیل شده از تعدادی بلوک است . هر بلوک ، شامل داده های  مربوط به Relocate کردن ۴ کیلوبایت از حافظه فایل است و آدرس شروع هر بلوک در حافظه باید مضرب صحیحی از ۴ باشد (بلوک باید در مرز های ۳۲ بیتی شروع شود)  . هر بلوک با ساختار زیر شروع میشود :

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
} IMAGE_BASE_RELOCATION;

VirtualAddress : حاوی RVA شروع بخش ۴ کیلوبایتی است که این بلوک قرار است اطلاعات relocation آن را ذخیره کند .

SizeOfBlock : اندازه کل بلوک فعلی در واحد بایت شامل ساختار فعلی (VirtualAddress و SizeOfBlock) و داده هایی که در ادامه ، تحت بلوک فعلی می آید . 

در هر بلوک ، در ادامه ی ساختار بالا به تعداد دلخواهی مدخل های Type / Offset می آید . هر مدخل Type / Offset یک عدد ۲ بایتی است و وظیفه ی Relocate کردن یک آدرس از کد ، در محدوده ۴ کیلوبایتی را دارد .

۴ بیت پر ارزش این عدد Type نام دارد که مشخص کننده نوع Relocation است . باقی بیت های عدد  Offset نام دارد که فاصله آن نقطه از کد است که باید Relocation در آن انجام شود . این فاصله نسبت به ابتدای محدوده ۴ کیلوبایتی است که بلوک فعلی مربوط به relocate کردن آن است . آدرس این محدوده ۴ کیلوبایتی در عضو VirtualAddress ساختار بالا ذخیره شده بود بنابراین مقدار VirtualAddress ساختار بالا به اضافه مقدار Offset میشود تا RVA نقطه ای که نیاز است در آن relocation انجام شود مشخص شود.  

انواع مختلف Relocation وجود دارد که فیلد Type که در بالا معرفی شد وظیفه ی مشخص کردن آن را داشت . در مرجع رسمی Microsoft این انواع به طور کامل لیست شده اند اما اگر بخواهیم نمونه هایی از آن هارا بگوییم دو نمونه پرکاربرد آن یکی IMAGE_REL_BASED_HIGHLOW است و یکی IMAGE_REL_BASED_DIR64 .

اولی مشخص میکند نقطه ای که آدرس آن توسط Offset مشخص شده ، یک آدرس ۳۲ بیتی است که باید delta به آن اضافه شود . 

دومی مشخص میکند نقطه مورد نظر یک آدرس ۶۴ بیتی است که باید مقدار delta به آن اضافه شود . 


Notice: Undefined offset: 0 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 246

Notice: Undefined offset: 1 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 247

Notice: Undefined offset: 2 in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-content/plugins/wp-parsidate/includes/fixes-permalinks.php on line 248

منابع

منبع رسمی

https://0xrick.github.io/win-internals/pe7/

این آموزش متعلق به بخش مهندسی معکوس است

برای مشاهده تمام آموزش های مهندسی معکوس وبسایت مسترپایتون به بخش مهندسی معکوس مراجعه کنید

پست های مرتبط

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

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

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

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

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

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

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

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

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

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

نظرات

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

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


Notice: Function WP_Scripts::add was called incorrectly. اسکریپت با شناسهٔ «better-payment» با وابستگی‌هایی در صف قرار گرفته است که ثبت نشده‌اند: better-payment-payir. Please see Debugging in WordPress for more information. (این پیام در نگارش 6.9.1 افزوده شده است.) in /home/mrpython/domains/mrpythonblog.ir/public_html/wp-includes/functions.php on line 6131