محمد حسن پزشکیان
عاشق امنیت و نفوذ ، رد تیم و دوستدار بزن بکش :)

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران

دراین مقاله میخوایم به صورت خیلی مختصر و گذرا زبان اسمبلی و ریجستر هارو بررسی کنیم


زمانی که یک برنامه با زبان کامپایلی نوشته میشه و توسط کامپایلر به یه فایل اجرایی تبدیل میشه ، در زبان ماشین یا 0  1 نمایش داده میشه و از این رو کار کردن با این زبان زیاد جالب نیست ، برای تسهیل این موضوع دیتا در مبنای هگز نمایش داده شد ، ولی دیتایی که باز ما سر در نمیاریم ، پس میریم به سطح بالاتر و کد رو به زبان اسمبلی بررسی میکنیم که متوجه بشیم برنامه چی کار میکنه (به هر خط از زبان اسمبلی میگیم دستورالعمل)


(توجه کنید که مبنا 2 و 16 Data Representation هست ولی زبان اسمبلی یک زبان برنامه نویسیه)

معرفی اجزاء حافظه

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

برای اینکه بتونید با اسمبلی کار کنیم باید اول اجزا حافظه رو بشناسیم :

1- در این قسمت کد برنامه قرار میگیره و این قسمت Readonly هست بخاطر اینکه برنامه نباید وسط کار کدشو عوض کنه

2- وقتی دیتا میخواد قرار بگیره باید به دو دسته initialized و uninitialized طبقه بندی میشه ، دیتا های دسته اول در قسمت data قرار میگیرن که شامل مواردی مثل Static variable و Global Variable میشوند

3- دیتاهای uninitialized  در bss قرار میگیرن (نیازش نداریم)

4- هیپ :ک زمانی که برنامه اجرا میشه و فضای بیشتری میخواد ، دیتا در هیپ ریخته میشه ، و هر وقت توابعی مثل calloc یا malloc صدا زده بشن

ریجستر ها

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

قبل اینکه بریم سراغ استک من ریجستر هارو معرفی کنم :

ریجستر ها دو نوع هستن (32 و 64 بیتی) من یه اشاره ای به 64 میکنم ولی 32 رو بررسی میکنیم (فرق زیادی نداره)

ما در کل 6 عدد ریجستر GPR یا General Purpose Registers داریم و این ریجستر ها دیتاهای عمومی رو ذخیره میکنن همونطور که در عکس بالا مشاهده میکنید 6 تا ریجستر در دسته بندی General قرار دارند

  • EAX که وظیفه نگهداری مقادیر ریاضی یا منطقی رو داره
  •  EBX نگهداری مکان حافظه Base pointer
  • ECX مقادیر مربوط به حلقه
  • EDX مقادیر آدرس دهی I/O و اعمال تقسیم
  • ESI یک پوینتر برای مبدا کپی یک استرینگ
  • EDI یک پوینتر برای مقصد کپی یک استرینگ

سه تا ریجستر دیگه هم هستن که رزرو شدن برای موارد خاص :

  • ESP : یک پوینتر برای اشاره به بالا استک
  • EBP : یک پوینتر برای اشاره به ابتدا استک (برای استک هر تابع جدا)
  • EIP : یک پوینتر برای اشاره به آدرس دستورالعمل بعدی جهت اجرا


در معماری 64 بیت ما یه ریجستر داریم به نام RAX که مقداری 64 بیتی اختیار میکنه ، اگر بگیم EAX یعنی یه ریجستری 32 بیتی که نصف RAX میشه و در حافظه پایین تر (اول تر) قرار داره ، به همین ترتیب ریجستر AX در 16 بیت اولی یا پایینی و ..

ریسجتر ها سریع ترین بخش حافظه هستن که در سیپیو برای هر هسته جدا درنظر گرفته میشن و مقادیری رو در خودشون ذخیره میکنن (تا 8 بایت یا کمتر در معماری 32 بیتی) و آدرسی دارن برای دسترسی به اون مقادیر

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

