Clear Sky Science · he
חיתוך בינארי סטטי מבוסס סטאק של WebAssembly ושינויו לייצור תת‑בינארים תקפים
מדוע חשוב לפצל קוד לחתיכות קטנות יותר
אפליקציות רשת מודרניות מסתמכות יותר ויותר על WebAssembly, שפה קומפקטית בדמות מכונה שמאפשרת לתוכניות שכתובות ב‑C, C++ או Rust לפעול במהירות קרובה‑למחשב המקומי בדפדפנים, בעננים ואפילו במכשירים משובצים זעירים. ככל שמערכות מריצות WebAssembly, צריכים דרכים בטוחות ומקיפות לבדוק את מנועי ההרצה האלה עבור שגיאות ופגיעויות ביטחוניות. אך תוכניות WebAssembly מהעולם האמיתי גדולות, מורכבות וקשה לאסוף במגוון מספק. עבודה זו מציגה שיטה חדשה לחתוך תוכניות WebAssembly קיימות להרבה מיני‑תוכניות קטנות, עצמאיות, ואז לשנותן בחוכמה. התוצאה היא אספקה עשירה של מקרים בדיקה תקפים, קטני קנה מידה, שיכולים לבחון מנועי WebAssembly בצורה יעילה יותר מכלי הבדיקה הקיימים.

מתוכנית אחת גדולה להרבה תוכניות קטנות
המחברים מתחילים מהתצפית שיצירת קוד WebAssembly אקראי כמעט אף פעם לא עובדת: השפה נבדקת בקפדנות, בייחוד סביב השימוש בסטאק שמחזיק ערכים זמניים. במקום ליצור קוד מאפס, הם מתחילים מבינאר "בסיסי" קיים ומשתמשים בטכניקה שנקראת חיתוך תוכניות (program slicing). פרוסה היא גרסה מצומצמת של תוכנית ששומרת רק את חלקי הקוד המשפיעים על נקודת עניין מסוימת, כמו הוראה ספציפית בתוך פונקציה. על‑ידי מעקב לאחור אחרי זרימת נתונים, שימוש בזיכרון וזרימת בקרה, השיטה מחלצת מקטע קומפקטי שממשיך "להיות משמעותי" מבחינת החישוב, במקום להיות רעש אקראי.
שמירה על איזון הסטאק הבלתי נראה
תוכניות 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, חיתוך תוכניות, שינוי בינארי, בטיחות תוכנה, אימות בזמן ריצה