למה אבטחת קוד קריטית במערכות Embedded במיוחד לקוד שנכתב ב C וגם ב C++ ?

תמונת אילוסטרציה ל קורס secure code embedded systems c and c++

עודכן לאחרונה: 19 אפריל, 2026

מה הסיבות ש Secure קוד ב Embedded System בעיקר אם נכתב ב C C++ הוא קריטי

 

בעבר, מערכות משובצות מחשב (Embedded Systems) נחשבו ל"איים מבודדים". הן לא היו מחוברות לאינטרנט, הן הריצו קוד סגור על חומרה ייעודית, וההנחה הייתה שמי שאין לו גישה פיזית למכשיר – לא יכול להזיק לו. היום, המציאות הזו השתנתה לחלוטין.

בעידן ה-IoT והמערכות המקושרות, המקרר הביתי, בקר המשאבה במפעל והמחשב ברכב מחוברים כולם לרשת. חיבור זה הופך כל שורת קוד ב-C או ב-++C למטרה פוטנציאלית עבור תוקפים.

ההבדל בין באג רגיל לפרצת אבטחה

בעוד שבתוכנת Desktop "באג" יכול להסתכם בקריסת האפליקציה, במערכות Embedded ההשלכות הן אחרות לגמרי:

  • נזק פיזי וסביבתי: קוד לא מאובטח בבקר תעשייתי עלול להוביל לחימום יתר או להשבתת תשתיות.
  • סיכון חיי אדם: במכשירים רפואיים או במערכות רכב, שיבוש של פסיקה (Interrupt) או דריסת זיכרון יכולים להיות קטלניים.
  • גניבת קניין רוחני: תוקפים יכולים לנצל חולשות כדי לחלץ קוד (Firmware) ולהנדס אותו לאחור.

למה C ו-++C הן "חרב פיפיות"?

שפות C ו-++C הן הבחירה הטבעית ל-Embedded בגלל היעילות והשליטה הישירה בחומרה. אך השליטה הזו מגיעה עם מחיר: השפה לא "שומרת" על המפתח. טעויות קטנות בניהול מצביעים (Pointers), חישוב שגוי של גודל מערך או שימוש לא נכון בטיפוסי נתונים (Integer Promotion) הם המקומות שבהם פרצות אבטחה נולדות.

הידעת? למעלה מ-70% מפרצות האבטחה הקריטיות בעשורים האחרונים נבעו מניהול זיכרון לא תקין – נושא שנמצא בליבת הקורס שלנו.

המטרה שלנו

דף תמיכה זה, והקורס כולו, נועדו להקנות לך את ה-"Security Mindset". אנחנו לא רק לומדים לכתוב קוד שעובד (Functional Code), אלא קוד שהוא חסין (Robust) ומאובטח (Secure) לפי התקנים המחמירים ביותר בעולם (MISRA, CERT).

בהמשך  ריכוז של השאלות הטכניות הנפוצות ביותר (Technical FAQ) עבור דף התמיכה. שאלות אלו נועדו לתת מענה למפתחים שרוצים להבין את העומק המקצועי של הקורס ואת הרלוונטיות שלו לעבודה היומיומית שלהם.

לפני שנרשמים מה חשוב שיהיה בארגז הכלים של המפתח

 

כדי להצליח בקורס ולצלול לעומק עולם האבטחה ב-Embedded, חשוב להגיע עם בסיס טכני איתן. הקורס אינו מיועד למתכנתים מתחילים, אלא למפתחים שכבר "מרגישים בבית" מול החומרה.

ידע קודם נדרש

  • שליטה בשפת C: ניסיון מעשי בכתיבת קוד למערכות Bare-metal או RTOS.
  • הבנת ארכיטקטורת מחשב: היכרות עם מושגי יסוד כמו ה-Stack, ה-Heap, אוגרים (Registers) וניהול זיכרון.
  • עבודה עם מצביעים (Pointers): הבנה עמוקה של Pointer Arithmetic וניהול מערכים – זהו האזור שבו רוב פרצות האבטחה מתרחשות.
  • היכרות ושליטה ב C++ : היכרות עם OOP בסיסי תסייע בהבנת מנגנוני ה-RAII וה-Templates.
  •  ⁠ניסיון מעשי עם מערכות הפעלה (RTOS/Bare-metal). ⁠הקורס יכלול שימוש (Evaluation Boards)

