في
مقال سابق (رابط) ، تحدثت عن المفهوم الأساسي لبرنامج Hypervisor القائم على تقنية المحاكاة الافتراضية لأجهزة Intel. أقترح الآن توسيع إمكانيات برنامج مراقبة الأجهزة الافتراضية عن طريق إضافة دعم لبنية المعالجات المتعددة (SMP) ، وأيضًا ضع في اعتبارك مثالاً على كيفية قيام برنامج مراقبة الأجهزة الافتراضية بإجراء تغييرات على نظام تشغيل الضيف.
سيتم تنفيذ جميع الإجراءات الإضافية على جهاز الكمبيوتر باستخدام التكوين التالي:
وحدة المعالجة المركزية: Intel Core i7 5820K
اللوحة الأم: Asus X99-PRO
رام: 16 جيجا
نظام التشغيل الضيف: Windows 7 x32 مع PAE Disabled
سأبدأ بوصف موقع مكونات برنامج مراقبة الأجهزة الافتراضية على القرص الصلب (يتم تحديد جميع القيم في القطاعات).
تختلف عملية تحميل hypervisor عن الإصدار السابق فقط في وجود وحدة نمطية جديدة hypervisor.ap ، والغرض منها هو التهيئة الأساسية لمعالج AP.عملية تحميل الوحدات في الذاكرة:
دعم SMPقمت بتطبيق برنامج مراقبة الأجهزة الافتراضية على مبدأ المعالجة المتعددة المتناظرة ، مما يعني أنه سيتم إطلاق نفس النسخة من VMX على جميع المعالجات المنطقية الموجودة. بالإضافة إلى ذلك ، ستكون جداول IDT و GDT ، وكذلك جداول ذاكرة الترحيل ، مشتركة لجميع المعالجات المنطقية. لقد فعلت ذلك لأن برنامج Hypervisor سيقوم بتهيئة الذاكرة فورًا لمساحة العنوان لنظام التشغيل الضيف ولا توجد حاجة لإعادة تعيين العناوين الفعلية للصفحات الفردية بشكل ديناميكي. أيضًا ، باستخدام هذا النهج ، لا تحتاج إلى مراقبة مراسلات مخابئ TLB للمعالج على جانب برنامج Hypervisor.
ستكون عملية التهيئة لـ BSP و AP مختلفة. سيتم إنشاء جميع الهياكل الرئيسية المشاركة في برنامج Hypervisor أثناء تهيئة BSP. بالإضافة إلى ذلك ، سيتم تعيين حالة النشاط لمعالجات AP بوضع الجذر غير vmx إلى حالة HLT. وبالتالي ، سيتم محاكاة بيئة نظام التشغيل الضيف وفقًا لما ستكون عليه بدون استخدام المحاكاة الافتراضية.
تهيئة BSP:
- تهيئة Spinlock
- تهيئة وتحميل جداول GDT و IDT
- تهيئة جداول الترحيل
- تهيئة هياكل VMCS وإنشاء جدول EPT مشترك
- تفعيل معالجات AP. للقيام بذلك ، يتم إرسال تسلسل مقاطعة INIT - SIPI إلى كل AP. المتجه لمقاطعة SIPI هو 0x20 ، وهو ما يتوافق مع نقل عنصر تحكم AP عند 0x20000 (وحدة hypervisor.ap)
- بدء تشغيل نظام تشغيل الضيف عند 0x7C00 (وحدة win7.mbr)
AP التهيئة:
- بعد تنشيط AP ، يكون المعالج في الوضع الحقيقي. تهيئة الوحدة النمطية hypervisor.ap الذاكرة وجداول الترحيل للتبديل إلى الوضع الطويل
- قم بتنزيل IDT و GDT وكذلك كتالوج جداول الترحيل التي تم إنشاؤها أثناء مرحلة تهيئة BSP
- تهيئة هياكل VMCS ، وتحميل جداول EPT التي تم إنشاؤها في مرحلة التهيئة من BSP
- التبديل إلى الوضع غير الجذر vmx مع حالة HLT النشطة
يمكننا القول أن تنفيذ دعم SMP في برنامج Hypervisor بسيط للغاية ، ولكن هناك بعض النقاط التي أود أن ألفت الانتباه إليها.
1.دعم USB Legacy
قد لا تحتوي موديلات اللوحة الأم الجديدة على موصلات PS / 2 ، لذلك يتم استخدام دعم USB Legacy لضمان التوافق مع الإصدارات السابقة. هذا يعني أنه يمكنك العمل باستخدام لوحة مفاتيح أو ماوس USB باستخدام نفس الأساليب (منافذ الإدخال / الإخراج) كما كانت مع معيار PS / 2. لا يعتمد تطبيق USB Legacy Support على طراز اللوحة الأم فحسب ، بل يمكن أيضًا أن يتم استخدامه في إصدارات مختلفة من البرامج الثابتة. على اللوحة الأم Asus X99-PRO ، يتم تنفيذ دعم USB Legacy من خلال مقاطعات SMI ، في المعالج الذي يحدث مضاهاة PS / 2. أكتب عن هذا بمثل هذه التفاصيل ، لأنه في حالتي (إصدار البرامج الثابتة 3801) ، لا يتوافق دعم USB Legacy مع الوضع الطويل وعندما يعود من SMM ، ينتقل المعالج إلى حالة إيقاف التشغيل.
الحل الأسهل في هذه الحالة هو إيقاف تشغيل دعم USB Legacy قبل التبديل إلى الوضع الطويل. ومع ذلك ، في Windows ، يتم استخدام طريقة اقتراع لوحة المفاتيح PS / 2 في مرحلة تحديد خيارات التمهيد ، لذلك يجب تنشيط دعم USB Legacy مرة أخرى قبل بدء تحميل نظام تشغيل الضيف.
2. تبديل مهمة الأجهزة
في أنظمة التشغيل الحديثة ، يتم تنفيذ التبديل بين المهام ، كقاعدة عامة ، من خلال طرق البرمجيات. ومع ذلك ، في Windows7 ، يتم تعيين المحددات التي تشير إلى TSS للمقاطعات 2 - NMI و 8 - خطأ مزدوج ، مما يعني أن هذه المقاطعات ستؤدي إلى تبديل سياق الأجهزة. لا يدعم Intel VMX تبديل مهام الأجهزة ، وتؤدي محاولة تنفيذه إلى خروج VM. لمثل هذه الحالات ، كتبت معالج تبديل المهام الخاص بي (وظيفة GuestTaskSwitch). يحدث مقاطعة خطأ مزدوج فقط في حالة وجود تعارض خطير في النظام بسبب المعالجة غير الصحيحة للمقاطعات الأخرى. في عملية التصحيح ، لم أصادف ذلك. لكن NMI يظهر على معالجات AP في وقت إعادة تشغيل Windows. لا يزال هذا يثير شكوكي لأنه من غير الواضح ما إذا كانت هذه NMIs ناتجة عن عملية إعادة تشغيل منتظمة أم أن هذه العملية غير الصحيحة لبرنامج Hypervisor في بعض المراحل السابقة. إذا كان لديك أي معلومات حول هذا الموضوع ، يرجى التحدث في التعليقات أو مراسلتي في رسالة شخصية.
التغييرات في نظام تشغيل الضيفبصراحة ، لم أستطع أن أقرر لفترة طويلة بالضبط التغييرات التي يجب أن يقوم بها برنامج مراقبة الأجهزة الافتراضية في عمل نظام التشغيل الضيف. والحقيقة هي من ناحية ، أردت أن أظهر شيئًا مثيرًا للاهتمام ، مثل إدخال معالجاتنا في بروتوكولات الشبكة الأساسية ، ولكن من ناحية أخرى ، فإن كل ذلك سيصل إلى كمية كبيرة من التعليمات البرمجية ، ولم يكن هناك الكثير للقيام به مع موضوع المشرف. بالإضافة إلى ذلك ، لم أرغب في ربط برنامج مراقبة الأجهزة الافتراضية بأي مجموعة محددة من الحديد.
ونتيجة لذلك ، تم العثور على الحل الوسط التالي: في هذا الإصدار من برنامج Hypervisor ، يتم تنفيذ التحكم في مكالمات النظام من وضع المستخدم ، وبعبارة أخرى ، سيكون من الممكن التحكم في تشغيل التطبيقات التي تعمل في نظام تشغيل الضيف. هذا النوع من التحكم سهل التنفيذ للغاية ويتيح لك بالإضافة إلى ذلك الحصول على نتيجة مرئية للعمل.
سيتم التحكم في تشغيل التطبيقات على مستوى مكالمات النظام. وسيكون الهدف الرئيسي تغيير نتيجة دالة
NtQuerySystemInformation بحيث يمكنك عند الاتصال مع وسيطة
SystemProcessInformation (
0x05 ) ، اعتراض معلومات العملية.
في Windows 7 ، يستخدم برنامج التطبيق لاستدعاء وظيفة النظام الأمر المجمع sysenter ، وبعد ذلك يتم نقل عنصر التحكم إلى معالج
KiFastCallEntry إلى kernel عند المستوى r0. للعودة إلى مستوى التطبيق r3 ، استخدم الأمر sysexit.
للوصول إلى نتائج
تنفيذ وظيفة
NtQuerySystemInformation ، من الضروري حفظ عدد الوظيفة المطلوبة في كل مرة يتم فيها تنفيذ الأمر sysenter. بعد ذلك ، عند تنفيذ
sysexit ، قارن القيمة المخزنة مع رقم الوظيفة التي يتم اعتراضها ، وإذا كان هناك تطابق ، قم بإجراء تغييرات على البيانات التي يتم إرجاعها بواسطة الوظيفة.
لا توفر Intel VMX وسائل مباشرة لرصد تنفيذ
sysenter / sysexit ، ومع ذلك ، إذا كتبت القيمة 0 إلى
Guest MSR IA32_SYSENTER_CS ، فإن
أوامر sysenter / sysexit ستثير استثناء GP الذي يمكن استخدامه لاستدعاء معالج VM Exit. من أجل استثناء GP لاستدعاء خروج VM ، تحتاج إلى تعيين 13 بت في حقل
استثناء الصورة النقطية من VMCS.
يتم استخدام الهيكل أدناه لمحاكاة زوج sysenter / sysexit.
typedef struct{ QWORD ServiceNumber; QWORD Guest_Sys_CS; QWORD Guest_Sys_EIP; QWORD Guest_Sys_ESP; } SysEnter_T;
يحتوي حقل
ServiceNumber على رقم الوظيفة التي يتم استدعاؤها ويتم تحديثها مع كل استدعاء إلى sysenter.
يتم
تحديث الحقول
Guest_Sys_CS و Guest_Sys_EIP و Guest_Sys_ESP عندما يحاول نظام التشغيل الضيف الكتابة إلى سجل MSR المقابل. للقيام بذلك ،
يتم تعيين أقنعة الكتابة في
عنوان MSR-Bitmap .
يجب ألا يرى نظام التشغيل الضيف التغييرات التي أجراها المشرف على تشغيل استدعاءات وظائف النظام. من خلال تعيين قناع القراءة لـ
MSR IA32_SYSENTER_CS ، يمكنك إعادة نظام التشغيل الضيف إلى قيمة التسجيل الأصلية عند القراءة.
ما يلي هو نظام مضاهاة الأمر
sysenter / sysexit .

