سؤال

لمعرفة مناطق خريطة الذاكرة التي يحتوي عليها برنامج تشغيل ، أكتب برنامج C بسيطًا لقراءة البيانات من/proc/self/maps:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    char buf[1024];
    int fd;
    ssize_t n;

    fd = open("/proc/self/maps", O_RDONLY);
    if (fd < 0) {
        perror("");
    }
    while ((n = read(fd, buf, 1000)) > 0) {
        buf[n] = 0;
        printf("%s", buf);
    }
    close(fd);

    return 0;
}

يبدو أن إخراج البرنامج مثل هذا (المسمى):

1. 08048000-08049000 r-xp 00000000 08:01 2323014    /tmp/a.out
2. 08049000-0804a000 rw-p 00000000 08:01 2323014    /tmp/a.out
3. b7f69000-b7f6a000 rw-p b7f69000 00:00 0
4. b7f6a000-b80c6000 r-xp 00000000 08:01 1826975    /lib/tls/i686/cmov/libc-2.9.so
5. b80c6000-b80c7000 ---p 0015c000 08:01 1826975    /lib/tls/i686/cmov/libc-2.9.so
6. b80c7000-b80c9000 r--p 0015c000 08:01 1826975    /lib/tls/i686/cmov/libc-2.9.so
7. b80c9000-b80ca000 rw-p 0015e000 08:01 1826975    /lib/tls/i686/cmov/libc-2.9.so
8. b80ca000-b80cd000 rw-p b80ca000 00:00 0
9. b80dd000-b80df000 rw-p b80dd000 00:00 0
10.b80df000-b80e0000 r-xp b80df000 00:00 0          [vdso]
11.b80e0000-b80fc000 r-xp 00000000 08:01 1826830    /lib/ld-2.9.so
12.b80fc000-b80fd000 r--p 0001b000 08:01 1826830    /lib/ld-2.9.so
13.b80fd000-b80fe000 rw-p 0001c000 08:01 1826830    /lib/ld-2.9.so
14.bfee9000-bfefe000 rw-p bffeb000 00:00 0          [stack]

كما يمكننا أن نستنتج من بت التنفيذ والبت القابلة للكتابة ، يرتبط أول سطرين بالرمز وقطاعات البيانات في البرنامج على التوالي.

لكن ما يربكني هو أن Libc.so ، هناك للمناطق التي يتم تعيينها من Libc.so. واحد منهم حتى لديه القليل فقط ، لا يمكن كتابته أو قراءةه أو تنفيذه. وشيء آخر مثير للاهتمام هو أن LD.SO لديها ثلاثة قطاعات فقط. مقارنة بقطاعات Libc.so ، فإن تلك التي لديها جزء خاص فقط مفقود.

لذلك أود أن أعرف ما هي القطاعات الأربعة في الواقع؟ أنا أستخدم Ubuntu SMP مع Kernel 2.6.28 و GCC 3.4.6 و BinuTils 2.19.

هل كانت مفيدة؟

المحلول

ال r-xp, r--p و rw-p التعيينات هي ببساطة مناطق تحتاج إلى أذونات مختلفة.

الغموض ---p التعيين هو نتيجة لإزاحة الذاكرة الافتراضية للأقسام الموصوفة في ملف ELF لا يتطابق بالضرورة مع الإزاحة المادية داخل الملف (قد يكون هناك حشوة لأسباب محاذاة).

أي ملف قزم نفسه قد يبدو هكذا:

| .... sections .... | .... more sections .... |

... لكن صف تخطيط الذاكرة الذي يشبه هذا:

| .... sections .... |     gap     | .... more sections .... |

(يمكنك رؤية هذا باستخدام objdump -h أو readelf -e.)

لذلك ، المبدأ العام هو ذلك ld.so يحتاج إلى تخصيص ما يكفي من الذاكرة لكل شيء:

|                                                            |

... ثم قم بعمل رسم خرائط واحد للجزء الأول:

| .... sections .... |                                       |

... ثم قم بعمل رسم خرائط ثانية للحصول على الجزء الثاني في المكان الصحيح:

| .... sections .... |             | .... more sections .... |

ثم يحمي "الفتحة" التي تبقى في مساحة العنوان الظاهري. هذا هو تعيين الغموض الذي تراه:

| .... sections .... |XXXXXXXXXXXXX| .... more sections .... |

أعتقد أن الحفرة محمية - بدلاً من التحرير لإعادة الاستخدام - من أجل الحفاظ على الأمور بسيطة: فهي تضمن أن كل مكتبة لديها نطاق عنوان افتراضي واحد فقط ، والذي لا يوجد فيه أي شخص آخر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top