Clear Sky Science · ar
التقسيم الثابت الثنائي المستند إلى المكدس في WebAssembly والتحوير لإنتاج ثنائيات فرعية صالحة
لماذا يهم تقسيم الشيفرة إلى أجزاء أصغر
تعتمد تطبيقات الويب الحديثة بشكل متزايد على WebAssembly، وهي لغة مربّعة مضغوطة تشبه الآلة تسمح للبرامج المكتوبة بلغة C أو C++ أو Rust بالتشغيل بسرعة تقارب السرعة الأصلية في المتصفحات والسحب وحتى الأجهزة المدمجة الصغيرة. ومع ازدياد الأنظمة التي تنفذ WebAssembly، نحتاج طرقًا آمنة وشاملة لاختبار محركات التنفيذ هذه بحثًا عن أخطاء وثغرات أمنية. لكن برامج WebAssembly الحقيقية كبيرة ومعقدة ومن الصعب جمع تنوع كافٍ منها. تقدم هذه الورقة طريقة جديدة لتقسيم برامج WebAssembly الموجودة إلى العديد من البرامج الصغيرة المستقلة ثم تعديلها بذكاء. النتيجة مورد غني بحالات اختبار صالحة وحجمها مناسب يمكنه اختبار محركات WebAssembly بفعالية أكبر بكثير من الأدوات الحالية.

من برنامج كبير واحد إلى برامج صغيرة متعددة
ينطلق المؤلفون من ملاحظة أن توليد شيفرة WebAssembly عشوائية بالكاد ينجح: فهذه اللغة تخضع لرقابة صارمة، خاصة في تعاملها مع المكدس الذي يخزن القيم المؤقتة. وبدلاً من إنشاء الشيفرة من الصفر، يبدأون من ثنائي WebAssembly "أساسي" موجود ويستخدمون تقنية تسمى تقسيم البرنامج. المقطع هو نسخة مقلصة من البرنامج تحفظ فقط أجزاء الشيفرة التي تؤثر على نقطة اهتمام مختارة، مثل تعليمة معينة داخل دالة. من خلال تتبع تدفق البيانات، واستخدام الذاكرة، وتدفق التحكم للخلف بدءًا من تلك النقطة، تستخرج الطريقة مقطعًا مدمجًا يبقى "معنياً" من حيث الحساب، بدلاً من أن يكون ضوضاء عشوائية.
الحفاظ على توازن المكدس غير المرئي
تعتمد برامج WebAssembly على انضباط صارم للمكدس: كل تعليمة تزيل وتضيف قيمًا، ويجب أن تترك الكتل المهيكلة والتفرعات المكدس في الشكل الصحيح عند انتهائها. يؤدي قطع أجزاء برنامج بشكل ساذج إلى كسر هذا الانضباط في الغالب، مما يجعل النتيجة غير صالحة. سبق أن أصلحت أعمال سابقة المقاطع عن طريق حشوها بنماذج ثابتة من تعليمات وهمية، مما أبقاها قابلة للتشغيل لكنه حدّ من تنوعها. تقدم هذه الورقة بدلاً من ذلك خوارزمية مخصصة لتصحيح توازن المكدس. تحلل تدفق التحكم داخل كل مقطع، وتجد أماكن حيث تخلّ التفرعات أو نهايات الكتل بشكل المكدس المتوقع، ثم تُدخل تسلسلات تعليمات مصممة خصيصًا لإسقاط القيم غير المطلوبة وتوليد قيم جديدة من الأنواع المناسبة. تستعيد هذه "الأدوات" الصغيرة الصِحّة بينما تسمح بأنماط تعليمات أغنى بكثير من الحشو البسيط.
بناء برامج مصغرة كاملة مع تعقيد متحكم به
لا يزال المقطع المصحح مجرد جسم دالة، وقد تستدعي تلك الدالة دوال أخرى أو تعتمد على ميزات على مستوى الوحدة مثل المتغيرات العالمية والذاكرة الخطية. لذلك يوسع المؤلفون طريقتهم لتجميع وحدات مصغرة قابلة للتنفيذ كاملة. بدءًا من دالة دخول مختارة عشوائيًا، يقومون بتقطيع وإصلاح أي دوال يتم استدعاؤها بشكل متكرر، حتى عمق استدعاء يحدده المستخدم يتحكم بعدد طبقات الاستدعاءات المحفوظة. بعد ذلك العمق، تُستبدل الاستدعاءات ببدائل قصيرة تُحاكي العدد الصحيح من الوسائط والنتائج دون جلب مزيد من الشيفرة. كما يعيد النظام بناء الأقسام المحيطة بوحدة WebAssembly — مثل الأنواع والجداول والذاكرة وما إلى ذلك — بحيث يكون كل ثنائي مولَّد مكتفيًا ذاتيًا ويمكن تشغيله مباشرة بواسطة الأدوات وبيئات التشغيل القياسية.

