ماخ-أو

Mach-O ( كائن Mach ) هو تنسيق ملفات للملفات التنفيذية ، ورمز الكائن ، والمكتبات المشتركة ، والتعليمات البرمجية المحملة ديناميكيًا، وملفات تفريغ الذاكرة الأساسية . وقد تم تطويره ليحل محل تنسيق a.out .

يستخدم نظام التشغيل Mach-O في بعض الأنظمة المبنية على نواة Mach . ومن أمثلة هذه الأنظمة NeXTSTEP و macOS و iOS التي تستخدم هذا التنسيق للملفات التنفيذية الأصلية والمكتبات والتعليمات البرمجية الكائنية.

تخطيط الملف

يتكون كل ملف Mach-O من رأس Mach-O واحد، يليه سلسلة من أوامر التحميل، ثم مقطع واحد أو أكثر، يحتوي كل منها على ما بين 0 و255 قسمًا. يستخدم Mach-O تنسيق إعادة التوجيه REL للتعامل مع مراجع الرموز. عند البحث عن الرموز، يستخدم Mach-O مساحة أسماء ثنائية المستوى تُشفّر كل رمز في زوج "اسم الكائن/اسم الرمز"، والذي يتم البحث عنه خطيًا، أولًا باسم الكائن ثم باسم الرمز. [ 2 ]

استُخدمت البنية الأساسية - وهي قائمة من "أوامر التحميل" ذات الطول المتغير التي تشير إلى صفحات البيانات في أماكن أخرى من الملف [ 3 ] - أيضًا في تنسيق الملف التنفيذي لبرنامج Accent . وقد استند تنسيق ملف Accent بدوره إلى فكرة من لغة Spice Lisp .

تُكتب جميع القيم متعددة البايتات في جميع هياكل البيانات بترتيب البايتات الخاص بالجهاز المضيف الذي تم إنتاج الكود من أجله. [ 4 ]

رأس ملف Mach-O [ 5 ]
إزاحةبايتوصف
04الرقم السحري
44نوع وحدة المعالجة المركزية
84نوع وحدة المعالجة المركزية
124نوع الملف
164عدد أوامر التحميل
204حجم أوامر التحميل
244الأعلام
284محجوز (64 بت فقط)

الرقم السحري للتعليمات البرمجية ذات 32 بت هو 0xfeedface بينما الرقم السحري للبنى ذات 64 بت هو 0xfeedfacf .

القيمة المحجوزة موجودة فقط في ملفات Mach-O ذات 64 بت. وهي محجوزة للاستخدام المستقبلي أو لتوسيع رأس الملف ذي 64 بت.

يشير نوع وحدة المعالجة المركزية إلى بنية مجموعة التعليمات المستخدمة في البرنامج. إذا كان الملف مخصصًا لإصدار 64 بت من بنية مجموعة التعليمات، فإن قيمة نوع وحدة المعالجة المركزية تكون مُفعّلة عند البت 0x01000000 . أما إذا كان الملف مخصصًا لإصدار 64 بت من بنية مجموعة التعليمات ولكن بمؤشرات 32 بت، فإن قيمة نوع وحدة المعالجة المركزية تكون مُفعّلة عند البت 0x02000000 .

قيم نوع وحدة المعالجة المركزية هي كما يلي: [ 6 ] [ 7 ]

نوع وحدة المعالجة المركزية
قيمةنوع وحدة المعالجة المركزية
0x00000001فاكس
0x00000002مرح
0x00000004NS32032
0x00000005NS32332
0x00000006MC680x0
0x00000007x86
0x00000008نظام MIPS
0x00000009NS32352
0x0000000BHP-PA
0x0000000Cذراع
0x0000000DMC88000
0x0000000Eسبارك
0x0000000Fi860 (big-endian)
0x00000010i860 (little-endian) أو ربما DEC Alpha [ 8 ]
0x00000011RS/6000
0x00000012باور بي سي / إم سي 98000
0x00000018RISC-V

لكل نوع من أنواع المعالجات المركزية مجموعة من قيم النوع الفرعي، تشير إلى طراز معين من هذا النوع من المعالجات المركزية الذي صُمم الكود من أجله. قد تدعم الطرازات الأحدث من نوع معين من المعالجات المركزية تعليمات أو ميزات أخرى غير مدعومة في الطرازات الأقدم، لذا قد يحتوي الكود المُجمَّع أو المكتوب لطراز أحدث على تعليمات غير صالحة في طراز أقدم، مما يتسبب في حدوث خطأ أو فشل في العمل بشكل صحيح عند تشغيله على طراز أقدم. أما الكود المُصمم لطراز أقدم فسيعمل على الطرازات الأحدث دون مشاكل.

إذا كان نوع وحدة المعالجة المركزية ARM، فإن الأنواع الفرعية هي كما يلي: [ 6 ]

نوع وحدة المعالجة المركزية ARM
قيمةإصدار وحدة المعالجة المركزية
0x00000000جميع معالجات ARM
0x00000001مُحسَّن للعمل مع معالج ARM-A500 ARCH أو أحدث.
0x00000002مُحسَّن للعمل مع معالج ARM-A500 أو أحدث.
0x00000003مُحسَّن للعمل مع معالج ARM-A440 أو أحدث.
0x00000004مُحسَّن للعمل مع معالج ARM-M4 أو أحدث.
0x00000005مُحسَّن للعمل مع معالجات ARM-V4T أو أحدث.
0x00000006مُحسَّن للعمل مع معالجات ARM-V6 أو أحدث.
0x00000007مُحسَّن للعمل مع معالج ARM-V5TEJ أو أحدث.
0x00000008مُحسَّن للعمل مع معالجات ARM-XSCALE أو أحدث.
0x00000009مُحسَّن للعمل مع معالجات ARM-V7 أو أحدث.
0x0000000Aمُحسَّن للعمل مع معالج ARM-V7F (Cortex A9) أو أحدث.
0x0000000Bمُحسَّن للعمل مع معالج ARM-V7S (Swift) أو أحدث.
0x0000000Cمُحسَّن للعمل مع معالج ARM-V7K (Kirkwood40) أو أحدث.
0x0000000Dمُحسَّن للعمل مع معالجات ARM-V8 أو أحدث.
0x0000000Eمُحسَّن للعمل مع معالجات ARM-V6M أو أحدث.
0x0000000Fمُحسَّن للعمل مع معالجات ARM-V7M أو أحدث.
0x00000010مُحسَّن للعمل مع معالج ARM-V7EM أو أحدث.

إذا كان نوع وحدة المعالجة المركزية x86 فإن الأنواع الفرعية هي كما يلي: [ 6 ]

نوع وحدة المعالجة المركزية x86
قيمةإصدار وحدة المعالجة المركزية
0x00000003جميع معالجات x86.
0x00000004مُحسَّن لأجهزة 486 أو أحدث.
0x00000084مُحسَّن للعمل مع معالجات 486SX أو أحدث.
0x00000056مُحسَّن للمعالجات Pentium M5 أو أحدث.
0x00000067مُحسَّن للعمل مع معالجات سيليرون أو أحدث.
0x00000077مُحسَّن للهواتف المحمولة المزودة بمعالجات سيليرون.
0x00000008مُحسَّن للعمل مع معالجات بنتيوم 3 أو أحدث.
0x00000018مُحسَّن للعمل مع معالجات Pentium 3-M أو أحدث.
0x00000028مُحسَّن للعمل مع معالجات Pentium 3-XEON أو أحدث.
0x0000000Aمُحسَّن للمعالجات Pentium-4 أو أحدث.
0x0000000Bمُحسَّن للعمل مع معالجات إيتانيوم أو أحدث.
0x0000001Bمُحسَّن للعمل مع معالجات Itanium-2 أو أحدث.
0x0000000Cمُحسَّن للعمل مع معالجات XEON أو أحدث.
0x0000001Cمُحسَّن للعمل مع معالج XEON-MP أو أحدث.

يلي قيمة النوع الفرعي قيمة نوع الملف.

