درهم مجهري

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

في أنظمة التشغيل التقليدية، يتطلّب توفير السرية والتكامل التامَين قدرًا لا بأس به من العمل (غالبًا ما يكون مكرّرًا) لأنّ أنظمة التشغيل التقليدية لا تتوافق مع بنية Android العميقة. على سبيل المثال، باستخدام بنية Android العادية، يحتاج المطوّرون إلى تنفيذ وسيلة لتحميل جزء من تطبيقهم وتنفيذه بأمان في آلة افتراضية محمولة (pVM)، ويتم إنشاء الحمولة باستخدام glibc. يستخدم تطبيق Android Bionic، يتطلب الاتصال بروتوكولاً مخصصًا مقابل الاعتراض، كما أن تصحيح الأخطاء باستخدام adb أمر صعب.

يسد Microdroid هذه الفجوات من خلال توفير نسخة نظام تشغيل جاهزة تم تصميمها لتتطلب أقل قدر من الجهد من المطورين لتفريغ جزء من التطبيق في جهاز افتراضي (pVM). يستند الرمز الأصلي إلى Bionic، ويحدث الاتصال عبر Binder، ويسمح باستيراد APEX من المضيف Android ويعرض مجموعة فرعية من واجهة برمجة تطبيقات Android، مثل ملف تخزين المفاتيح لعمليات التشفير باستخدام المفاتيح المدعومة من الأجهزة. بشكل عام، من المفترض أن يجد المطوّرون في Microdroid بيئة مألوفة تتضمّن الأدوات التي اعتادوا عليها في نظام التشغيل Android الكامل.

الميزات

‫Microdroid هو إصدار مُبسَّط من Android مع بعض المكونات الإضافية الخاصة بأجهزة افتراضية شخصية. يدعم Microdroid ما يلي:

  • مجموعة فرعية من واجهات برمجة تطبيقات NDK (يتم توفير جميع واجهات برمجة التطبيقات لتنفيذ libc و Bionic في Android)
  • ميزات تصحيح الأخطاء، مثل adb وlogcat وtombstone وgdb
  • ميزة "التشغيل المتحقّق منه" وSELinux
  • تحميل وتنفيذ برنامج ثنائي مع المكتبات المشتركة المضمّنة في حزمة APK
  • Binder RPC عبر vsock وتبادل الملفات مع عمليات التحقّق الضمنية من السلامة
  • تحميل عناوين APEX

لا يدعم Microdroid ما يلي:

  • واجهات برمجة تطبيقات Java لنظام Android في حِزم android.\*

  • SystemServer وZygote

  • رسومات/ واجهة المستخدم

  • طبقة تجريد الأجهزة (HALs)

بنية النماذج المصغّرة الدقيقة

يشبه Microdroid تمامًا Cuttlefish فيهما بنية تشبه بنية Android العادية. يتألف Microdroid من القسم التالي الصور المجمّعة معًا في صورة قرص مركبة:

  • bootloader - التحقّق من صحة النواة وبدء تشغيلها
  • boot.img: يحتوي على النواة ومساحة التخزين المؤقت لبدء التشغيل.
  • vendor_boot.img: يحتوي على وحدات نواة خاصة بأجهزة افتراضية، مثل virtio.
  • super.img - يتألّف من الأقسام المنطقية للنظام والمورّد.
  • vbmeta.img: يحتوي على البيانات الوصفية للتشغيل المتحقَّق منه.

يتم شحن صور الأقسام في APEX للمحاكاة الافتراضية ويتم تجميعها في صورة قرص مركب من قِبل "VirtualizationService". بالإضافة إلى ملف VirtualizationService الرئيسي لصورة القرص المركب لنظام التشغيل، يكون VirtualizationService مسؤولاً عن إنشاء الأقسام الأخرى التالية:

  • payload: مجموعة من الأقسام التي تستند إلى حِزم APEX وحِزم APK من Android
  • instance - قسم مشفَّر للحفاظ على بيانات التشغيل التي تم التحقّق منها لكل مثيل، مثل الملح لكل مثيل والمفاتيح العامة الموثوق بها في APEX ومقاييس التراجع