إضافة التنوع عبر التحوير الدقيق
حتى مع التقسيم، تبقى العديد من الثنائيات المولَّدة شبيهة ببرنامج الأصل. لتوسيع التغطية، يُدخل المؤلفون مرحلة تحوير تعمل للخلف عبر كل دالة. بالنسبة للتعليمات التي تستهلك مداخل، تختار الخوارزمية عشوائيًا نوع نتيجة جديد، وتجد تعليمات بديلة تنتج ذلك النوع، ثم تُحوّر بشكل متكرر التعليمات السابقة التي تزود مداخله بحيث يتناسق كامل السلسلة. يحافظ هذا على صحة المكدس أثناء إعادة تشكيل الحساب. مقارنة بمجموعة أساسية من برامج WebAssembly الواقعية، تحتوي الثنائيات المحوَّرة على أنماط تعليمات مميزة أكثر بكثير وتستخدم بكثافة أكبر ميزات نادرة الظهور مثل عمليات المتجهات، وهي مهمة لاختبار التنفيذ الكامل لمحركات WebAssembly.
ما تكشفه التجارب
لاختبار النهج، نفذ المؤلفون حوالي 17,000 سطر من بايثون يغطي تقريبًا معيار WebAssembly 2.0 بالكامل. باستخدام مجموعة بيانات عامة كبيرة من آلاف الثنائيات الواقعية، أظهروا أن التقنية يمكنها عادة تقليص البرامج إلى جزء من عدد تعليماتها الأصلي — غالبًا إلى أقل من 40% من أحجام الخط الأساس الأكبر — مع إبقائها صالحة في أكثر من 99% من الحالات عند تمكين التحوير. تعمل الطريقة بسرعة، عادةً أقل من ثانية لكل ثنائي مولَّد متوسط الحجم، وتزيد بشكل كبير كلًا من نطاق أنواع التعليمات وعدد تسلسلات التعليمات الفريدة المرصودة. عمليًا، يعني ذلك أن المختبرين وباحثي الأمن يستطيعون تحويل مجموعة متواضعة من برامج WebAssembly إلى مجموعة كبيرة ومتنوعة من الثنائيات الصغيرة والصالحة التي تناسب الفازينغ، والاختبار التفاضلي، واختبار الانحدار لبيئات تشغيل WebAssembly.
كيف يساعد هذا في الحفاظ على أمان WebAssembly
بعبارات يومية، تصف الورقة "مُنقِّح شيفرة" ذكيًا لـ WebAssembly: يقطع البرامج الكبيرة إلى أجزاء أصغر ومعنوية، يصلحها تلقائيًا بحيث تظل ملتزمة بقواعد اللغة الصارمة، ثم يعيد تشكيلها لاستكشاف زوايا غير معتادة من مجموعة التعليمات. وبما أن هذه البرامج المصغرة تظل واقعية ومع ذلك مدمجة، فيمكن تشغيلها بسرعة وبأعداد كبيرة، مما يزيد فرص اكتشاف أخطاء دقيقة أو مشكلات أمنية في البرمجيات التي تنفذ WebAssembly. مع انتشار WebAssembly من المتصفحات إلى السحب والأجهزة، يوفر هذا التوليد المنهجي لثنائيات اختبار صالحة ومتنوعة أداة مهمة للحفاظ على متانة وأمن هذا النظام البيئي.
الاستشهاد: Choi, G., Jeon, S. Stack-based static WebAssembly binary slicing and mutation for generating valid sub-binaries. Sci Rep 16, 10910 (2026). https://doi.org/10.1038/s41598-026-45837-y
الكلمات المفتاحية: اختبار WebAssembly, تقسيم البرنامج, تحوير ثنائي, أمن البرمجيات, التحقق أثناء التشغيل