نوع الملف
قيمةوصف
0x00000001ملف كائن قابل للنقل.
0x00000002طلب ملف تنفيذي مُقسّم إلى صفحات.
0x00000003تم إصلاح ملف المكتبة المشتركة للجهاز الظاهري.
0x00000004ملف أساسي.
0x00000005ملف تنفيذي مُحمّل مسبقًا.
0x00000006ملف مكتبة مشتركة مرتبط ديناميكيًا.
0x00000007محرر الروابط الديناميكية.
0x00000008ملف حزمة مرتبط ديناميكيًا.
0x00000009ملف مكتبة مشترك للربط الثابت فقط، بدون محتويات أقسام.
0x0000000Aملف مصاحب يحتوي على أقسام تصحيح الأخطاء فقط.
0x0000000Bx86_64 kexts.
0x0000000Cملف يتكون من برامج Mach-O أخرى لتشغيلها في نفس مساحة المستخدم التي تشترك في ملف واحد مرتبط.

بعد قيمة نوع الملف، يكون عدد أوامر التحميل وإجمالي عدد البايتات التي تأتي بعد رأس Mach-O، ثم علامة 32 بت مع الإعدادات الممكنة التالية.

إعدادات العلم
العلم في وضعية الانعطاف الأيسرالعلم بالصيغة الثنائيةوصف
1<<00000_0000_0000_0000_0000_0000_0001لا يحتوي ملف الكائن على أي مراجع غير معرفة.
1<<10000_0000_0000_0000_0000_0000_0010ملف الكائن هو ناتج عن ربط تزايدي بملف أساسي ولا يمكن تعديله مرة أخرى.
1<<20000_0000_0000_0000_0000_0000_0100يُعد ملف الكائن مدخلاً للرابط الديناميكي ولا يمكن تعديله بشكل ثابت مرة أخرى.
1<<30000_0000_0000_0000_0000_0000_1000يتم ربط المراجع غير المعرفة لملف الكائن بواسطة الرابط الديناميكي عند تحميله.
1<<40000_0000_0000_0000_0000_0000_0001_0000يحتوي الملف على مراجع غير معرفة ديناميكية مرتبطة مسبقًا.
1<<50000_0000_0000_0000_0000_0010_0000يحتوي الملف على أجزاء للقراءة فقط وأجزاء للقراءة والكتابة مقسمة.
1<<60000_0000_0000_0000_0000_0100_0000يتم تشغيل روتين تهيئة المكتبة المشتركة بشكل كسول عن طريق التقاط أخطاء الذاكرة في أجزائها القابلة للكتابة (قديم).
1<<70000_0000_0000_0000_0000_1000_0000تستخدم الصورة روابط مساحة اسم ثنائية المستوى.
1<<80000_0000_0000_0000_0000_0001_0000_0000يجبر الملف التنفيذي جميع الصور على استخدام روابط مساحة الاسم المسطحة.
1<<90000_0000_0000_0000_0010_0000_0000تضمن هذه المظلة عدم وجود تعريفات متعددة للرموز في صورها الفرعية، لذا يمكن دائمًا استخدام تلميحات مساحة الاسم ذات المستويين.
1<<100000_0000_0000_0000_0100_0000_0000لا تقم بإخطار وكيل الربط المسبق بشأن هذا الملف التنفيذي.
1<<110000_0000_0000_0000_0000_1000_0000_0000الملف الثنائي غير مرتبط مسبقًا، ولكن يمكن إعادة ربطه مسبقًا. يُستخدم فقط عندما لا يتم تعيين MH_PREBOUND.
1<<120000_0000_0000_0000_0001_0000_0000_0000يشير هذا إلى أن هذا الملف الثنائي يرتبط بجميع وحدات مساحة الاسم ذات المستويين للمكتبات التابعة له.
1<<130000_0000_0000_0000_0010_0000_0000_0000من الآمن تقسيم الأقسام إلى أقسام فرعية باستخدام الرموز لإزالة التعليمات البرمجية غير المستخدمة.
1<<140000_0000_0000_0000_0100_0000_0000_0000تم توحيد الصيغة الثنائية من خلال عملية إلغاء الربط المسبق.
1<<150000_0000_0000_0000_1000_0000_0000_0000تحتوي الصورة المرتبطة الأخيرة على رموز ضعيفة خارجية.
1<<160000_0000_0000_0001_0000_0000_0000_0000تستخدم الصورة المرتبطة الأخيرة رموزًا ضعيفة.
1<<170000_0000_0000_0010_0000_0000_0000_0000عند ضبط هذه البتة، سيتم منح جميع المكدسات في المهمة امتياز تنفيذ المكدس.
1<<180000_0000_0000_0100_0000_0000_0000_0000عند ضبط هذه البتة، يعلن الملف الثنائي أنه آمن للاستخدام في العمليات ذات المعرف الفريد (uid) صفر.
1<<190000_0000_0000_1000_0000_0000_0000_0000عندما يتم ضبط هذه البتة، يعلن الملف الثنائي أنه آمن للاستخدام في العمليات عندما تكون قيمة UGID صحيحة.
1<<200000_0000_0001_0000_0000_0000_0000_0000عندما يتم تعيين هذا البت على مكتبة ديناميكية، فإن الرابط الثابت لا يحتاج إلى فحص المكتبات الديناميكية التابعة لمعرفة ما إذا كان يتم إعادة تصدير أي منها.
1<<210000_0000_0010_0000_0000_0000_0000_0000عند ضبط هذا البت، سيقوم نظام التشغيل بتحميل الملف التنفيذي الرئيسي في عنوان عشوائي.
1<<220000_0000_0100_0000_0000_0000_0000_0000للاستخدام فقط مع المكتبات الديناميكية. عند الربط مع مكتبة ديناميكية تم ضبط هذه البتة عليها، لن يقوم الرابط الثابت تلقائيًا بإنشاء أمر تحميل إلى المكتبة الديناميكية إذا لم تتم الإشارة إلى أي رموز من المكتبة الديناميكية.
1<<230000_0000_1000_0000_0000_0000_0000_0000يحتوي على قسم من النوع S_THREAD_LOCAL_VARIABLES.
1<<240000_0001_0000_0000_0000_0000_0000_0000عند ضبط هذا البت، سيقوم نظام التشغيل بتشغيل الملف التنفيذي الرئيسي مع كومة غير قابلة للتنفيذ حتى على الأنظمة الأساسية (مثل i386) التي لا تتطلب ذلك.
1<<250000_0010_0000_0000_0000_0000_0000_0000تم ربط الكود لاستخدامه في أحد التطبيقات.
1<<260000_0100_0000_0000_0000_0000_0000_0000لا تتضمن الرموز الخارجية المدرجة في جدول رموز nlist جميع الرموز المدرجة في معلومات dyld.
1<<270000_1000_0000_0000_0000_0000_0000_0000السماح لأوامر التحميل LC_MIN_VERSION_MACOS و LC_BUILD_VERSION مع منصات macOS و macCatalyst و iOSSimulator و tvOSSimulator و watchOSSimulator.
1<<311000_0000_0000_0000_0000_0000_0000يُستخدم هذا الخيار فقط مع مكتبات dylib. عند ضبط هذا الخيار، تصبح مكتبة dylib جزءًا من ذاكرة التخزين المؤقت المشتركة لـ dyld، بدلاً من أن تكون منفصلة في نظام الملفات.
7<<28الأرقام التي تحمل علامة "x" ليس لها استخدام، وهي محجوزة للاستخدام المستقبلي.

يمكن ضبط عدة أرقام ثنائية على واحد في العلامات لتحديد أي معلومات أو إعدادات تنطبق على النظام الثنائي.

الآن تُقرأ أوامر التحميل كما لو أن المرء قد وصل إلى نهاية رأس Mach-O.

ملفات ثنائية متعددة البنية

يمكن دمج ملفات Mach-O المتعددة في ملف ثنائي متعدد البنى . يسمح هذا لملف ثنائي واحد باحتواء تعليمات برمجية تدعم بنى مجموعات تعليمات متعددة، على سبيل المثال لأجيال وأنواع مختلفة من أجهزة Apple، بما في ذلك بنى معالجات مختلفة [ 9 ] مثل ARM64 و x86-64 . [ 10 ]

جميع الحقول في الترويسة العامة هي من نوع big-endian. [ 4 ]

يكون رأس الملف العام بالشكل التالي: [ 11 ]

رأس Mach-O العالمي
إزاحةبايتوصف
04الرقم السحري
44عدد الثنائيات

الرقم السحري في ملف ثنائي متعدد البنية هو 0xcafebabe بترتيب البايتات الكبير، لذا فإن أول أربعة بايتات من الرأس ستكون دائمًا 0xca 0xfe 0xba 0xbe ، بهذا الترتيب.