5- استک : که این بخش قبلا در مقاله ای جدا بررسی شده ولی به صورت خلاصه : استک مثل دسته بشقابه که دیتا جدید باید روش قرار بگیره و هر دیتایی که بخواد پاک شه باید از روش برداشته بشه ، به گذاشتن میگن push و به برداشتن میگن pop

در استک هر خونه (هر بشقاق) آدرس خودشونو دارن ، خونه هایی که در بالای استک هستن آدرس پایین تری دارن

یا به بیان دیگه استک به سمت آدرس حافظه پایین تر رشد میکنه، به کل این بشقاب ها یا خونه ها میگن استک فریم

بررسی دقیق تر استک و مفاهیم Epilogue و Prologue

وقتی یه فانکشن صدا زده میشه یا اجرا میشه ، باید استک فریم اون تابع ساخته بشه :

در وهله اول برنامه از تابع main شروع میشه و مقادیر مین میرن داخل استک ، و چون کار ما با تابع main فعلا تموم شده پس یه آدرس بازگشت از main ذخیره میکنیم (4 بایتی) در حافظه برای وقتی که کار ما با func تموم شد و خواستیم برگردیم به main ، حالا کنترل از دست main خارج میشه و به func داده میشه ، استک فریم func میخواد در استک پیاده سازی بشه پس ebp میاد و به بالای ادرس برگشتی main اشاره میکنه (هروقت ebp به جایی اشاره کرد یعنی استک فریم توابع میخواد اونجا قرار بگیره و یه تابع داره شروع به گذاشتن دیتا خودش میکنه ، (در اینجا ما فرایند Prologue رو داریم یعنی استک برای تابع func اماده میشه و فضاش جدا میشه و استک فریمشو میسازه))


حالا باید توجه کنیم که ebp و esp جفتی دارن به یکجا اشاره میکنن ، مقادیر 10  و آدرس باز گشتی هر کدوم دوتا 4 بایتی هستن که در بالای ebp قرار دارن ، به سمت ادرس حافظه بیشتر ، اگر بخوایم به ret دسترسی داشته باشیم باید 4 تا از ebp بریم بالاتر یعنی ebp+4 و اگر به 10 بخوایم دسترسی داشته باشیم ، یعنی به مقدار ادرس main باید 8 بایت بریم جلو یعنی ebp+8

حالا آدرس esp آپدیت میشه میره بالا به اندازه متغییر هایی که توی func هست و جا باز میشه براشون

اولین متغییر func میره تو استک یعنی 0 و این 0 ، 4 بایت پایین تر از ebp قرار داره پس اگر ما بخوایم اشاره کنیم بهش باید بگیم ebp-4 یعنی هرجا که ebp هست -4 تا پایین ترش

بعدش x باید بیاد و x چی بود؟ 10 ، حالا 10 باید بیاد تو اینجا ولی 10 نمیتونه کپی یا جابجا بشه 

پس اینجا کاربرد ریجستر معلوم میشه، باید 10 اول ریخته بشه تو یه ریجستر بعد ریخته بشه اونجا

حالا 10 فاصلش تا ebp چقدره؟ -8 بایت ، پس ebp -8 (اگر بخواید در زبان هگزادسیمال بنویسید یه 0x قبل عدد باید بزارید که میشه ebp-0x8)

حالا ک func تموم میشه میخوایم دیتاهارو از حافظه pop کنیم ، در اینجا Epilogue صورت میگیره ، دیتا شروع میکنه به پاک شدن و esp بعد هر pop جاشو اپدیت میکنه به خونه ای با حافظه (بالاترررررر) و جایی میرسه که esp میرسه به ادرس برگشتی و esp و ebp جفتی به یه جا اشاره میکنن و وقتی ebp حذف میشه و فقط esp میمونه (استم فریم func پاک شده) اینجا کار Epilogue تموم شده و کنترل به تابع main برمیگرده

زبان اسمبلی

جهت درک بیشتر تفاوت بین معماری، اسمبلر و سینتکس این مقاله رو بخونید

ما در اینجا میریم سراغ دستورالعمل (Instruction) با سینتکس اینتل :

هر دستورالعمل دوتا بخش داره ، (بخش عملیاتی یا operation و یک یا دو آرگومان)

operation arg1