סביבת העבודה והכלים (Software Stack)

במהלך הקורס נשתמש בכלים המקובלים ביותר בתעשייה, כדי שהידע שתרכשו יהיה ישים מיד ביום העבודה הבא שלכם:

  • קומפיילרים: עבודה מול GCC ו-Clang, תוך התמקדות בדגלי אבטחה (Hardening Flags).
  • כלי אנליזה סטטיים: התנסות ב-Cppcheck ובדיקת קוד מול חוקי MISRA.
  • כלי אנליזה דינמיים: שימוש ב-AddressSanitizer (ASan) ו-Valgrind לאיתור זליגות זיכרון בזמן אמת.
  • סביבת הרצה: שילוב בין עבודה על Linux (לצרכי סימולציה ובדיקות) לבין פלטפורמות Embedded נפוצות.

למי הקורס מתאים?

  • מפתחי Firmware ו-Embedded מנוסים.
  • מהנדסי מערכות משובצות שרוצים להתמחות בהגנת סייבר.
  • ראשי צוותים וארכיטקטים של תוכנה בתחומי הרכב, הרפואה והביטחון.
  • מפתחי Real-Time המעוניינים ליישר קו עם התקנים הבינלאומיים העדכניים.

מדריך מהיר: חמשת "המוקשים" הנפוצים בקוד C/C++

 

כדי לכתוב קוד מאובטח, צריך קודם כל להכיר את הדרכים שבהן הוא נשבר. הנה חמש מהטעויות הנפוצות ביותר במערכות Embedded והדרך הנכונה להתמודד איתן:

1. Buffer Overflow

המוקש: שימוש בפונקציות כמו strcpy או sprintf ללא בדיקת גבולות המערך. תוקף יכול להזין מחרוזת ארוכה מהמתוכנן ולדרוס את ה-Stack, מה שמאפשר הרצת קוד זדוני.

הפתרון: מעבר לפונקציות בטוחות (כמו strncpy או snprintf) ושימוש ב-Stack Canaries – מנגנון שמזהה דריסת זיכרון לפני שהפונקציה חוזרת.

2. שימוש בזיכרון לאחר שחרור (Use-after-free)

המוקש: גישה למצביע (Pointer) שמתייחס לכתובת זיכרון שכבר שוחררה (free). במערכות מורכבות, הכתובת הזו עלולה להיות מוקצית מחדש למשימה אחרת, מה שמוביל לשיבוש נתונים קריטי.

הפתרון: אימוץ אסטרטגיית Static Allocation במידת האפשר, או שימוש ב-Smart Pointers (ב-C++) שמנהלים את מחזור החיים של האובייקט באופן אוטומטי.

3. קידום טיפוסים (Integer Promotion) וגלישה

המוקש: חישובים אריתמטיים פשוטים בין טיפוסים שונים (למשל uint8_t מול int) עלולים להוביל לתוצאות לא צפויות בגלל חוקי השפה, או לגלישה (Overflow) שמשבשת לוגיקה של בדיקות אבטחה.

הפתרון: שימוש בטיפוסים מוגדרים היטב (stdint.h), בדיקת חריגות לפני ביצוע הפעולה, והפעלת דגלי קומפיילר כמו -Wconversion.

4. מצב מרוץ (Race Condition) בפסיקות

המוקש: פונקציית פסיקה (ISR) שמעדכנת משתנה גלובלי בזמן שתוכנית ה-Main קוראת אותו. ללא הגנה, התוכנית עלולה לקרוא ערך חלקי או שגוי.

הפתרון: הגדרת משתנים כ-volatile, שימוש ב-Atomic Operations או חסימת פסיקות ב"קטעים קריטיים" (Critical Sections).