عدد الملفات الثنائية هو عدد الإدخالات التي تلي العنوان.

يتبع العنوان سلسلة من الإدخالات بالشكل التالي: [ 12 ]

إدخالات الملفات العامة لـ Mach-O
إزاحةبايتوصف
04نوع وحدة المعالجة المركزية
44نوع وحدة المعالجة المركزية
84إزاحة الملف
124مقاس
164محاذاة المقطع (قوة العدد 2)

يتبع تسلسل المدخلات تسلسل من صور Mach-O. يشير كل مدخل إلى صورة Mach-O.

يجب أن يكون نوع وحدة المعالجة المركزية ونوعها الفرعي لإدخال ما هو نفسه نوع وحدة المعالجة المركزية ونوعها الفرعي لصورة Mach-O التي يشير إليها الإدخال.

يمثل موضع الملف وحجمه موضع بداية صورة Mach-O في الملف، وحجم صورة Mach-O التي يشير إليها الإدخال.

يمثل محاذاة القسم اللوغاريتم الثنائي لمحاذاة البايتات في الملف المطلوب لصورة Mach-O التي يشير إليها الإدخال؛ على سبيل المثال، تعني القيمة 14 أن الصورة يجب أن تكون محاذية على حد 2^ 14 بايت، أي حد 16384 بايت. هذا ضروري للأدوات التي تُعدّل الملف الثنائي متعدد البنية، لكي تحافظ على محاذاة الصورة بشكل صحيح.

أوامر التحميل

تُقرأ أوامر التحميل مباشرة بعد رأس Mach-O.

يُحدد رأس Mach-O عدد أوامر التحميل الموجودة بعد رأس Mach-O وحجمها بالبايتات حتى نهاية أوامر التحميل. ويُستخدم حجم أوامر التحميل كفحص للتكرار.

عندما تتم قراءة أمر التحميل الأخير ولا يتطابق عدد البايتات لأوامر التحميل، أو إذا تجاوزنا عدد البايتات لأوامر التحميل قبل الوصول إلى أمر التحميل الأخير، فقد يكون الملف تالفًا.

كل أمر تحميل عبارة عن سلسلة من الإدخالات بالشكل التالي: [ 13 ]

أمر التحميل
إزاحةبايتوصف
04نوع الأمر
44حجم القيادة

يُحدد نوع أمر التحميل المعلمات المُستخدمة فيه. إذا بدأ أمر التحميل بتفعيل البت 0x80000000 ، فهذا يعني أن هذا الأمر ضروري لتحميل أو تشغيل الملف التنفيذي. يسمح هذا لمُحملات Mach-O القديمة بتجاوز الأوامر غير المفهومة لها والتي لا تُعد ضرورية لتحميل التطبيق.

أمر تحميل المقطع

تستخدم ملفات Mach-O الثنائية التي تستخدم نوع أمر التحميل 0x00000001 الإصدار 32 بت من أمر تحميل المقطع، [ 14 ] بينما يتم استخدام 0x00000019 لتحديد الإصدار 64 بت من أمر تحميل المقطع. [ 15 ]

يختلف أمر تحميل المقطع باختلاف حجم رأس Mach-O، سواء كان 32 بت أو 64 بت. ويعود ذلك إلى أن بنية المعالج 64 بت تستخدم عناوين 64 بت، بينما تستخدم بنية المعالج 32 بت عناوين 32 بت.

تُضاف جميع عناوين ذاكرة الوصول العشوائي الافتراضية إلى عنوان أساسي للحفاظ على تباعد التطبيقات. يحتوي كل قسم في أمر تحميل المقطع على إزاحة قائمة إعادة التوطين التي تحدد الإزاحات في القسم التي يجب تعديلها بناءً على العنوان الأساسي للتطبيق. لا داعي لإعادة التوطين إذا كان من الممكن وضع التطبيق في مواقع عناوين ذاكرة الوصول العشوائي المحددة له، مثل العنوان الأساسي صفر.

أمر التحميل (المقطع load32/64)
الإزاحة (32 بت)بايت (32 بت)الإزاحة (64 بت)بايت (64 بت)وصف
04040x00000001 (نوع الأمر 32 بت)

0x00000019 (نوع الأمر 64 بت)

4444حجم القيادة
816816اسم المقطع
244248عنوان
284328حجم العنوان
324408إزاحة الملف
364488الحجم (بايت من إزاحة الملف)
404564أقصى حماية للذاكرة الافتراضية
444604الحماية الأولية للذاكرة الافتراضية
484644عدد الأقسام
524684Flag32

لا يمكن أن يتجاوز اسم المقطع 16 حرفًا نصيًا بالبايت. الأحرف غير المستخدمة قيمتها 0x00 .

يحتوي أمر المقطع على عنوان كتابة القسم في مساحة العناوين الافتراضية بالإضافة إلى عنوان التطبيق الأساسي. ويُحدد حجم العنوان (عدد البايتات المراد كتابتها في موقع العنوان).

بعد معلومات العنوان، يتم تحديد موضع إزاحة الملف، ثم يتم تحديد موقع بيانات المقطع في ملف Mach-O الثنائي، وعدد البايتات المراد قراءتها من الملف.

عندما يكون حجم العنوان أكبر من عدد البايتات المراد قراءتها من الملف، يتم تعيين باقي البايتات في مساحة ذاكرة الوصول العشوائي إلى 0x00 .

يوجد جزء يُسمى `<input>` __PAGEZERO، وله إزاحة ملف صفرية وحجم صفري في الملف. وله عنوان ذاكرة افتراضية وحجم مُحددان. كما أن أذونات الوصول إليه مُعيّنة على الصفر، مما يعني أنه لا يمكن استخدامه إطلاقًا (أي وصول إلى هذا الجزء سيؤدي إلى خطأ في الصفحة). الغرض من هذا الجزء هو اكتشاف مؤشرات NULL غير الصالحة (التي قيمتها صفر). في بيئات 32 بت، يكون الحجم الافتراضي لهذا الجزء 4  كيلوبايت، بينما في بيئات 64 بت يكون 4  جيجابايت (يكتشف هذا مؤشرات NULL غير الصالحة ذات 32 بت والتي قد تكون قد اقتُطعت أثناء عملية إسناد ذهاب وإياب عبر عدد صحيح 32 بت). يمكن ضبط حجم هذا الجزء من خلال -pagezero_sizeعلامة المُصرّف/الرابط.

عند وضع مقطع في مساحة العناوين الافتراضية، يُمنح أذونات الوصول إلى وحدة المعالجة المركزية المحددة بقيمة حماية الذاكرة الافتراضية الأولية. يمكن تغيير أذونات الوصول إلى منطقة معينة من مساحة العناوين الافتراضية بواسطة تطبيق أو مكتبة برمجية من خلال استدعاءات لوظائف مثل mprotect() ؛ وتحدّ حماية الذاكرة الافتراضية القصوى من الأذونات الممنوحة للوصول إلى المقطع.

الأذونات
بت الإذن في النظام الثنائيوصف
00000000000000000000000000000001يسمح هذا القسم لوحدة المعالجة المركزية بقراءة البيانات من هذا القسم (إعداد القراءة).
0000000000000000000000000000010يسمح هذا القسم لوحدة المعالجة المركزية بكتابة البيانات إلى هذا القسم (إعداد الكتابة).
0000000000000000000000000000100يسمح هذا القسم لوحدة المعالجة المركزية بتنفيذ التعليمات البرمجية في هذا القسم (إعداد التنفيذ).
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx000الأرقام التي تحمل علامة "x" ليس لها استخدام، وهي محجوزة للاستخدام المستقبلي.

ثم بعد إعدادات حماية عنوان وحدة المعالجة المركزية، يأتي عدد الأقسام الموجودة داخل هذا الجزء والتي تتم قراءتها بعد إعدادات علامة الأجزاء.

إعدادات علامة القطاع هي كالتالي:

إعدادات علامة القطاع.
Flag32 في النظام الثنائيوصف
00000000000000000000000000000001محتويات الملف لهذا الجزء مخصصة للجزء العلوي من مساحة الجهاز الظاهري، أما الجزء السفلي فهو مملوء بالأصفار (للمكدسات في ملفات الذاكرة الأساسية).
0000000000000000000000000000010هذا الجزء هو الجهاز الظاهري الذي يتم تخصيصه بواسطة مكتبة أجهزة ظاهرية ثابتة، وذلك للتحقق من التداخل في محرر الروابط.
0000000000000000000000000000100لا يحتوي هذا الجزء على أي شيء تم نقله بداخله ولا شيء تم نقله إليه، أي أنه يمكن استبداله بأمان دون نقل.
0000000000000000000000000001000هذا الجزء محمي. إذا بدأ الجزء عند الإزاحة 0، فإن الصفحة الأولى منه غير محمية. أما باقي صفحات الجزء فهي محمية.
0000000000000000000000000010000يتم جعل هذا الجزء للقراءة فقط بعد تطبيق عمليات النقل إذا لزم الأمر.
xxxxxxxxxxxxxxxxxxxxxxxxxxx00000الأرقام التي تحمل علامة "x" ليس لها استخدام، وهي محجوزة للاستخدام المستقبلي.

عدد الأقسام في المقطع هو مجموعة من المدخلات التي تُقرأ على النحو التالي:

القسم 32/64
الإزاحة (32 بت)بايت (32 بت)الإزاحة (64 بت)بايت (64 بت)وصف
016016اسم القسم
16161616اسم المقطع
324328عنوان القسم
364408حجم القسم
404484إزاحة ملف القسم
444524تنسيق
484564إزاحة ملف عمليات النقل
524604عدد عمليات النقل
564644العلم/النوع
604684محجوز 1
644724محجوز ٢
غير متوفرغير متوفر764محجوز 3 (64 بت فقط)

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

ينطبق حجم القسم على كل من حجم القسم في موقع عنوانه وحجمه في الملف في موقع الإزاحة الخاص به.

تُقرأ قيمة قسم Flag/Type على النحو التالي:

إعدادات علامة القسم
العلم بالصيغة الثنائيةوصف
10000000000000000000000000000000xxxxxxxxيحتوي هذا القسم على تعليمات الآلة الحقيقية فقط
01000000000000000000000000000000xxxxxxxxيحتوي هذا القسم على رموز مدمجة لا ينبغي أن تكون موجودة في جدول محتويات ranlib
001000000000000000000000000000000xxxxxxxxيُسمح بإزالة الرموز الثابتة في هذا القسم في الملفات التي تحمل علامة MH_DYLDLINK.
000100000000000000000000000000000xxxxxxxxلا يوجد اتصال لاسلكي
00001000000000000000000000000000xxxxxxxxتكون الكتل نشطة إذا كانت تشير إلى كتل نشطة
000001000000000000000000000000000xxxxxxxxيُستخدم مع نماذج التعليمات البرمجية i386 المكتوبة بواسطة dyld
000000100000000000000000000000000xxxxxxxxقسم تصحيح الأخطاء
0000000000000000000010000000000xxxxxxxxيحتوي هذا القسم على بعض تعليمات الآلة
0000000000000000000001000000000xxxxxxxxيحتوي القسم على مدخلات نقل خارجية
0000000000000000000000100000000xxxxxxxxيحتوي القسم على إدخالات النقل المحلي

أي من الإعدادات التي تنطبق على القسم لها قيمة ثنائية مضبوطة على واحد. آخر ثمانية أرقام ثنائية هي قيمة نوع القسم.

قيمة نوع القسم
العلم بالصيغة الثنائيةوصف
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000110قسم يحتوي فقط على مؤشرات الرموز غير الكسولة
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000111قسم يحتوي فقط على مؤشرات الرموز الكسولة
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001000قسم يحتوي على رموز مختصرة فقط
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001100قسم التعبئة الصفرية عند الطلب (والذي يمكن أن يكون حجمه أكبر من 4 جيجابايت)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00010000قسم يحتوي فقط على مؤشرات الرموز الكسولة إلى مكتبات dylibs المحملة بشكل كسول

يقوم مُحمِّل Mach-O بتسجيل أقسام مؤشر الرمز وأقسام رمز الجذع. ويتم استخدامها بالتسلسل بواسطة جدول الرموز غير المباشر لتحميل استدعاءات الأساليب.

يُخزَّن حجم كل جزء من الرمز في القيمة reserved2. كل مؤشر عبارة عن موقع عنوان 32 بت في Mach-O ذي 32 بت، وموقع عنوان 64 بت في Mach-O ذي 64 بت. عند الوصول إلى نهاية القسم، ننتقل إلى القسم التالي أثناء قراءة جدول الرموز غير المباشر.

رقم الجزء وأرقام الأقسام

يتم تحديد مواقع الأجزاء والأقسام حسب رقم الجزء ورقم القسم في أقسام معلومات تحرير الروابط المضغوطة وغير المضغوطة.

قيمة المقطع 3 تعني الإزاحة لبيانات أمر تحميل المقطع الرابع في ملف Mach-O بدءًا من الصفر لأعلى (0،1،2،3 = المقطع الرابع).

تُرقّم الأقسام أيضًا بدءًا من القسم 1. يُستخدم الرقم صفر في جدول الرموز للرموز غير المُعرّفة في أي قسم (غير مُعرّفة). مثل طريقة أو بيانات موجودة ضمن قسم آخر من جدول رموز الملفات الثنائية.

المقطع الذي يحتوي على سبعة أقسام يعني أن القسم الأخير هو القسم الثامن. وإذا كان أمر تحميل المقطع التالي يحتوي على ثلاثة أقسام، فسيتم تسميتها بالأقسام 9 و10 و11. القسم رقم 10 يعني المقطع الثاني، القسم 2.

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

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

إذا كنت تقوم ببناء برنامج تحميل Mach-O، فأنت تريد تفريغ الأقسام إلى عناوين RAM المحددة بالإضافة إلى عنوان أساسي للحفاظ على تباعد التطبيقات حتى لا تكتب فوق بعضها البعض.

يمكن إعادة تسمية أسماء المقاطع وأسماء الأقسام إلى أي شيء تريده، ولن تكون هناك أي مشاكل في تحديد موقع الأقسام المناسبة بواسطة رقم القسم أو رقم المقطع طالما أنك لا تغير ترتيب أوامر المقاطع.

تتشابه مكتبات الربط مع أي ملف ثنائي آخر من نوع Mach-O، باستثناء عدم وجود أمر يحدد نقطة الدخول الرئيسية التي يبدأ عندها البرنامج.

توجد ثلاثة أوامر تحميل لتحميل ملف مكتبة الارتباط.

نوع أمر التحميل 0x0000000C مخصص لمسار الملف الكامل للمكتبة المشتركة المرتبطة ديناميكيًا.

تُستخدم أوامر التحميل من النوع 0x0000000D للمواقع المشتركة المرتبطة ديناميكيًا من المسار الحالي للتطبيق.

يُستخدم أمر التحميل من النوع 0x00000018 لمكتبة مشتركة مرتبطة ديناميكيًا يُسمح بفقدانها. توجد أسماء الرموز في مكتبات ارتباط أخرى، ويتم استخدامها في حال فقدان المكتبة، مما يعني استيراد جميع الرموز استيرادًا ضعيفًا.

يُقرأ أمر مكتبة الربط على النحو التالي:

أمر التحميل (ربط المكتبة)
إزاحةبايتوصف
040x0000000C (نوع الأمر)

0x0000000D (نوع الأمر)

0x00000018 (نوع الأمر)

44حجم القيادة
84إزاحة السلسلة (دائماً إزاحة 24)
124ختم التاريخ والوقت
164الإصدار الحالي
204إصدار متوافق
24حجم الأمر - 24سلسلة مسار الملف

يبدأ اسم مسار الملف من إزاحة السلسلة النصية، وهي دائمًا 24. عدد البايتات لكل حرف نصي هو عدد البايتات المتبقية في حجم الأمر. تُحدد نهاية مسار ملف المكتبة بالحرف 0x00 . تُستخدم قيم 0x00 المتبقية كحشو، إن وُجد.

يتم تحديد موقع المكتبة حسب الرقم الترتيبي في أقسام معلومات تحرير الروابط المضغوطة وغير المضغوطة.

تُرقّم مكتبات الربط من الترتيب 1 فصاعدًا. تُستخدم القيمة الترتيبية صفر في جدول الرموز لتحديد أن الرمز غير موجود كرمز خارجي في ملف ثنائي آخر من نوع Mach-O.