operation arg1,arg2

در سینتکس اسمبلی دیتا از راست به چپ منتقل میشه ، یعنی اگر ما دوتا ارگومان داشته باشیم ارگومان راستی میشه مبدا و ارگومان چپی میشه مقصد ، در کد بالا arg2 مبدا و arg1 مقصد هست

بریم سراغ یه سری از دستورات مهم :

بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

mov : این دستور برای انتقال دیتا به ریجستر هست

سینتکس اینطوریه که مقداری رو از سمت راست میریزه تو چپ ، مقدار 15 در خونه ebp-12 هست و در خانه 15 هست ، حالا دیتاش میخواد منتقل بشه به eax ، اگر مستقیم بزنیم بدون [] آدرس خونه 15 منتقل میشه نه خود عدد 15 ، ولی اگر [] بزنیم خود عدد 15 رو منتقل میکنه


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

add : این دستور یک دستور برای اضافه کردن یک مقدار به یک ریجستر هست (خود مقدار به یک دیجستر یا یک ریجستر به یک ریجستر)

برای مثال در گیف بالا ما اول 5 رو ریختیم تو یه ریجستر ، 6 رو ریختیم تو یکی دیگ و با add 6 رو ریختیم داخل ریجستری که 5 رو داشت و در نهایت 11 بدست امد


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

sub : مقدار ارگومان 2 رو از ارگومان 1 کم میکنه ، 15 رو میریزم یجا 3 رو میزیم یجا ، حالا 3 رو از 15 کم میکنیم و نتیجرو میریزیم تو جای 15 که میشه 12


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

push : رو توی گیف اول توضیح دادم : اول esp میره بالا (به سمت ادرس حافظه پایین تر) و جاخالی میکنه و دیتا ریخته میشه تو اونجا 


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

pop : این میاد دقیقا برعکس push یه دیتایی رو پاک میکنه ، اول اون دیتا رو میریزه تو یه ریجستر بعد esp آپدیت میشه و میاد پایین


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

lea : اینم خیلی ساده میاد و آدرس یه خونه از حافظرو ذخیره میکنه توی یه ریجستر


بررسی مختصر مفاهیم حافظه سیستم و اسمبلی

cmp : میاد و مثل sub مقایسه میکنه ولی نتیجشو به صورت flag داخل سیپیو نشون میده ، مثلا اگر سه رو از یک کم کنیم که میشه 2 و مثبته پس نتیجه بزرگتر از صفره یا 0> ولی اگر 1 رو از سه کم کنیم میشه -2 و فلگ میشه 0< یا کوچیکتر از صفر ولی اگر 3-3 باشه فلگ میشه 0 

یه سری دستورات دیگم بود که نیازمند این بود که درک کامل تری از استک و اسمبلی داشته باشید برای مثال jump که در صورتی که نیاز بشه اجرا میشه و میپره به سایر دستور العمل ها یا call که برای صدا زدن تابع استفاده میشه

و دستور اخر هم ret/leave هست که همون فرایند اپیلاگ رو اجرا میکنه


پی نوشت 1 :ک این مطالب بعضا جنبه مرور داره و اگر زیاد و کامل متوجه نمیشید یعنی باید کامل و دقیق و جزئی هرکدوم رو یادبگیرید و این مطلب مناسب شما نیست

پی نوشت 2 : تک تک این انیمیشنارو خودم ساختم با صرف چندین ساعت برای هرکدوم ، و کپی بدون ذکر منبع مجاز نیست

اگر سوالی چیزی بود در خدمتم :)



محمد حسن پزشکیان
محمد حسن پزشکیان

عاشق امنیت و نفوذ ، رد تیم و دوستدار بزن بکش :)

کارشناس تست نفوذ سنجی ، علاقه مند به امنیت تهاجمی و رد تیمینگ | عضو انجمن بین المللی ورزش های رزمی کشور آلمان و دارای احکام بین المللی و داخلی کمربند مشکی در سبک های کیوکوشین ، هاپکیدو ، کیک بوکسینگ و چند تام قهرمانی کشوری

27 دی 1400 این مطلب را ارسال کرده

نظرات