5. התעלמות מערכי חזרה (Return Values)

המוקש: פונקציות מערכת רבות מחזירות סטטוס שגיאה, אך מפתחים נוטים להתעלם מהן ("לי זה לא יקרה"). תוקף יכול לגרום לפונקציה להיכשל במכוון כדי להעביר את המערכת למצב לא מוגדר.

הפתרון: אכיפת בדיקת ערכי חזרה לכל פונקציה קריטית ושימוש ב-Static Analysis כדי לוודא שאין התעלמות משגיאות.

מדריך עומק למהנדסים — מבט של מרצה

 

כאשר אני פוגש מהנדסים שמגיעים לקורס, רובם כבר “יודעים C”. חלקם עובדים שנים על מערכות Embedded, חלקם מגיעים מעולמות RTOS, דרייברים או Firmware. ובכל זאת, כמעט בכל קוד שאני בודק — גם של מפתחים מנוסים — יש דפוסים חוזרים של טעויות אבטחה, או ליתר דיוק: הנחות לא נכונות לגבי התנהגות המערכת.

הנקודה המרכזית שאני מדגיש כבר בשיעור הראשון היא זו:
במערכות Embedded, אבטחת קוד אינה שכבה נוספת — היא חלק מהדיזיין הבסיסי של המערכת. כל החלטה על זיכרון, תזמון, API או קומפיילר משפיעה ישירות על רמת הסיכון.

במאמר הזה אני מרכז את התשתית המחשבתית והטכנית שאני מצפה מהסטודנטים להבין. לא כסילבוס, אלא כבסיס מקצועי שמגדיר מה זה “קוד בטוח” במערכות משובצות.

פרויקטים ומעבדות (Hands-on)

הקורס מבוסס על גישת "Learn by Breaking" – אנחנו לומדים איך לתקוף ולהפיל מערכת, כדי להבין איך לבנות אותה חסינה באמת. כל מודול מסתיים במעבדה מעשית (Lab) שבה תתנסו במקרים אמיתיים מהשטח.

מעבדה 1: מציד באגים ל-Hardening

במעבדה זו תקבלו קוד קיים למערכת בקרה פשוטה המכילה פגימויות זיכרון קלאסיות. המטרה: להריץ התקפת Buffer Overflow שתגרום למערכת לשנות את זרימת התוכנית (Jump to address).

דוגמה למה שנלמד לתקן:

  • הקוד הבעייתי (Unsafe):

C

void process_data(char *input) {

    char buffer[16];

    // סכנה: אין בדיקה של גודל הקלט!

    strcpy(buffer, input); 

}

 

  • הקוד המאובטח (Secure) לאחר המעבדה:

C

#define SAFE_BUFFER_SIZE 16

 

void process_data(const char *input) {

    char buffer[SAFE_BUFFER_SIZE];

    // שימוש בפונקציה בטוחה עם הגבלת גודל וסיומת Null

    if (strncpy(buffer, input, SAFE_BUFFER_SIZE - 1) != NULL) {

        buffer[SAFE_BUFFER_SIZE - 1] = '';

        // לוגיקה נוספת לטיפול בשגיאה

    }

}

 

מעבדה 2: ניהול משאבים ו-Race Conditions

התמודדות עם באגים חמקמקים שקורים רק ב-Runtime. נשתמש בסימולטור RTOS כדי לזהות מצבי מרוץ (Race Conditions) בין פסיקות (ISRs) למשימות רקע.

מה עושים בפועל?

  • זיהוי משתנים גלובליים לא מוגנים.
  • הטמעת Atomic Operations במקום חסימת פסיקות גורפת (לשיפור ביצועים).
  • שימוש ב-Lock-guards ב-C++ כדי למנוע Deadlocks.

מעבדה 3: Refactoring לקוד תקני (MISRA Compliance)

קבלת פרויקט "מלוכלך" והעברתו דרך כלי אנליזה סטטיים (Static Analysis). המשימה היא להביא את הקוד למצב של אפס חריגות מתקן MISRA-C/C++.