لن تواجه معلومات تعديل الرابط أي مشكلة في تحديد موقع المكتبة المناسبة للقراءة حسب الرقم الترتيبي طالما لم يتم تغيير ترتيب إدخال أوامر مكتبة الرابط.

ينبغي تجنب استخدام أمر ربط المكتبة 0x00000018 لأسباب تتعلق بالأداء، لأنه في حالة فقدان المكتبة، يجب إجراء بحث من خلال جميع مكتبات الربط المحملة.

__LINKEDITجدول الرموز

تحتوي ملفات تطبيق Mach-O ومكتبات الربط على أمر جدول الرموز.

يُقرأ الأمر على النحو التالي:

أمر التحميل (جدول الرموز)
إزاحةبايتوصف
040x00000002 (نوع الأمر)
44حجم الأمر (دائماً 24)
84الرموز (إزاحة الملف بالنسبة لرأس Mach-O)
124عدد الرموز
164جدول السلاسل النصية (إزاحة الملف بالنسبة إلى رأس Mach-O)
204حجم جدول السلاسل

إزاحة ملف الرموز هي المسافة النسبية من بداية رأس Mach-O إلى بداية إدخالات الرموز في الملف. ويشير عدد إدخالات الرموز إلى نهاية جدول الرموز.

يحتوي كل رمز على إزاحة اسم يجب ألا تتجاوز حجم جدول السلاسل النصية. تُضاف إزاحة اسم كل رمز إلى إزاحة ملف جدول السلاسل النصية، والتي بدورها تكون نسبية إلى بداية رأس Mach-O. وينتهي كل اسم رمز بقيمة بايت 0x00 .

يستخدم عنوان الرمز عنوانًا من 32 بت لملفات Mach-O ذات 32 بت وعنوانًا من 64 بت لملفات Mach-O ذات 64 بت.

تُقرأ كل خانة رمزية على النحو التالي:

الرمز 32/64
الإزاحة (32 بت)بايت (32 بت)الإزاحة (64 بت)بايت (64 بت)وصف
0404إزاحة الاسم
4141نوع الرمز
5151القسم رقم 0 إلى 255
6262معلومات البيانات (الرقم التسلسلي للمكتبة)
8488عنوان الرمز

تُضاف قيمة اسم الرمز إلى قيمة جدول السلاسل النصية. ويُقرأ آخر بايت من النص على أنه 0x00 .

تحتوي قيمة نوع الرمز على عدة أقسام قابلة للتعديل في النظام الثنائي. يُقرأ نوع الرمز كما يلي:

أقسام نوع الرمز
الأرقام الثنائيةوصف
???xxxxxرموز تصحيح الأخطاء المحلية
xxxx???xنوع عنوان الرمز
xxx?xxx?علامات ضبط رؤية الرموز

تُستخدم الأرقام التي تحمل علامة الاستفهام (؟) للغرض المحدد؛ أما الأرقام التي تحمل علامة x فتُستخدم لأغراض أخرى.

الأرقام الثنائية الثلاثة الأولى هي رموز تُحدد مواقع أسماء الدوال بالنسبة لتعليمات لغة الآلة المُجمّعة، وأرقام الأسطر بحسب موقع العنوان. تُتيح لنا هذه المعلومات توليد أرقام أسطر لموقع تعطل البرنامج. رموز تصحيح الأخطاء المحلية مفيدة فقط عند تصميم التطبيق، وليست ضرورية لتشغيله.

نوع عنوان الرمز
القيمة الثنائيةوصف
xxxx000xالرمز غير مُعرَّف
xxxx001xرمز مطلق
xxxx101xالرمز غير المباشر
xxxx110xالرمز المحدد مسبقًا غير معرف
xxxx111xالرمز المحدد في رقم القسم

إعدادات العلم التالية:

علامات ضبط رؤية الرموز
القيمة الثنائيةوصف
xxx1xxx0رموز خاصة
xxx0xxx1رمز خارجي

الرموز الخارجية هي رموز لها عنوان محدد في مكتبة الربط، ويمكن نسخها إلى رمز غير محدد في تطبيق Mach-O. يُضاف موقع العنوان إلى عنوان مكتبة الربط الأساسي.

يتم تجاهل الرمز الخاص حتى لو كان مطابقًا لاسم رمز غير مُعرَّف. ولا يمكن تعيين رمز خاص ورمز خارجي إلى رمز غير مُعرَّف إلا إذا كانا في الملف نفسه.

بعد نوع الرمز، يأتي رقم القسم الذي يوجد فيه الرمز. رقم القسم هو قيمة بايت (من 0 إلى 255). يمكنك إضافة أقسام أكثر من 255 باستخدام أوامر تحميل المقاطع، ولكن أرقام الأقسام ستكون حينها خارج نطاق قيمة البايت المستخدمة في إدخالات الرمز.

يشير رقم القسم صفر إلى أن الرمز غير موجود في أي قسم من أقسام التطبيق، وأن موقع عنوان الرمز هو صفر، وبالتالي فهو مُعيّن على أنه غير مُعرّف. يجب العثور على اسم رمز خارجي مطابق في مكتبة الارتباط التي تحتوي على عنوان الرمز.

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

أقسام معلومات بيانات الرموز
الأرقام الثنائيةوصف
؟؟؟؟؟؟؟؟xxxxxxxxرقم المكتبة الترتيبي من 0 إلى 255
xxxxxxxx????xxxxخيارات علامة التحميل الديناميكي
xxxxxxxxxxxx????خيار نوع العنوان

يُعيّن رقم المكتبة الترتيبي إلى الصفر إذا كان الرمز رمزًا خارجيًا، أو موجودًا في الملف الحالي. أما الرموز غير المعرّفة فقط، فتستخدم قسم معلومات البيانات لتحديد رقم المكتبة الترتيبي وخيارات الرابط.

خيارات علامة التحميل الديناميكي هي كما يلي:

خيارات علامة التحميل الديناميكي
الأرقام الثنائيةوصف
xxxxxxxx0001xxxxيجب تعيينها لأي رمز محدد يتم الرجوع إليه بواسطة المحمل الديناميكي.
xxxxxxxx0010xxxxيستخدمه الرابط الديناميكي في وقت التشغيل.
xxxxxxxx0100xxxxإذا لم يتمكن الرابط الديناميكي من العثور على تعريف لهذا الرمز، فإنه يضبط عنوان هذا الرمز على 0.
xxxxxxxx1000xxxxإذا وجد الرابط الثابت أو الرابط الديناميكي تعريفًا آخر لهذا الرمز، فسيتم تجاهل التعريف.

يمكن اختيار أي من الخيارات الأربعة المتاحة.

فيما يلي قيم خيارات نوع العنوان:

خيارات عنوان المحمل الديناميكي
الأرقام الثنائيةوصف
xxxxxxxxxxxx0000استدعاء دالة المؤشر غير المحملة بشكل كسول
xxxxxxxxxxxx0001استدعاء دالة المؤشر للتحميل الكسول
xxxxxxxxxxxx0010استدعاء الأسلوب المحدد في هذه المكتبة/البرنامج
xxxxxxxxxxxx0011تم تعريف استدعاء الأسلوب الخاص في هذه المكتبة/البرنامج
xxxxxxxxxxxx0100استدعاء دالة مؤشر خاصة غير محملة بشكل كسول
xxxxxxxxxxxx0101استدعاء دالة مؤشر خاصة محملة بشكل كسول

لا يمكن تعيين سوى قيمة واحدة لنوع العنوان. المؤشر هو قيمة يقرأها كود الآلة للبرنامج لاستدعاء دالة من ملف ثنائي آخر. تعني كلمة "خاص" أنه لا يُسمح للبرامج الأخرى بقراءة أو استدعاء الدالة/الأساليب باستثناء الملف الثنائي نفسه. أما كلمة "كسول" فتعني أن المؤشر ينتقل إلى dyld_stub_binder الذي يبحث عن الرمز ثم يستدعي الدالة، ثم يستبدل موقع dyld_stub_binder بموقع الرمز. أي استدعاءات أخرى تتم من كود الآلة في الملف الثنائي ستنتقل الآن إلى عنوان الرمز ولن تستدعي dyld_stub_binder.

تنظيم جدول الرموز

