לדלג לתוכן

7.1 הקדמה להנדסה הפוכה תרגול

תרגול - הקדמה להנדסה הפוכה

תרגיל 1 - זיהוי קובץ ומחרוזות

הריצו את הפקודות הבאות על הקובץ /bin/ls:

א. השתמשו בפקודת file כדי לזהות את סוג הקובץ. ענו על השאלות:
- האם זה קובץ 32 ביט או 64 ביט?
- האם הוא מקושר סטטית או דינמית?
- האם הוא stripped או לא?

ב. השתמשו בפקודת strings /bin/ls | head -50 כדי לראות את 50 המחרוזות הראשונות. האם אתם מזהים מחרוזות שעוזרות להבין מה התוכנית עושה?

ג. השתמשו בפקודת strings /bin/ls | wc -l כדי לספור כמה מחרוזות יש בקובץ. השוו עם strings /bin/cat | wc -l. מי מכיל יותר מחרוזות ומה זה אומר?


תרגיל 2 - זיהוי קריאות לפונקציות בדיסאסמבלי

כתבו תוכנית C פשוטה שמדפיסה "Hello World", מקצה זיכרון עם malloc, כותבת אליו, ומשחררת אותו. קמפלו אותה בלי debugging symbols (בלי -g):

gcc -o hello hello.c

א. השתמשו ב-objdump -d -M intel hello כדי לעשות דיסאסמבלי. מצאו את הפונקציה main.

ב. זהו את כל הקריאות (call) שmain מבצע. לאילו פונקציות הוא קורא? (רמז: חפשו את @plt אחרי שם הפונקציה)

ג. עבור כל קריאה, הסתכלו על ההוראות שלפני ה-call וזהו את הארגומנטים. זכרו: הארגומנט הראשון ב-rdi, השני ב-rsi, השלישי ב-rdx.


תרגיל 3 - מציאת מחרוזת מוסתרת

כתבו תוכנית C שמכילה שתי פונקציות:
- פונקציית visible_func שמדפיסה "This is visible"
- פונקציית hidden_func שמדפיסה "You found the secret!" (הפונקציה הזו לא נקראת מ-main)

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

א. למצוא את כל הפונקציות בקובץ עם nm או objdump -t.

ב. למצוא את המחרוזת "secret" עם strings.

ג. להבין באיזו פונקציה המחרוזת הזו נמצאת - השתמשו ב-objdump -d -M intel כדי לראות את הדיסאסמבלי של hidden_func ולזהות את הקריאה ל-puts עם המחרוזת.


תרגיל 4 - סיור ב-GDB בלי קוד מקור

כתבו תוכנית C שמחשבת עצרת (factorial) של מספר שמועבר כארגומנט משורת הפקודה. קמפלו בלי הדגל -g:

gcc -o factorial factorial.c

א. פתחו את התוכנית ב-GDB:

gdb ./factorial

ב. הגדירו breakpoint ב-main ועשו run 5 (שולח "5" כארגומנט). מה קורה?

ג. השתמשו ב-disassemble main כדי לראות את האסמבלי. זהו:
- איפה הקריאה ל-atoi (המרה ממחרוזת למספר)?
- איפה הקריאה לפונקציית החישוב?
- איפה הקריאה ל-printf?

ד. הגדירו breakpoint בפונקציית חישוב העצרת. עשו run 5 וצעדו עם nexti כמה צעדים. בדקו את ערכי האוגרים עם info registers. האם אתם יכולים לעקוב אחרי הלוגיקה?


תרגיל 5 - ניתוח עם strace ו-ltrace

א. הריצו את הפקודה הבאה ובחנו את הפלט:

strace /bin/echo "hello world" 2>&1 | head -30

מצאו את קריאת המערכת write - מה הfile descriptor שהיא כותבת אליו? מה המחרוזת שהיא כותבת? (רמז: fd 1 הוא stdout, כזכור מפרק 5.5)

ב. הריצו strace על תוכנית ה-factorial שלכם מתרגיל 4 וזהו:
- אילו קבצים הליבה (libc) נטענים בהתחלה?
- איזו קריאת מערכת מדפיסה את התוצאה?

ג. הריצו ltrace על תוכנית ה-factorial ובחנו:
- אילו פונקציות libc נקראות?
- מה הארגומנטים וערכי ההחזרה שלהן?

ד. השוו את הפלט של strace ו-ltrace. מה ההבדל ביניהם? אילו פרטים כל אחד חושף שהשני לא?