פרויקט סיום: תכנון API מאובטח למערכת Embedded

בפרויקט המסכם, תדרשו לתכנן מאפס שכבת Driver או API למערכת תקשורת. הפרויקט חייב לכלול:

  1. Input Validation: אימות קלט קפדני מול פקודות שמגיעות מבחוץ (UART/CAN-Bus).
  2. Fault Management: מנגנון התאוששות עצמי (Self-healing) במקרה של שגיאת זיכרון.
  3. Static Memory: עבודה ללא שימוש ב-Malloc/Free בכלל.

הנה דוגמה נוספת למעבדה שמתמקדת במעבר ל-C++ מאובטחת. זהו אחד הנושאים הכי מבוקשים, כי מפתחים רבים חוששים מה"תקורה" (Overhead) של C++ במערכות Embedded, והמעבדה הזו מראה איך להשתמש בה כדי להגביר את האבטחה בלי להקריב ביצועים.

מעבדה 4: ניהול משאבים ב-C++ ופתרון ה-Memory Leak

במעבדה זו נלמד כיצד למנוע את אחת הבעיות הנפוצות והמסוכנות ביותר: זליגת זיכרון (Memory Leak) וגישה לזיכרון משוחרר. נראה איך מנגנוני השפה המודרניים מחליפים את הניהול הידני המסוכן.

דוגמה לשינוי התפיסתי (Refactoring):

  • הקוד המסוכן (Raw Pointers):
    במקרה של תקלה או יציאה מוקדמת מהפונקציה, הזיכרון לא ישוחרר לעולם.

C++

void processing_task() {

    DeviceHandler* handler = new DeviceHandler(); // הקצאה ידנית

    

    if (!handler->initialize()) {

        return; // אופס! הזיכרון דלף (Memory Leak)

    }

    

    handler->run();

    delete handler; // שחרור ידני - קל לשכוח או לבצע פעמיים

}

  • הקוד המאובטח (RAII & Smart Pointers):
    הזיכרון משוחרר באופן אוטומטי ברגע שהאובייקט יוצא מטווח הראייה (Scope), גם אם קרתה שגיאה.

C++

void processing_task() {

    // שימוש ב-Unique Pointer - אפס תקורה בביצועים וביטחון מלא

    auto handler = std::make_unique<DeviceHandler>();

    

    if (!handler->initialize()) {

        return; // הזיכרון משוחרר אוטומטית כאן!

    }

    

    handler->run();

    // אין צורך ב-delete ידני

}

מה תרגלו הסטודנטים במעבדה זו?

  1. מימוש מחלקות בגישת RAII: הבטחת שחרור משאבים (זיכרון, Mutex, קבצים) גם במקרה של חריגות (Exceptions) או שגיאות.
  2. שימוש ב-Smart Pointers: הבנה מתי להשתמש ב-std::unique_ptr (בעלות יחידה) ומתי ב-std::shared_ptr.
  3. מניעת התנהגות לא מוגדרת: שימוש במילות המפתח override ו-final כדי למנוע טעויות ירושה מסוכנות.
  4. אופטימיזציה בזמן קומפילציה: שימוש ב-constexpr כדי להעביר חישובים מורכבים ואימותי נתונים מזמן הריצה (Runtime) לזמן הקומפילציה, מה שמונע פרצות פוטנציאליות במכשיר עצמו.

 

שאלות ותשובות טכניות לאבטחת קוד ב סי וסי פלאס פלאס

 

ש: מה ההבדל המהותי בין תקן MISRA לבין תקן CERT C?