تُخزَّن جميع إدخالات جدول الرموز بالترتيب حسب النوع. أول الرموز التي تُقرأ هي رموز تصحيح الأخطاء المحلية إن وُجدت، ثم الرموز الخاصة، ثم الرموز الخارجية، وأخيرًا الرموز غير المُعرَّفة التي ترتبط بجدول رموز ثنائي آخر يحتوي على عنوان الرمز الخارجي في ملف ثنائي آخر من نوع Mach-O.

يوجد أمر تحميل معلومات جدول الرموز 0x0000000B دائمًا إذا كان هناك قسم لجدول الرموز في ملف Mach-O الثنائي. يُخبر هذا الأمر الرابط بعدد الرموز المحلية، والرموز الخاصة، والرموز الخارجية، والرموز غير المُعرَّفة. كما يُحدد رقم الرمز الذي تبدأ منه. تُستخدم معلومات جدول الرموز قبل قراءة مدخلات الرموز بواسطة الرابط الديناميكي، حيث تُخبره بمكان بدء قراءة الرموز لتحميل الرموز غير المُعرَّفة، ومكان بدء البحث عن الرموز الخارجية المطابقة دون الحاجة إلى قراءة جميع مدخلات الرموز.

يجب عدم تغيير ترتيب الرموز في قسم الرموز، حيث يتم ترقيم كل رمز من الصفر فصاعدًا. يستخدم أمر معلومات جدول الرموز أرقام الرموز لتحديد ترتيب تحميل الرموز غير المعرّفة في أقسام المؤشرات والوحدات الفرعية. سيؤدي تغيير الترتيب إلى استدعاء الدالة الخاطئة أثناء تنفيذ كود الآلة.

__LINKEDITمعلومات جدول الرموز

يستخدم الرابط الديناميكي أمر معلومات جدول الرموز لمعرفة مكان قراءة إدخالات جدول الرموز تحت أمر جدول الرموز 0x00000002 ، من أجل البحث السريع عن الرموز غير المعرفة والرموز الخارجية أثناء الربط.

يُقرأ الأمر على النحو التالي:

أمر التحميل (معلومات جدول الرموز)
إزاحةبايتوصف
040x0000000B (نوع الأمر)
44حجم الأمر (دائماً 80)
84فهرس الرموز المحلية
124عدد الرموز المحلية
164فهرس الرموز الخارجية
204عدد الرموز الخارجية
244فهرس الرموز غير المعرفة
284عدد الرموز غير المعرفة
324إزاحة جدول المحتوى
364عدد إدخالات جدول المحتويات
404إزاحة جدول الوحدات النمطية
444عدد إدخالات جدول الوحدة النمطية
484إزاحة إلى جدول الرموز المرجعي
524عدد إدخالات جدول الرموز المرجعية
564إزاحة جدول الرموز غير المباشرة
604إدخالات جدول الرموز غير المباشرة
644إزاحة النقل الخارجي
684عدد عمليات النقل الخارجية
724تعويض النقل المحلي
764عدد عمليات النقل المحلية

يتم ضرب فهرس الرمز في 12 لـ Mach-O 32 بت، أو 16 لـ Mach-O 64 بت بالإضافة إلى إزاحة إدخالات جدول الرموز للعثور على الإزاحة لقراءة إدخالات الرموز بواسطة فهرس رقم الرمز.

يكون فهرس الرمز المحلي صفرًا لأنه يقع في بداية إدخالات الرموز. تُستخدم الرموز المحلية لمعلومات تصحيح الأخطاء.

عدد الرموز المحلية هو عدد الرموز الموجودة بعد فهرس الرمز.

يتم تكرار نفس الخاصيتين للرموز الخارجية والرموز غير المعرفة من أجل قراءة سريعة لإدخالات جدول الرموز.

توجد فجوة صغيرة في الفهرس/الحجم بين الرموز المحلية والرموز الخارجية في حالة وجود رموز خاصة.

أي إزاحات ملفات تساوي صفرًا تكون غير مستخدمة.

جدول غير مباشر

يقوم مُحمِّل Mach-O بتسجيل أقسام مؤشر الرموز وأقسام الرموز الفرعية أثناء أوامر تحميل المقاطع. ويستخدمها جدول الرموز غير المباشر بالتتابع لتحميل استدعاءات الدوال. وبمجرد الوصول إلى نهاية القسم، ننتقل إلى القسم التالي.

يحدد إزاحة جدول الرموز غير المباشر مجموعة من القيم ذات 32 بت (4 بايت) والتي تستخدم كمؤشر لرقم الرمز.

إن ترتيب أرقام فهرس الرموز هو الترتيب الذي نكتب به عنوان كل رمز واحداً تلو الآخر في أقسام المؤشر والجذع.

يحتوي قسم رمز الجذع على تعليمات لغة الآلة مع تعليمات قفز إلى عنوان الرمز غير المباشر لاستدعاء دالة/طريقة من ملف ثنائي آخر من نوع Mach-O. يعتمد حجم كل تعليمة قفز على نوع المعالج، ويُخزَّن في القيمة reserved2 ضمن القسم section32/64 من أمر تحميل المقطع.

تُمثل أقسام المؤشر قيم عناوين 32 بت (4 بايت) للملفات الثنائية Mach-O ذات 32 بت، وقيم عناوين 64 بت (8 بايت) للملفات الثنائية Mach-O ذات 64 بت. يقرأ رمز الآلة هذه المؤشرات، وتُستخدم القيمة المقروءة كموقع لاستدعاء الدالة/الطريقة بدلاً من أن تحتوي على تعليمات رمز الآلة.

إن رقم فهرس الرمز 0x40000000 بت مضبوطة هو طريقة مطلقة، مما يعني أن المؤشر يحدد العنوان الدقيق للطريقة.

إن رمز رقم الفهرس 0x80000000 بت مضبوطة هو طريقة محلية، مما يعني أن المؤشر نفسه موجود في الطريقة وأنه لا يوجد اسم للطريقة (طريقة محلية).

إذا كنت تقوم بتصميم برنامج تفكيك، يمكنك بسهولة ربط اسم الرمز فقط بعنوان الإزاحة لكل جذع ومؤشر لإظهار استدعاء الطريقة أو الدالة التي تحدث دون البحث عن موقع عنوان الرمز غير المحدد في ملفات Mach-O الأخرى.

__LINKEDITطاولة مضغوطة

إذا كان أمر تحرير جدول الروابط المضغوطة موجودًا، فلن تكون هناك حاجة إلى الرموز غير المعرّفة/الخارجية في جدول الرموز. كما لن يكون هناك حاجة إلى جدول الرموز غير المباشر وموقع أقسام الروابط الفرعية والمؤشرات.

لا يزال جدول الرموز غير المباشر موجودًا في حالة إنشاء ملفات Mach-O متوافقة مع الإصدارات السابقة والتي يتم تحميلها على إصدارات نظام التشغيل الأحدث والأقدم.

أمر التحميل (جدول تحرير الرابط المضغوط)
إزاحةبايتوصف
040x00000022 (نوع الأمر)
44حجم الأمر (دائماً 48 بايت)
84إعادة ضبط إزاحة الملف
124حجم إعادة التأسيس
164إزاحة ملف الربط
204حجم الغلاف
244إزاحة ملف الربط الضعيف
284حجم التجليد الضعيف
324إزاحة ملف الربط الكسول
364حجم التجليد الكسول
404إزاحة ملف التصدير
444حجم التصدير

أي إزاحات ملفات تساوي صفرًا هي أقسام غير مستخدمة.

معلومات الربط

تتم قراءة أقسام الربط، والربط الضعيف، والربط الكسول باستخدام نفس تنسيق رمز العملية.

في الأصل، كان جدول الرموز يحدد نوع العنوان في حقل معلومات البيانات في جدول الرموز على أنه كسول أو ضعيف أو غير كسول.

يعني الربط الضعيف أنه إذا تم تحديد المكتبة المراد البحث فيها بواسطة رقم المكتبة الترتيبي، ولم يكن اسم الرمز المحدد موجودًا ولكنه موجود في ملف Mach-O مختلف تم تحميله مسبقًا، فسيتم استخدام موقع الرمز من ملف Mach-O الآخر.

تعني كلمة "Lazy" أن العنوان الذي يُكتب موجود في dyld_stub_binder، والذي يبحث عن الرمز ثم يستدعي الدالة، ثم يستبدل موقع dyld_stub_binder بموقع الرمز. أي استدعاءات أخرى تتم من كود الآلة في الملف الثنائي ستنتقل الآن إلى عنوان الرمز ولن تستدعي dyld_stub_binder.

