LoudBugFix-הסברים

עמוד

הדיון הזה מכיל 0 תגובות, ויש לו משתתף 1, והוא עודכן לאחרונה ע״י  adi לפני 1 שנה, 7 חודשים.

מוצגות 1 תגובות (מתוך 1 סה״כ)
  • מאת
    תגובות
  • #83321

    adi
    משתתף

    שלום, חשבנו לפרט פה על הרעיונות של השורד שלנו, מכיוון ולא היה מספיק זמן ביום התחרות להתעמק בו.
    קצת על השורד
    הרעיון העיקרי מאחורי השורד הוא הפצצה חזקה יותר מהפצצה רגילה- אם אנחנו פוגעים בשורד מסויים, אנחנו גורמים לו להרוג את השורד הנוסף שבקבוצה שלו.
    הדרך שאנו עשינו זאת היא באמצעות כתיבה לאזור המשותף בזיכרון שממנו השורדים מעתיקים קוד לזירה. אנו דורסים את הקוד שבזיכרון ומחליפים אותו בדברים לא חוקיים. וכך אנו בעצם הורגים את שניהם.
    מכיוון שאזורים אלו "מוגנים", לא ניתן לגשת אליהם, אך שורדים מאותה הקבוצה יכולים. לכן, כאשר אנחנו משתלטים על שורד אנחנו יכולים להשתמש בו לכתוב לאזור הזה לפי רצוננו.
    ההנחה העומדת מאחורי שיטה זו היא שהקבוצה משתמשת באסטרטגיה פופולארית למדי ומעתיקה קוד לאזור המוגן שלה באמצעות הפקודה Movsw, ולאחר מכן מחליפה את הסגמנטים ES וDS כך שmovsw יעתיק קוד מהאזור המוגן לזירה. לכן, אם נפגע בשורד מסויים, בין אם נגרום לו לכתוב ל DS באמצעות פקודות כמו mov [si],bl או אם נחזיר לES את הערך המקורי שלו באמצעות משהו כמו push ds pop es ואז נשתמש בstosw כדי למלא ג'אנק בES, אנחנו הצלחנו לפגוע לו באזור המוגן.
    ניתן לממש עיקרון זה כמעט על כל שורד באופן יעיל, לדוגמה להחליף את ערך ההפצצה של השורד לערך שגורם לשורד שנפגע לכתוב בES (מומלץ רק אם השורד מפציץ במרווחים- שכן ערך ההפצצה חוקי אך לא יוצר רצף של פקודות חוקיות ובכך מונע מהשורד שנפגע למות- הזירה מאותחלת ל0xcccc) או לדוגמה להשתמש בעקרון זה על מנת להשתלט על שורדים באופן מהיר יותר (רלוונטי לFSM או כל שורד שמשתלט על שורדים). ובכל זאת, הדרך הכי יעילה בעינינו היא להשתמש בrep movsw על מנת "להפציץ" קוד מES ולאחר מכן לאתחל את עצמך (באופן דומה יחסית לFSM). כמו כן, מומלץ לעשות זאת כאשר הdirection flag דולק על מנת שכיוון ההעתקה יהיה הפוך.
    אנו חושבים שזו הדרך היעילה ביותר מהסיבות הבאות:
    ראשית, Rep movsw מייצר הפצצה מהירה מאוד בגלל שהפעולה היחידה שאתה עושה רוב הזמן זה להפציץ במהירות של 2 בתים לאופקוד.
    שנית, ניתן לבחור באופן חופשי את ערכי ההפצצה. לדוגמה, לולאת ההפצצה שלנו הייתה jmp short 0xe
    עד שהגענו לרצף של 15 נופים, ולאחר אלו היה קטע קוד שגורם למי שמריץ אותו לכתוב לES שלו 0xcccc 512 פעמים (עד שES מתמלא).
    בנוסף לכך, זוהי דרך מאוד יעילה להשתמש בזומבים, מכיוון וניתן לגרום לזומבים לעבוד באותו אופן- דבר שלא אפשרי עם שורדים מורכבים אחרים, ואף ניתן להשתמש ברגיסטר פנוי כדי להרוג את הזומבים לפני סוף המשחק (חשוב מאוד לציין גם שאף 20 שורדים כאלו לא יהרגו זה את זה במידה והם רצים במרווח מסויים, פשוט כי הם מסונכרנים מאוד טוב ולכן הם רק יכולים לעזור לניצחונך).
    חשוב לציין שהסיבה להשתמש בdirection flag היא שרוב השורדים מעתיקים קוד ומתקדמים בזיכרון. לכן, אם לדוגמה שורד מסויים מפציץ במהירות 2 בתים לאופקוד, ומנסה לפגוע בשורד המתקדם במהירות של בית לאופקוד, אם הוא מפציץ בלי הdirection flag מהירות ההפצצה שלו ביחס לשורד זה תהיה בית לאופקוד. לעומת זאת, אם הוא מפציץ עם הdirection flag מהירות ההפצצה שלו תהיה שלושה בתים לאופקוד.
    בנוסף לכך, הסיבה שהפצצנו jmp short רוב הזמן היא כי אנחנו רוצים לוודא שאם מישהו נפגע מהפצצה שלנו, כמעט בטוח שהוא יריץ את הקוד שלנו במלואו (אם סתם היינו מעתיקים הרבה פעמים את הקוד לתוך ES זה גם היה לוקח הרבה זמן וגם היינו עלולים לפגוע במישהו כך שרק חלק מהפקודות יורצו ואז זה לא יעבוד).
    בהתחלה הפצצנו ערך שלא הורג אך כותב לES (Mov[si],bl) אבל אז בגלל שרצינו לשלב את השורד עם סיילנט ארור (מפורט בפסקה מתחת לזאת), נאלצנו לשנות את ההפצצה למשהו שלא פוגע, אבל רצינו לוודא שהדבר ייקח מינימום זמן ושכמות הבתים הפגיעים לא תהיה גדולה מדי. לכן בחרנו להפציץ jmp short שאחריו שמנו מספר מתאים של nop כך שלא נדלג על הקוד שלנו.
    זוג שורדים זהים לשורד שתיארנו מנצחים כמעט את כל השורדים מכל השנים, כולל SilentError של שנה שעברה. הסיבה לניצחונות מול סיילנט ארור היא שהשורד מפציץ מאוד מהר ומכיוון שהמלכודת התחתונה של סיילנט ארור יחסית רחוקה ממנו, יוצא שסביר יותר ששורד זה יפגע בסיילנט ארור מאשר שסיילנט ארור "יברח" מהפצצות שלו (דבר זה היה עובד עם שורדים אחרים כמו FSM לדוגמה אם היו מפציצים מהר יותר, אך זה לא אפשרי אלא אם הופכים את הdirection flag, אבל אז לא ניתן להשתמש בFSM )
    למרות זאת, היו שורדים שהיו כמעט חסינים אלינו לחלוטין כמו פוביה וapocalypse. לכן, רצינו לשלב את סיילנט ארור עם השורד שלנו, אך הייתה בעיה לגרום להם לשרוד והדבר פגע בסיכויי הניצחון שלנו מספיק על מנת שזה לא יהיה שווה את זה.
    לכן, הוספנו לסיילנט ארור שבקבוצה שלנו הגנה- אנו כתבנו למיקום מסויים באזור המוגן שלו ערך מסויים. במהלך ההפצצה של השורד שלנו כל שורד שנפגע בודק האם ערך זה מופיע במיקום המסויים בזיכרון שלו. במידה וכן, אנחנו מאתחלים את סיילנט ארור שנפגע (לא סביר אם זה לא השורד שלנו בצורה קיצונית, מכיוון ואנחנו היחידים שיודעים את המיקום ואת הערך שלו. בנוסף לכך, האתחול כנראה לא יתאים לכל שורד שאינו סיילנט ארור). בנוסף לזה, גרמנו לשניהם להתחיל ממרחק התחלתי קבוע שממנו הם לא יפגעו זה בזה ממנו (בהנחה שהמלכודות של סיילנט ארור לא נפגעות אלא אם השורד שלנו פגע בהן, ולכן הדבר לא עובד במאה אחוז אך עוזר).
    בסופו של דבר, הגענו למצב שהשורד השני שלנו כמעט לעולם לא הורג את סיילנט ארור, וסיילנט ארור כמעט ולא הורג את השורד שלנו. בכך בעצם הרווחנו את היתרונות של הפצצה מהירה וחזקה מהשורד שלנו, כמו גם ניצחון מול שורדים חזקים כמו סיילנט ארור, וגם הרווחנו את ההגנה מהפצצות שיש לסיילנט ארור.
    נהנינו מאוד מהתחרות ושמחנו להשתתף בה, זו הייתה הפעם השנייה שלנו (בפעם הראשונה בעיקר ניסינו ללמוד ולהשתפר ולא היינו טובים במיוחד), עבדנו על השורד הזה באזור החצי שנה פחות או יותר, ואנחנו מקווים שהקוד שכתבנו והרעיונות שחידשנו יעזרו לשפר את התחרות והאתגר בה. למרות שלא נשתתף שנה הבאה, נשמח לעזור למי שיצטרך, וניתן לפנות אלינו דרך המיילים שלנו
    adi@trugman.com
    itaityro@gmail.com
    אנחנו גם נמליץ לקרוא את הקוד של SilentError ושל FSM, שניהם נמצאים בפורום.
    מקווים שנהניתם, עדי ואיתי מהקבוצה LoudBugFix.
    נ.ב הסיבה לשם היא שאנחנו חברים של אלה שכתבו את Silent Error ומכיוון ותכננו לנצח את השורד שלהם, חשבנו שזה יהיה משעשע לקרוא לעצמנו בשם הפוך משלהם.

מוצגות 1 תגובות (מתוך 1 סה״כ)

יש להתחבר למערכת על מנת להגיב.