تسلسل بدء التشغيل

يحدث تسلسل تشغيل Microdroid بعد تشغيل الجهاز. تتم مناقشة عملية تشغيل الجهاز في قسم البرامج الثابتة لنظام التشغيل pVM ضمن مستند البنية. يعرض الشكل 1 الخطوات التي تحدث أثناء تسلسل التمهيد في Microdroid:

عملية التمهيد الآمن مثيل microdroid

الشكل 1: عملية التمهيد الآمن لآلة microdroid الافتراضية

وفي ما يلي شرح الخطوات:

  1. يتم تحميل برنامج الإقلاع في الذاكرة بواسطة crosvm ويبدأ pvmfw في التنفيذ. قبل الانتقال إلى أداة تحميل البرامج، تُنفِّذ pvmfw مهمتَين:

    • التحقّق من برنامج الإقلاع للتأكّد من أنّه من مصدر موثوق به (Google أو أحد المصنّعين الأصليين للأجهزة)
    • تضمن هذه الميزة استخدام أداة تحميل البرامج نفسها بشكلٍ متسق في عمليات التمهيد المتعدّدة لنظام التشغيل الظاهري الشخصي نفسه من خلال استخدام صورة المثيل. على وجه التحديد، يتم تشغيل pVM في البداية باستخدام صورة مثيل فارغة. ويخزِّن pvmfw هوية برنامج التمهيد في صورة المثيل ويشفّرها. وبالتالي، في المرة التالية التي يتم فيها التمهيد لوحدة pVM باستخدام صورة المثيل نفسها، يفكّ pvmfw تشفير هوية العميل المحفوظة من صورة المثيل ويتأكّد من أنّها هي نفسها التي تم حفظها سابقًا. إذا اختلفت الهويات، يرفض pvmfw التمهيد.

    بعد ذلك، يشغِّل برنامج الإقلاع نظام التشغيل Microdroid.

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

  3. يتحقّق برنامج الإقلاع من بروتوكول vbmeta والأقسام المتسلسلة، مثل boot وsuper، وفي حال نجاحها، يشتق أسرار المرحلة التالية من الجهاز الافتراضي (PVM). بعد ذلك، ينقل Microdroid التحكّم إلى النواة.

  4. بما أنّه سبق أن تحقّق مشغّل الإقلاع من قسم Super (الخطوة 3)، يُثبِّت kernel القسم Super بدون قيد أو شرط. كما هو الحال مع نظام Android الكامل، يتألّف القسم الفائق من أقسام منطقية متعددة تم تثبيتها على dm-verity. ويتم بعد ذلك تمرير التحكّم إلى عملية init التي تبدأ خدمات أساسية مختلفة. يتشابه نص init.rc البرمجي مع نص برمجي كامل Android، ولكنه مصمّم خصيصًا لتلبية احتياجات Microdroid.

  5. تبدأ عملية init مدير Microdroid الذي يصل إلى مثيل الصورة. تُشفِّر خدمة مدير Microdroid الصورة باستخدام المفتاح الذي تم تمريره من المرحلة السابقة وتقرأ المفاتيح العامة ومقاييس التراجع لملف APK العميل وAPEXes التي يثق بها هذا الجهاز الظاهري للبرامج. وتستخدم كلّ من zipfuse وapexd هذه المعلومات لاحقًا عند تثبيت حِزم APK الخاصة بالعملاء وحِزم APEX المطلوبة، على التوالي.

  6. تبدأ خدمة مدير Microdroid في ‎apexd.

  7. يُثبِّت apexd نطاقات APEX في الأدلة /apex/<name>. الفرق الوحيد بين كيفية تثبيت نظامَي التشغيل Android وMicrodroid لحِزم APEX هو أنّه في نظام التشغيل Microdroid، تأتي حِزم APEX من أجهزة الكتل الافتراضية (/dev/vdc1، …)، وليس من الملفات العادية (/system/apex/*.apex).

  8. zipfuse هو نظام ملفات FUSE في Microdroid. zipfuse يُثبّت حزمة APK الخاصة بالعميل، وهي في الأساس ملف Zip بتنسيق نظام ملفات. في الأسفل، يتم تمرير ملف APK كجهاز كتلة افتراضية بواسطة pVM مع dm-verity، كما هو الحال مع APEX. يحتوي ملف APK على ملف إعدادات يحتوي على قائمة بتطبيقات APEX التي طلبها مطوّر التطبيقات لوحدة pVM هذه. يستخدم apexd القائمة عند تفعيل نقاط اتصال APEX.

  9. يعود تدفّق عملية التمهيد إلى خدمة Microdroid manager. بعد ذلك، تتواصل خدمة التحكم مع VirtualizationService في Android باستخدام Binder RPC حتى تتمكّن من الإبلاغ عن الأحداث المهمة، مثل الأعطال أو عمليات الإيقاف، وقبول الطلبات، مثل إنهاء تشغيل جهاز افتراضي. تقرأ خدمة المدير موقع البرنامج الثنائي الرئيسي من ملف تهيئة APK وتنفذه.

تبادل الملفات (AuthFS)

من الشائع أن تستخدم مكوّنات Android الملفات للإدخال والإخراج والحالة وإرسالها كأوصاف ملفات (ParcelFileDescriptor نوع في AIDL) مع التحكّم في الوصول من خلال نواة Android. يسهّل AuthFS وظائف مماثلة لتبادل الملفات بين نقاط النهاية التي لا تثق ببعضها البعض على مستوى حدود pVM.

في الأساس، AuthFS هو نظام ملفات عن بُعد يتضمّن عمليات تحقّق شفافة من السلامة في عمليات الوصول الفردية، مثل fs-verity. تسمح عمليات التحقّق للواجهة الأمامية، مثل برنامج قراءة الملفات الذي يتم تشغيله في جهاز افتراضي، برصد ما إذا كانت الواجهة الخلفية غير الموثوق بها، عادةً Android، قد تلاعبت بمحتوى الملف.

لتبادل الملفات، يتم بدء البرنامج الخلفي (fd\_server) باستخدام إعدادات لكل ملف تحدد ما إذا كان مخصّصًا للإدخال (للقراءة فقط) أو الإخراج (للقراءة والكتابة). بالنسبة إلى الإدخال، تفرض الواجهة الأمامية أن تتطابق المحتوى مع علامة هاشتاغ معروفة، بالإضافة إلى شجرة Merkle للتحقّق من الوصول. بالنسبة إلى الناتج، يحتفظ AuthFS داخليًا بشجرة تجزئة للمحتويات كما هو ملاحظ من عمليات الكتابة، ويمكنه فرض التكامل عند قراءة البيانات مرة أخرى.

يستند النقل الأساسي حاليًا إلى Binder RPC، ولكن قد يتغيّر ذلك في المستقبل لتحسين الأداء.

إدارة المفاتيح

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

متوسط عائد النقرة في Binder

يتم التعبير عن معظم واجهات Android في AIDL، والتي يتم إنشاؤها على أساس برنامج تشغيل Binder لنظام التشغيل Linux. لدعم الواجهات بين الأجهزة الافتراضية للتطبيقات، تمت إعادة كتابة بروتوكول Binder للعمل على مآخذ التوصيل، vsock في حال الأجهزة الافتراضية للتطبيقات. يتيح التشغيل عبر مآخذ التوصيل استخدام واجهات AIDL الحالية في Android في هذه البيئة الجديدة.

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