ת: בעוד ששני התקנים שואפים לקוד איכותי יותר, המיקוד שלהם שונה:

  • MISRA (Motor Industry Reliability Association): מתמקד באמינות ובטיחות (Safety). הוא מגדיר תת-קבוצה בטוחה של שפת C כדי למנוע התנהגויות לא צפויות במערכות קריטיות (כמו רכב או תעופה).
  • CERT C: מתמקד באבטחת סייבר (Security). הוא מזהה דפוסי קוד שניתן לנצל (Exploit) כדי להחדיר קוד זדוני או לגרום לקריסה מכוונת.
    בקורס נלמד כיצד לשלב בין השניים כדי לקבל קוד שהוא גם בטוח וגם חסין לפריצות.

ש: מדוע הקצאת זיכרון דינמית (malloc/free) נחשבת למסוכנת במערכות Embedded?

ת: במערכות זמן אמת, שימוש ב-Heap מעלה שלוש בעיות מרכזיות:

  1. דטרמיניזם: פעולת ההקצאה עלולה לקחת זמן משתנה.
  2. פרגמנטציה (קיטוע): הזיכרון עלול להתמלא ב"חורים" שימנעו הקצאות חדשות לאורך זמן.
  3. אבטחה: שגיאות כמו Use-After-Free או Double Free הן מקור קלאסי לפרצות.
    בקורס נלמד חלופות כמו Static Allocation ו-Memory Pools המבטיחות יציבות ואבטחה.

ש: האם שימוש ב-C++ הופך את המערכת לפחות בטוחה בהשוואה ל-C?

ת: ממש לא, אם יודעים באילו כלים להשתמש. מצד אחד, פיצ'רים כמו Exception Handling או Dynamic Cast עלולים להיות בעייתיים במערכות Embedded מסוימות. מצד שני, מנגנונים כמו RAII, Smart Pointers ו-Templates מאפשרים למנוע זליגות זיכרון ושגיאות לוגיות כבר בזמן הקומפילציה – מה שהופך את הקוד למאובטח הרבה יותר מקוד C מסורתי.

ש: מהו "Undefined Behaviour" ולמה זה קריטי למפתחי Embedded?

ת: זהו מצב שבו תקן השפה לא מגדיר מה אמור לקרות (למשל: חריגה מגבולות מערך או Integer Overflow). במקרה כזה, הקומפילר יכול לבצע אופטימיזציה ש"תשבור" את הלוגיקה של המפתח. תוקפים מנצלים בדיוק את המקומות האלו כדי לשנות את זרימת התוכנית. בקורס נלמד לזהות מצבים אלו בעזרת כלי אנליזה סטטיים.

ש: איך הקורס מתייחס לעבודה עם מערכת הפעלה (RTOS)?

ת: הקורס סוקר דפוסי עבודה מאובטחים מול RTOS, בדגש על Concurrency. נלמד איך למנוע Race Conditions ו-Priority Inversion שיכולים לשבש את מנגנוני האבטחה של המערכת, ואיך להשתמש נכון ב-Atomic Operations כדי להגן על משאבים משותפים.

הפרק הבא הוא "מדריך מהיר: חמשת המוקשים הנפוצים בקוד C/C++". המטרה של הפרק הזה בדף התמיכה היא לתת "ערך מוסף" מיידי – להראות לקורא דוגמאות קונקרטיות לבעיות שהוא עלול לפגוש ביומיום ואיך הקורס מלמד לפתור אותן.

 

למה אבטחת קוד ב-Embedded שונה מהותית מ-IT

במערכות IT, כשל תוכנה לרוב מתבטא באובדן נתונים, פגיעה בפרטיות או השבתת שירות. במערכות Embedded, הקוד מחובר ישירות לעולם הפיזי.

משמעות של Buffer Overflow בדרייבר של בלמים אינה קריסת אפליקציה — אלא פעולה פיזית לא צפויה.
משמעות של Race Condition במערכת רפואית יכולה להיות מינון שגוי.
משמעות של Undefined Behavior במערכת תעשייתית יכולה להיות נזק לציוד יקר.

ההבדל אינו רק ברמת הסיכון, אלא גם באופי הסביבה:

  • אין מערכת הפעלה מלאה שמגנה עליך
  • אין תמיד MMU
  • יש אילוצי זמן אמת
  • יש מגבלות זיכרון
  • ויש צורך בדטרמיניזם