لا يقوم قسم الربط البسيط بأي عمليات تحميل أو عنونة معقدة. يجب أن يكون الرمز موجودًا في ترتيب مكتبة المجموعة.

تحدد قيمة البايت 0x1X رقم ترتيب مكتبة الارتباط. أما الرقم الست عشري X فهو رقم ترتيب المكتبة من 0 إلى 15.

تقوم قيمة البايت التي تتراوح من 0x20 إلى 0x2F بتعيين الرقم الترتيبي لمكتبة الارتباط إلى القيمة التي تتم قراءتها بعد رمز العملية.

تسلسل البايت 0x20 0x84 0x01 يحدد الرقم الترتيبي 132.

يتم ترميز القيمة العددية بعد رمز العملية كرقم LEB128 . تُجمع آخر 7 أرقام ثنائية لتكوين رقم أكبر، بشرط أن يكون الرقم الثنائي الأخير مساويًا للواحد. يتيح لنا هذا ترميز قيم عددية ذات أطوال متغيرة.

تحدد قيمة البايت 0x4X اسم الرمز. ويحدد الرقم الست عشري المسمى X إعداد العلامة.

يشير الإعداد 8 إلى أن الدالة مستوردة بشكل ضعيف. ويشير الإعداد 1 إلى أن الدالة مستوردة بشكل غير ضعيف.

يُحدد تسلسل البايتات 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00 اسم الرمز Example. بايت الحرف النصي الأخير هو 0x00 . وهو مُستورد بشكل ضعيف، أي يُمكن استبداله إذا وُجد رمز آخر قابل للتصدير يحمل نفس الاسم.

تحدد قيمة البايت 0x7X الموقع الحالي. يشير الرقم السداسي العشري المُشار إليه بـ X إلى المقطع المُختار من 0 إلى 15. بعد رمز العملية، يُضاف الإزاحة كرقم LEB128 إلى إزاحة المقطع.

يقوم تسلسل البايت 0x72 0x8C 0x01 بتعيين الموقع إلى عنوان أمر تحميل الجزء الثالث ويضيف 140 إلى العنوان.

يربط رمز العملية من 0x90 إلى 0x9F موقع المجموعة الحالي باسم رمز المجموعة وترتيب المكتبة. يزيد موقع المجموعة الحالي بمقدار 4 بايتات لملف Mach-O ثنائي 32 بت، أو يزيد عنوان المجموعة بمقدار 8 بايتات لملف Mach-O ثنائي 64 بت.

تسلسل البايتات 0x11 0x72 0x8C 0x01 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00 0x90 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x32 0x00 0x90

يُعيّن هذا الأمر ترتيب مكتبة الارتباط رقم 1. ثم يُعيّن الموقع إلى رقم المقطع 2، ويُضيف 140 إلى الموقع الحالي. يبحث عن رمز باسم Example في ترتيب المكتبة المُحدد. يكتب رمز العملية 0x90 عنوان الرمز ويزيد العنوان المُعيّن حاليًا. بعد ذلك، يُعيّن رمز العملية اسم الرمز التالي للبحث عن رمز باسم Example2. يكتب رمز العملية 0x90 عنوان الرمز ويزيد العنوان المُعيّن حاليًا.

يؤدي التنسيق الجديد إلى إزالة الحقول المتكررة في جدول الرموز ويجعل جدول الرموز غير المباشر قديمًا.

نقطة الدخول الرئيسية للتطبيق

يتم استخدام أمر التحميل الذي يبدأ بالنوع 0x00000028 لتحديد موقع العنوان الذي يبدأ التطبيق عنده.

أمر التحميل (نقطة الدخول الرئيسية)
إزاحةبايتوصف
040x00000028 (نوع الأمر)
44حجم الأمر (دائماً 24 بايت)
88موقع العنوان
168حجم ذاكرة المكدس

إذا لم تكن هناك حاجة لنقل أجزاء/أقسام البرنامج لتشغيله، فإن نقطة الدخول الرئيسية هي موقع العنوان المحدد. هذا ينطبق فقط في حال إضافة عناوين أجزاء التطبيق إلى عنوان أساسي للتطبيق يساوي صفرًا، وعدم حاجة الأقسام إلى أي عمليات نقل.

نقطة الدخول الرئيسية في مُحمِّل Mach-O هي عنوان البرنامج الأساسي بالإضافة إلى موقع العنوان. هذا هو العنوان الذي يُضبط عليه المعالج لبدء تنفيذ تعليمات لغة الآلة.

وقد حل هذا محل أمر التحميل القديم 0x00000005 الذي كان يختلف باختلاف نوع وحدة المعالجة المركزية لأنه كان يخزن الحالة التي يجب أن تكون عليها جميع السجلات قبل بدء البرنامج.

رقم تعريف التطبيق الفريد (UUID)

يتم استخدام أمر التحميل الذي يبدأ بالنوع 0x0000001B لتحديد المعرف الفريد عالميًا (UUID) للتطبيق.

أمر التحميل (رقم UUID)
إزاحةبايتوصف
040x0000001B (نوع الأمر)
44حجم الأمر (دائماً 24 بايت)
816معرّف فريد عالمي (UUID) ذو 128 بت

يحتوي UUID على رقم عشوائي فريد مكون من 128 بت عند تجميع التطبيق والذي يمكن استخدامه لتحديد ملف التطبيق على الإنترنت أو في متاجر التطبيقات.

الحد الأدنى لإصدار نظام التشغيل

يتم استخدام أمر التحميل الذي يبدأ بالنوع 0x00000032 لتحديد الحد الأدنى من معلومات إصدار نظام التشغيل.

أمر التحميل (الحد الأدنى لإصدار نظام التشغيل)
إزاحةبايتوصف
040x00000032 (نوع الأمر)
44حجم القيادة
84نوع المنصة
124الحد الأدنى لإصدار نظام التشغيل
164إصدار SDK
204عدد الأدوات المستخدمة

أنواع المنصات التي يُفترض أن يعمل عليها الملف الثنائي هي كما يلي:

نوع المنصة.
قيمةمنصة
0x00000001نظام التشغيل macOS
0x00000002نظام التشغيل iOS
0x00000003tvOS
0x00000004أرشيف
0x00000005bridgeOS
0x00000006ماك كاتاليست
0x00000007محاكي نظام التشغيل iOS
0x00000008محاكي tvOS
0x00000009محاكي نظام التشغيل أندرويد
0x0000000ADriverKit
0x0000000Bنظام التشغيل VisionOS
0x0000000Cمحاكي نظام التشغيل VisionOS

تُقرأ قيمة الإصدار 32 بت كقيمة 16 بت وقيمتين 8 بت. على سبيل المثال، قيمة الإصدار 32 بت 0x000D0200 تُقسّم إلى: 0x000D (القيمة 13)، ثم 8 بتات التالية 0x02 (القيمة 2)، ثم 8 بتات الأخيرة 0x00 (القيمة صفر)، مما يُعطي رقم الإصدار 13.2.0v. تُقرأ قيمة إصدار SDK بنفس الطريقة.

عدد الأدوات اللازمة لإنشاء الملف الثنائي هو مجموعة من المدخلات التي تُقرأ على النحو التالي:

نوع الأداة
إزاحةبايتوصف
04نوع الأداة
44إصدار الأداة

قيم أنواع الأدوات هي كما يلي:

قيمة نوع الأداة.
قيمةنوع الأداة المستخدمة
0x00000001CLANG
0x00000002سويفت
0x00000003إل دي

يُقرأ رقم الإصدار بنفس طريقة قراءة إصدار نظام التشغيل وإصدار SDK.

مع إطلاق نظام التشغيل Mac OS X 10.6، طرأت تعديلات جوهرية على ملف Mach-O، مما يجعل الملفات الثنائية المُجمّعة على جهاز يعمل بنظام 10.6 أو أحدث قابلة للتنفيذ (افتراضيًا) فقط على أجهزة تعمل بنظام Mac OS X 10.6 أو أحدث. ويعود هذا الاختلاف إلى أوامر التحميل التي لا يفهمها الرابط الديناميكي في الإصدارات السابقة من Mac OS X. ومن التغييرات المهمة الأخرى في تنسيق Mach-O تغيير طريقة __LINKEDITعمل جداول Link Edit (الموجودة في القسم). في الإصدار 10.6، تُضغط هذه الجداول الجديدة بإزالة البيانات غير المستخدمة وغير الضرورية؛ إلا أن نظام Mac OS X 10.5 والإصدارات الأقدم لا تستطيع قراءة تنسيق جدول Link Edit الجديد هذا. ولإنشاء ملفات تنفيذية متوافقة مع الإصدارات السابقة، يمكن استخدام علامة الرابط "-mmacosx-version-min=".

