الحماية للأبد -Security 4 Ever

الحماية للأبد -Security 4 Ever (https://www.sec4ever.com/home/index.php)
-   أساسيات لغة الأسمبلي (https://www.sec4ever.com/home/forumdisplay.php?f=8)
-   -   إدارة الذاكرة (https://www.sec4ever.com/home/showthread.php?t=19576)

zero-cool 25-06-2019 12:58 AM

إدارة الذاكرة
 
السلام عليكم ورحمة الله وبركاته

إن شاء الله تكونوا في تمام الصحة والعافية إخواني





اليوم ، سأحاول جمع كل ما يمكن أن أفهمه حول إدارة الذاكرة أثناء تنفيذ البرنامج.
تتم كتابة هذه المقالة لفهم استغلال بعض عيوب التطبيق ،
مثل buffer overflow أو heap overflow أو format string

تحتاج ال process التي يتم تشغيلها على جهاز ما إلى ذاكرة ،
كما أن كمية الذاكرة محدودة في جهاز الكمبيوتر.
لذلك يجب أن تبحث ال process عن الذاكرة المتاحة لتكون قادرة على العمل.
ومع ذلك ، فإن ال process تتحول الآن إلى أنظمة تشغيل متعددة المهام.
تشتغل العديد من ال processes في نفس الوقت.
ماذا سيحدث إذا أرادت اثنين processes الوصول ، في نفس الوقت ، إلى نفس المنطقة من الذاكرة؟
والأهم من ذلك ، إذا كانت هناك process تحجذ إحدى مناطق الذاكرة ،
ثم process أخرى تحل محل منطقة الذاكرة نفسها ببياناتها الخاصة ، فستفكر ال process A ، في استرجاع بياناتها ، لكنها ستعثر بالفعل على البيانات من B.
سيكون من الضروري أن تتواصل ال processes باستمرار مع بعضها البعض لمعرفة من يفعل ماذا وأين ومتى.
سيكون مضيعة حقيقية للوقت وتعقيد كبير لهذه المشكلة.

هنا يأتي دور الذاكرة الإفتراضية (virtual memory)
لن تسحب ال processes مباشرة إلى الذاكرة الفيزيائية (physical memory)
يتم وضعها في صناديق ، وتخصص لهم مجموعة من الذاكرة الإفتراضية (4 جيجابايت للأجهزة ذات 32 بت) ،
مما يجعلهم يعتقدون أنهم الوحيدون الذين يعملون على الجهاز.
عندها تتدخل ال MMU (وحدة إدارة الذاكرة ، قطعة من الأجهزة مدمجة في الوقت الحاضر في المعالج) ،
وتعمل على الربط بين النطاقات المختلفة للذاكرة الافتراضية والذاكرة الحقيقية.

ال process لم تعد تقلق بشأن ال implementation تبع الذاكرة.

تتم معالجة جميع ال processes ذات المستوى المنخفض بواسطة ال MMU.
إنها نوع من طبقة التجريد التي تبسط حياة ال process.

كل process لها جدول الصفحات الخاص بها.
ومع ذلك ، إذا تم تمكين العنونة الافتراضية ،
فإنه ينطبق على جميع البرامج التي تعمل على الجهاز ، بما في ذلك النواة.
وبالتالي ، يجب حجز جزء من المساحة الافتراضية لكل برنامج للنواة !

تجزئة الذاكرة

هنا سنرى كيف هي ذاكرة البرنامج بعد عملية الكومبايل عندما يتم تحميله في الذاكرة لإنشاء process
نعثر على الأقسام الثلاثة التالية (من بين الأقسام الأخرى ، لكنها المهمة أكثر ):

text.
data.
bss.

ومناطق الذاكرة التالية:

stack
heap

قسم ال (.text) هو القسم الذي يحتوي على كود البرنامج ،
وبشكل أكثر دقة التعليمات في لغة الآلة.
إفتراضيا هذا الجزء له صلاحية قرائة فقط أي Read Only أو RO
يصلح فقط لتخزين الكود وليس المتغيرات.
يمكن أن تؤدي أخطاء البرمجة إلى هذا الخطأ الشهير "Segmentation Fault"
والتي يمكن أن تشير إلى أن المستخدم حاول كتابة غير مصرح بها في منطقة الذاكرة المحمية ضد الكتابة.
بسبب ثباتها ، إنها مساحة ذاكرة ذات حجم ثابت.
سيبدأ البرنامج في بداية هذا الجزء ، ثم يقرأ التعليمات واحدة تلو الأخرى.




يخزن قسم bss المتغيرات العامة والثابتة للبرنامج.
إذا تمت تهيئة هذه البيانات ، يتم حفظها في قسم data.
بينما الآخرون في قسم bss.
وهي أيضا مناطق ذاكرة ذات حجم ثابت.
على الرغم من القدرة على الكتابة ، لن تتغير المتغيرات النهائية والثابتة أثناء تنفيذ البرنامج .

يمكننا أن نأخذ مثالا بال C. البرنامج التالي فارغ. دعونا ننظر إلى حجم أقسامه المختلفة.

كود PHP:

#include <stdio.h>
 
int main(void) {
    return 
0;




كود PHP:

root@kali:~# gcc code.c -o code
root@kali:~# size code
   
text       data        bss        dec        hex    filename
   1368        292          4       1664        680    code 

الآن ، دعونا نضيف متغيرا عام غير مهيأ ونشوف أحجام الأقسام المختلفة مرة أخرى:

كود PHP:

#include <stdio.h>
 
int global;
 
int main(void) {
    return 
0;


كود PHP:

root@kali:~# gcc code.c -o code
root@kali:~# size code
   
text       data        bss        dec        hex    filename
   1368        292          8       1668        684    code 

نلاحظ أن قسم bss قد زاد بمقدار 4 بايت لتخزين المتغير الثابت غير المهيأ.
إذا قمنا بنفس الطريقة بإضافة متغير ثابت داخل الوظيفة ال main ()

كود PHP:

#include <stdio.h>
 
int global;
 
int main(void) {
    static 
int var;
    return 
0

كود PHP:

root@kali:~# gcc code.c -o code
root@kali:~# size code
   
text       data        bss        dec        hex    filename
   1368        292         12       1672        688    code 

مرة أخرى ، لاحظنا أن bss قد زاد بمقدار 4 بايت لتخزين هذا المتغير.

إذا قمنا لآن بتهيئة المتغير var

كود PHP:

#include <stdio.h>
 
int global;
 
int main(void) {
    static 
int var = 5;
    return 
0;


كود PHP:

root@kali:~# gcc code.c -o code
root@kali:~# size code
   
text       data        bss        dec        hex    filename
   1368        296          8       1672        688    code 

هذه المرة ، لم يعد المتغير مخزّنا في قسم bss ، ولكن في قسم data،
حيث نلاحظ أنه انتقل من 292 إلى 296 بينما انخفض قسم bss بمقدار 4 بايت

أخيرا ، إذا قمنا أيضا بتهيئة المتغير العام

كود PHP:

#include <stdio.h>
 
int global = 100;
 
int main(void) {
    static 
int var = 5;
    return 
0;


كود PHP:

root@kali:~# gcc code.c -o code
root@kali:~# size code
   
text       data        bss        dec        hex    filename
   1368        300          4       1672        688    code 

يتم تخزين كلا المتغيرين في قسم data. ، وليس في قسم bss.

ال (heap) ، يمكن التحكم فيها بواسطة المبرمج.
هذه هي المنطقة التي تتم فيها كتابة مناطق الذاكرة المخصصة ديناميكيا (malloc () أو calloc ())
مثل المكدس ، لا تحتوي مساحة الذاكرة هذه على حجم ثابت.
تزيد وتنقص وفقًا لمتطلبات المبرمج ، الذي يمكنه حجز أو حذف الكتل عبر خوارزميات التخصيص أو الإصدار للاستخدام في المستقبل.
كلما زاد حجم ال heap ، تزداد عناوين الذاكرة ، وتقترب عناوين الذاكرة الخاصة بالمكدس.
حجم المتغيرات في ال heap غير محدود (باستثناء الحد الفعلي للذاكرة) ، على عكس المكدس.
بالإضافة إلى ذلك ، يمكن الوصول إلى المتغيرات المخزنة في ال heap في البرنامج عبر ال pointers.
ومع ذلك ، فإن الوصول إلى المتغيرات المخزنة في ال heap يتم فقط باستخدام pointers ،
فإنه يؤدي إلى إبطاء عمليات الوصول هذه قليلا ، على عكس الوصول في المكدس .

المكدس يحتوي أيضا على حجم متغير ، ولكن كلما كان الحجم أكبر ، كلما انخفضت عناوين الذاكرة ، مع الاقتراب من الجزء العلوي من ال heap
هذا هو المكان الذي نجد فيه المتغيرات المحلية للوظائف بالإضافة إلى إطار مكدس (stack frame) هذه الوظائف.
ال stack frame تبع وظيفة هو منطقة في الذاكرة ، في المكدس ،
حيث يتم تخزين جميع المعلومات اللازمة لاستدعاء هذه الوظيفة بحيث يحتوي أيضا على المتغيرات المحلية تبع الوظيفة.

آمل أن يكون لديك فكرة أوضح عن تجزئة الذاكرة عند تشغيل البرنامج.



بالتوفيق لكم


الساعة الآن 10:05 AM

Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.