כל אלו הופכים את שפת C — עם החופש שהיא נותנת — לכלי מסוכן אם לא משתמשים בו בצורה ממושמעת.

 

שאלה: למה גם מפתחים מנוסים ב-C עושים טעויות קריטיות?

התשובה הקצרה: בגלל הפער בין מה שהקוד “נראה” שעושה לבין מה שהקומפיילר והחומרה באמת עושים.

התשובה המלאה מורכבת משלושה גורמים:

1. Undefined Behavior אינו “מקרה קצה” — הוא מרכזי

רבים מתייחסים ל-Undefined Behavior כאל משהו נדיר. בפועל, הוא מופיע בדפוסים יומיומיים:

  • גישה מחוץ לגבולות מערך
  • שימוש בזיכרון משוחרר
  • המרות טיפוסים מסוכנות
  • Integer overflow לא מבוקר

הבעיה אינה רק שהקוד שגוי — אלא שהתוצאה אינה מוגדרת כלל. כלומר, אותו קוד יכול להתנהג אחרת בין קומפיילרים, בין אופטימיזציות, או בין גרסאות.

2. מודל הזיכרון אינו אינטואיטיבי

Stack, Heap, Static, Registers — כולם מתנהגים אחרת.
כאשר מוסיפים Interrupts או RTOS, התמונה מסתבכת עוד יותר.

3. אמון יתר בקומפיילר

הקומפיילר מניח שהקוד חוקי. אם הוא מזהה Undefined Behavior, הוא רשאי לבצע אופטימיזציות שמפרקות את ההיגיון של המפתח.

שאלה: מהו Buffer Overflow וכיצד מטפלים בו נכון ב-Embedded?

Buffer Overflow הוא אחת הבעיות הבסיסיות והנפוצות ביותר.

דוגמה קלאסית:

#include <string.h>

 

void process_input(const char *input) {

    char buffer[16];

    strcpy(buffer, input);

}

 

הבעיה כאן ברורה: אין בדיקה של אורך הקלט. אם input ארוך מ-16 בתים, נכתב מעבר לגבולות ה-buffer.

למה זה קריטי ב-Embedded?

  • אין הגנות של מערכת הפעלה
  • אין Address Space Isolation
  • כתיבה מעבר לגבול יכולה לשנות משתנים אחרים, מצביעים או אפילו כתובת חזרה

איך מטפלים נכון?

לא מספיק להחליף פונקציה — צריך לשנות גישה.

#include <string.h>

 

void process_input(const char *input) {

    char buffer[16];

    size_t len = strnlen(input, sizeof(buffer) - 1);

    memcpy(buffer, input, len);

    buffer[len] = '';

}

 

עקרונות חשובים:

  • תמיד שליטה באורך
  • העדפת פונקציות שמקבלות size
  • הגדרת חוזים ברורים לפונקציות

בנוסף, בסביבות מתקדמות יותר:

  • שימוש ב-Stack Canaries
  • בדיקות קומפילציה עם -fstack-protector
  • Static Analysis

שאלה: מה זה Static Analysis ולמה הוא קריטי?

Static Analysis הוא תהליך של ניתוח קוד ללא הרצה.

הוא מזהה:

  • גישות מסוכנות לזיכרון
  • שימוש במשתנים לא מאותחלים
  • דליפות זיכרון
  • בעיות תחרות (race conditions)

למה זה חשוב במיוחד ב-Embedded?

כי:

  • קשה לשחזר באגים בזמן אמת
  • אין תמיד לוגים
  • לא תמיד ניתן להריץ debugger על target

איך משלבים ב-CI/CD?

תהליך נכון נראה כך:

  1. כל commit מפעיל ניתוח סטטי
  2. כשל בניתוח חוסם merge
  3. דוחות נשמרים ומנותחים לאורך זמן

כלים נפוצים:

  • Clang-Tidy
  • Cppcheck
  • Coverity (בתעשייה)

טעות נפוצה:

להריץ Static Analysis רק “לפני שחרור”.
בפועל, צריך לשלב אותו כחלק מהפיתוח השוטף.

שאלה: מה ההבדל בין MISRA C ל-CERT C?

שני הסטנדרטים עוסקים בכתיבת קוד בטוח, אך הם שונים בגישה.

MISRA C

  • נועד לתעשיות קריטיות (רכב, תעופה)
  • מגדיר חוקים נוקשים מאוד
  • מגביל שימוש בתכונות מסוימות של השפה

לדוגמה:

  • איסור על רקורסיה
  • הגבלות על casting
  • דרישות ברורות ל-typing

CERT C

  • מבוסס על חולשות אבטחה אמיתיות
  • פחות נוקשה
  • יותר פרקטי לסביבות מגוונות

מתי להשתמש במה?

  • מערכות Safety-Critical → MISRA
  • מערכות כלליות עם דגש אבטחה → CERT

בפועל, בהרבה ארגונים משלבים בין השניים.

שאלה: האם C++ מתאים ל-Embedded מאובטח?

זו שאלה שחוזרת בכל מחזור.

התשובה: כן — אבל רק אם משתמשים בו נכון.

למה C++ נתפס כמסוכן?

  • Exceptions
  • Dynamic Allocation
  • RTTI
  • Templates מורכבים

כל אלו יכולים לפגוע בדטרמיניזם ובביצועים.

איך משתמשים נכון?

גישה נפוצה היא Safe Subset של C++:

  • ללא exceptions
  • ללא RTTI
  • שליטה על allocation
  • שימוש ב-RAII

דוגמה:

#include <array>

 

class SafeBuffer {

public:

    explicit SafeBuffer(size_t size) : size_(size) {}

 

    bool write(size_t index, char value) {

        if (index >= size_) return false;

        data_[index] = value;

        return true;

    }

 

private:

    std::array<char, 32> data_;

    size_t size_;

};

 

הגישה כאן:

  • encapsulation
  • בדיקות גבולות
  • מניעת גישה ישירה לזיכרון

שאלה: מהם המוקשים הנפוצים ביותר בקוד Embedded?

1. Use After Free

גישה לזיכרון ששוחרר.
במערכות ללא הגנות — זה עלול לגרום להתנהגות אקראית לחלוטין.

2. Integer Overflow

במיוחד עם טיפוסים קטנים (uint8_t, uint16_t).
עלול לגרום לחישובים שגויים או לבעיות לוגיות.

3. Race Conditions

במערכות RTOS או עם interrupts.

לדוגמה:

  • משתנה גלובלי נכתב ע"י interrupt ונקרא ע"י thread
  • ללא הגנה → מצב לא עקבי

4. Null Pointer Dereference

עדיין אחת הסיבות הנפוצות לקריסות.

5. Improper Initialization

משתנים לא מאותחלים → ערכים אקראיים

שאלה: איך ניגשים לאבטחה כבעיה מערכתית ולא נקודתית?

אבטחה אינה פונקציה אחת — היא תכונה של המערכת כולה.

עקרונות שאני מדגיש:

1. Design First

לא מוסיפים אבטחה בסוף — מתכננים מראש:

  • מי שולט בזיכרון
  • מי אחראי על סנכרון
  • איך מוגדרים boundaries

2. Determinism

קוד חייב להיות צפוי:

  • ללא side effects לא מבוקרים
  • ללא הקצאות דינמיות בזמן קריטי

3. Minimalism

פחות קוד = פחות שטח תקיפה

4. Visibility

יכולת לראות מה קורה:

  • לוגים
  • asserts
  • בדיקות

שאלה: איך נראה תהליך Refactoring לקוד לא בטוח?

במעבדות הקורס אנחנו עובדים על קוד “מלוכלך”.

התהליך כולל:

  1. זיהוי נקודות סיכון
  2. סימון Undefined Behavior
  3. הכנסת בדיקות גבולות
  4. הפרדת אחריות
  5. התאמה לסטנדרט (MISRA / CERT)