في
مرحلة مضاهاة
sysexit ، تتم مقارنة الرقم
المخزن للوظيفة المطلوبة برقم NtQuerySystemInformation (0x105). في حالة المطابقة ، يتم التحقق من استدعاء NtQuerySystemInformation مع وسيطة معلومات معالجة النظام وإذا كان الأمر كذلك ، فإن وظيفة
ChangeProcessNames (DWORD SPI_GVA، DWORD SPI_size) تقوم بإجراء تغييرات على الهياكل التي تحتوي على معلومات حول العمليات.
SPI_GVA هو عنوان الضيف الظاهري لبنية
SYSTEM_PROCESS_INFORMATIONSPI_size هو الحجم الإجمالي للهياكل بالبايت.
تبدو بنية
SYSTEM_PROCESS_INFORMATION نفسها كما يلي:
typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; BYTE Reserved1[48]; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; PVOID Reserved2; ULONG HandleCount; ULONG SessionId; PVOID Reserved3; SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG Reserved4; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; PVOID Reserved5; SIZE_T QuotaPagedPoolUsage; PVOID Reserved6; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved7[6]; } SYSTEM_PROCESS_INFORMATION;
لا يوجد شيء معقد في تحليله ، الشيء الرئيسي هو عدم نسيان ترجمة عنوان الضيف الافتراضي إلى فعلي ، حيث يتم استخدام وظيفة
GuestLinAddrToPhysAddr () .
للتوضيح ، قمت باستبدال الحرفين الأولين في أسماء جميع العمليات بعلامة "
:) ". تظهر نتيجة هذا الاستبدال في لقطة الشاشة.
الملخصبشكل عام ، تم الانتهاء من المهام المحددة في بداية المقالة. يضمن برنامج Hypervisor التشغيل المستقر لنظام التشغيل الضيف ، ويتحكم أيضًا في استدعاء وظائف النظام من مستوى التطبيق. ألاحظ أن العيب الرئيسي لاستخدام محاكاة الأمر
sysenter / sysexit هو زيادة كبيرة في مكالمات VM Exit ، مما يؤثر على الأداء وهذا ملحوظ بشكل خاص عندما يكون نظام التشغيل الضيف في وضع المعالج المفرد. يمكن التخلص من هذا العيب إذا كنت تتحكم في المكالمات فقط في سياق العمليات المحددة.
وهذا كل شيء الآن. يمكن أن تؤخذ مصادر المقال
هناشكرا لكم على اهتمامكم.