تطبيقات أخرى

محللات ومحررات لغة Mach-O

ليس من النادر أن يعمل باحثو الأمن وغيرهم مع ملفات Mach-O من مصادر أخرى غير أجهزة Mac. وتنتشر البرامج التي تتيح تحليل أو حتى تعديل بنية بيانات Mach-O (كصيغة ملف).

بالنسبة للغة البرمجة روبي ، توفر مكتبة ruby-macho [ 16 ] تطبيقًا لمحلل ومحرر ثنائي Mach-O.

عدائي ماخ-أو

نظريًا، يُمكن تشغيل برنامج بصيغة Mach-O، بواسطة كود قادر على تحميل صور Mach-O في الذاكرة، على أنظمة تشغيل أخرى غير النظام الذي صُمم البرنامج لأجله، طالما وُجدت صورة ثنائية لـ Mach-O تُطابق نوع المعالج في الحاسوب المُستخدم. تحتوي معظم الحواسيب المكتبية والمحمولة على معالجات x86 ، ما يعني أن Mach-O بملف ثنائي x86 سيتمكن من التشغيل بمجرد تحميل الأجزاء في الذاكرة. أما إذا كانت Mach-O تحتوي على ملفات ثنائية ARM فقط ، مثل برامج أجهزة iPhone أو iPad، فلا يُمكن تشغيلها إلا على حاسوب مزود بنواة ARM متوافقة (ليس بالضرورة نواة Apple Silicon )؛ وإلا، فسيتعين استخدام أداة محاكاة مثل QEMU، حيث سيتعين تحويل تعليمات ARM إلى تعليمات x86 مُكافئة باستخدام أدوات محاكاة المعالج مثل QEMU.

تتمثل إحدى المشكلات العملية في تحميل وتنفيذ برنامج Mach-O مباشرةً في ظهور "رموز غير مُعرَّفة": فالملفات الثنائية لا تعمل بمعزل عن غيرها، بل تستدعي دوالًا/أساليب (رموزًا) من ملفات Mach-O الثنائية (المكتبات) لكي تعمل؛ ويؤدي عدم العثور على رمز إلى ظهور هذا الخطأ. تفترض ملفات Mach-O الخاصة بأنظمة iPhone (iOS) وmacOS وwatchOS وtvOS وجود مجموعة مكتبات مختلفة، مما يُسبب عدم توافق ناتج عن هذه المشكلة. يجب أن تكون هذه المكتبات موجودة على الجهاز الذي يُحاول تشغيل البرنامج، أو أن يستبدلها مُحمِّل Mach-O باستخدام دوال التكييف الخاصة به أو الدوال الموجودة في أنظمة التشغيل المُضيفة. كما يجب أن تُوفر إجراءات المكتبة المُستدعاة نفس واجهة التطبيق الثنائية التي تُوفرها إجراءات نظام التشغيل المُخصصة للبرنامج الثنائي، أو يجب توفير إجراء تكييف.

  • أُضيفت خاصية دعم لغة Mach-O إلى بعض إصدارات نظام NetBSD كجزء من تطبيق التوافق الثنائي، مما سمح بتشغيل بعض الملفات الثنائية لنظام Mac OS 10.3. [ 17 ] [ 18 ]
  • بالنسبة لنظام لينكس، قام شينيتشيرو هاماجي بكتابة برنامج تحميل Mach-O قادر على تحميل الملفات الثنائية لنظام 10.6. [ 19 ] وكحلٍّ أكثر شمولاً يعتمد على برنامج التحميل هذا، يهدف مشروع دارلينج إلى توفير بيئة متكاملة تسمح بتشغيل تطبيقات macOS على نظام لينكس.

انظر أيضًا إلى قسم "المشاريع المشتقة من نظام التشغيل داروين" ، والذي يتضمن بعض الجهود الأخرى لتحقيق التوافق الثنائي بين نظامي macOS وiOS. حتى الجهود التي استندت مباشرةً إلى نواة داروين نفسها تطلبت إضافة أكواد لاستبدال المكتبات والمكونات الأخرى التي لم تُصدرها شركة آبل كمصدر مفتوح.

انظر أيضاً

مراجع

  1. مواضيع برمجة Mach-O (ملف PDF) . أبل. 28 نوفمبر 2006.
  2. "مرجع تنسيق ملف Mach-O لنظام التشغيل OS X ABI" . شركة أبل. 4 فبراير 2009. مؤرشف من الأصل في 4 سبتمبر 2014.
  3. أفاديس تيفانيان الابن؛ ريتشارد ف. رشيد؛ مايكل و. يونغ؛ ديفيد ب. غولوب؛ ماري ر. طومسون؛ ويليام بولوسكي؛ ريتشارد سانزي (يونيو 1987). "واجهة يونكس للذاكرة المشتركة وملفات الذاكرة المُرتبطة في نظام ماخ" . وقائع مؤتمر يوسينكس الصيفي . فينيكس، أريزونا، الولايات المتحدة الأمريكية: جمعية يوسينكس. الصفحات 53-67 . 
  4. 1 2 "أنواع البيانات" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة آبل. 4 فبراير 2009 [2003]. مؤرشف من الأصل في 11 سبتمبر 2014. تم الاطلاع عليه في 15 مارس 2023 .
  5. xnu/EXTERNAL_HEADERS/mach-o/loader.h في main - apple-oss-distributions/xnu على GitHub
  6. 1 2 3 cctools/include/mach/machine-cctools.h في main - apple-oss-distributions/cctools على GitHub
  7. llvm-project/llvm/include/llvm/BinaryFormat/MachO.h في main - llvm-project/llvm على GitHub
  8. xnu/osfmk/mach/machine.h في main - apple-oss-distributions/xnu على GitHub
  9. "الملفات الثنائية الشاملة وملفات PowerPC الثنائية 32 بت/64 بت" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة آبل، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 4 سبتمبر 2014.
  10. "بناء ملف تنفيذي شامل لنظام macOS" . مطورو Apple .
  11. "fat_header" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة Apple Inc. ، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 4 سبتمبر 2014.
  12. "fat_arch" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة آبل، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 4 سبتمبر 2014.
  13. "هياكل بيانات أمر التحميل" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة آبل، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 11 سبتمبر 2014. تم الاطلاع عليه في 15 مارس 2023 .
  14. "segment_command" . مرجع تنسيق ملف Mach-O لنظام التشغيل OS X ABI . شركة آبل، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 11 سبتمبر 2014. تم الاطلاع عليه في 15 مارس 2023 .
  15. "segment_command_64" . مرجع تنسيق ملفات Mach-O لنظام التشغيل OS X ABI . شركة آبل، 4 فبراير 2009 [2003]. مؤرشف من الأصل في 11 سبتمبر 2014. تم الاطلاع عليه في 15 مارس 2023 .
  16. ويليام وودروف (15 نوفمبر 2021)، مكتبة روبي خالصة لتحليل ملفات Mach-O.
  17. إيمانويل دريفوس (20 يونيو 2006). " التوافق الثنائي بين Mach وDarwin لأنظمة NetBSD/powerpc وNetBSD/i386" . تم الاطلاع عليه في 18 أكتوبر 2013 .
  18. إيمانويل دريفوس (سبتمبر 2004)، التوافق الثنائي لنظام التشغيل Mac OS X على NetBSD: التحديات والتنفيذ (PDF)
  19. شينيتشيرو هاماجي، مُحمِّل Mach-O لنظام لينكس - لقد كتبته...

فهرس

  • ليفين، جوناثان (25 سبتمبر 2019). *أساسيات نظام التشغيل، المجلد 1: وضع المستخدم (  الإصدار 1.3.3.7). نورث كاسل، نيويورك: تكنولوجيكس. ISBN 978-0-9910555-6-2.
  • سينغ، أميت (19 يونيو 2006). أساسيات نظام التشغيل ماك أو إس إكس: منهج النظم . أديسون-ويسلي بروفيشنال. ISBN 978-0-13-270226-3.