המטרה אינה רק “לתקן באג” — אלא לשנות את הארכיטקטורה.

שאלה: איך Dynamic Analysis משלים את התמונה?

בניגוד ל-Static Analysis, כאן הקוד רץ.

כלים כמו:

  • AddressSanitizer
  • ThreadSanitizer

מאפשרים לזהות:

  • גישות לא חוקיות לזיכרון
  • race conditions
  • memory leaks

יתרון:

מזהים בעיות שלא תמיד נראות בניתוח סטטי

חיסרון:

דורש הרצה — לא תמיד אפשרי על target אמיתי

לכן משלבים:

  • בדיקות על host
  • סימולציה
  • בדיקות יחידה

מה הערך המוסף בקורס אבטחת קוד למערכות משובצות מחשב

 

הסמכות וסטנדרטים בינלאומיים

כתיבת קוד מאובטח למערכות Embedded היא לא רק המלצה; היא דרישה לעמידה בתקני איכות ורגולציה מחמירים. הקורס נועד ליישר קו עם הסטנדרטים המובילים בתעשייה, כדי שהפרויקטים שלכם יהיו מוכנים לאישור (Certification).

הכרות עמוקה עם תקן MISRA

  • MISRA-C:2012 / MISRA C++:2023: תקנים אלו מגדירים תת-קבוצה (Subset) בטוחה של שפות C/C++, על ידי פסילת מבני קוד מסוכנים. בקורס נלמד את ה-Rationale מאחורי החוקים הקריטיים וכיצד להשתמש בכלי אנליזה סטטיים כדי לוודא עמידה בהם (Static Analysis Rule Enforcement).

  • חשיבות לתעשייה: עמידה בתקן MISRA היא חובה עבור ספקי תוכנה לתעשיות הרכב (ISO 26262), הרפואה (IEC 62304) והתעופה.

אבטחת סייבר עם CERT C/C++

  • CERT (Computer Emergency Response Team): בעוד ש-MISRA מתמקד בבטיחות ואמינות, תקן CERT C מזהה דפוסי קוד שניתן לנצל להתקפות סייבר. בקורס נלמד כיצד לזהות ולתקן פרצות המוגדרות ב-CERT C Top 10, כגון Buffer Overflow, Format String ומצבי מרוץ.

הכנה לרגולציות עתידיות

  • הקורס מספק את התשתית הטכנית לעמידה ברגולציות אבטחת סייבר חדשות, כגון ה-Cyber Resilience Act האירופי, המחייב יצרני מכשירים מחוברים (IoT) להוכיח כי התוכנה שלהם מאובטחת לאורך כל מחזור החיים שלה.

 תמיכה לוגיסטית וליווי

אנחנו מבינים שלמידת חומר טכני מורכב דורשת יותר מהרצאות פרונטליות. לכן, הקורס מציע מעטפת תמיכה מקיפה:

ליווי במהלך המעבדות

  • במהלך המעבדות (Labs), מדריכים מנוסים יהיו זמינים לתמיכה בזמן אמת, כדי לעזור לכם לפתור בעיות, להריץ את הבדיקות ולבצע את ה-Refactoring בהצלחה.

גישה לחומרים ולהקלטות

  • כל חומרי הלימוד – כולל מצגות, דוגמאות קוד, וחוברות המעבדה – יהיו זמינים לכם דרך פורטל הלמידה.

  • במידה ותפספסו שיעור, או שתרצו לחזור על נושא מורכב, תוכלו לצפות בהקלטות השיעורים בזמנכם החופשי.

ייעוץ טכני לפני ההרשמה

  • אינכם בטוחים אם הרקע הטכני שלכם מתאים? צוות היועצים הטכניים שלנו ישמח לשוחח איתכם, להבין את הניסיון שלכם ולהמליץ על מסלול הלימודים המתאים ביותר עבורכם.


תחומי לימוד הכי מבוקשים בהייטק בשנת 2026

© כל הזכויות שמורות Real Time Group