שְׁאֵלָה:
GAS / x86 פירק רישום gs חשוף כהוראה, האם זה באג?
perror
2013-08-23 20:01:18 UTC
view on stackexchange narkive permalink

נתקלתי בהוראה x86-32 מוזרה (opcode 0x65 ) מפוענחת על ידי objdump כ- gs (לא % gs קוד> אבל gs ). מצאתי אותו בזמן טאטא ליניארי מלא של בינארי ( objdump -D ), ולכן הפענוח בוודאי לא נכון. אבל, עדיין, objdump לא פענח אותו כהוראה (רע) , אז זה אומר שאפשר להיתקל בזה ואני רוצה לדעת מה זה אומר.

הנה דוגמה להוראה זו:

  080484fc <_IO_stdin_used>: 80484fc: 01 00 add% eax, (% eax) 80484fe: 02 00 add (% eax), % al 8048500: 48 dec% eax 8048501: 65 גרם < ========================= כאן !!! 8048502: 6c insb (% dx),% es: (% edi) 8048503: 6c insb (% dx),% es: (% edi) 8048504: 6f outsl% ds: (% esi), (% dx) 8048505: 20 57 6f ו-% dl, 0x6f (% edi) 8048508: 72 6c jb 8048576 <_IO_stdin_used + 0x7a> 804850a: 64 21 0a ו-% ecx,% fs: (% edx) 804850d: 00 44 6f 64 add%%, edi,% ebp, 2) 8048511: 67 65 20 54 68 and% dl,% gs: 0x68 (% si) 8048516: 69 .byte 0x69 8048517: 73 21 jae 804853a <_IO_stdin_used + 0x3e>  
שים לב כי חיפוש ההוראה הזו באינטרנט הוא די קשה בגלל הרישום % gs המסווה את כל שאר הלהיטים האפשריים.

אז האם מדובר ב"הוראות "אמיתיות? או שמא מדובר בתקלה המיוצרת על ידי גז ?

הממ, נראה שזה באג מקריני השיניים של GNU ... הקוד הקוד "0x65" תואם למעשה לקידומת המתאימה ל-% gs: (mem_ref) ". אבל הנה, נראה שמנתח 'libopcodes' מפרש את זה בטעות ו * שוכח * לפרש את הדברים הבאים בהמשך כהפניה לזיכרון ... (יכול להיות שאני טועה, אבל אנסה לענות מתי אדע יותר על כל זה) .
על פי המדריכים של אינטל, ההוראות "ins *" * מתעלמות * מקדמות מקטעות ומשתמשות תמיד ב-% es.
אז, זה אומר שזה בגלל שיש לך את קוד הקודים '0x65' ואחריו הוראות 'ins' שהמפענח טועה ... אני מבין, זה מעניין. תודה.
קצת מאוחר, אבל: המפענח מבין את זה "לא בסדר" מכיוון שאתה מפרק מחרוזת טקסט * אפסית. אינך יכול לקבל החלטות על פירוק "טוב" או "רע" תוך הזנתו עם קלט רע. (מצחיק: המחרוזת הזו כל כך ידועה שקיבלתי אותה אחרי שפענחתי את שלוש התווים הראשונים.)
אחד תשובה:
Igor Skochinsky
2013-08-23 20:36:07 UTC
view on stackexchange narkive permalink

בקפדנות זו לא הוראה. זה הקידומת לעקיפת קטע (קידומות נחשבות לחלק מההוראה).

מרבית הגישות לזיכרון משתמשות בברירת הקטעים ב DS למעט אלה הכרוכות ב ESP או EBP רישום (הם כברירת מחדל ל- SS ) וכמה הוראות "מחרוזות" ( movs , scas וכו ') . קידומות לעקיפת פלחים מאפשרות לך להשתמש בבורר פלחים אחר כדי לגשת לנתונים שלך. לְמָשָׁל. בזמנים של DOS בדרך כלל נעשה שימוש במעקף CS כדי לגשת לנתונים המאוחסנים בקטע הקוד (כגון טבלאות קפיצה):

  seg001: 00EA shl bx, 1; SWITCHseg001: 00EC jmp cs: off_13158 [bx]; קפיצה למתג ... seg001: 0588 off_13158 dw offset loc_12DD7; נתונים XREF: _main + E6rseg001: 0588 dw offset loc_12DE5; טבלת קפיצה להצהרות מתגeg001: 0588 dw offset loc_12DE5seg001: 0588 dw offset loc_12DE5  

ה- 80386 הוסיף שני רישומי קטעים נוספים ( GS ו- FS ) והקידומות המתאימות.

מכיוון שהקידומת GS אינה משפיעה בפועל על ההוראה הבאה ( insb ) בקוד שנחתם לעיל, GAS בחר להדפסתו בשורה נפרדת.

בחלק מההוראות הבאות תוכלו לראות כיצד זה משפיע על הפירוק:

  64 21 0a -> ו-% ecx, % fs: (% edx) ^^ ^^^ 67 65 20 54 68 -> ו-% dl,% gs: 0x68 (% si) ^^ ^^^  

BTW, 67 הוא קידומת נוספת, הפעם עקיפת גודל הכתובת . זו הסיבה שההוראה משתמשת ברישום SI של 16 סיביות ולא ב ESI המלא.

זה די מסודר וברור (כמו תמיד, איגור!). אך האם היית מחשיב זאת כהתנהגות (באג) לא רצויה של 'גז'?
ובכן, אני לא יודע. אתה יכול להתווכח על כך בשני הכיוונים. זה לא כמו ש- GAS מתקשה נגד שטויות / קוד מעורפל, אתה צריך להיות שמח שהוא לא התרסק לפחות :)
נ.ב. לפעמים זה הגיוני לשים קידומת בהוראת פסאודו נפרדת, ראה למשל. [קטע זה] (http://pastie.org/pastes/8263242/text) מאיזה libc ישן.
אם אני מבין היטב את הדוגמה שלך, הסמל ממוקם ** אחרי ** קידומת ההוראה ??? זה אומר שתלוי אם אנחנו באים מהבלוק לפני כן או אם אנחנו קופצים אליו דרך הסמל, הסמנטיקה לא לגמרי זהה (האחד אטומי והשני לא). אני בהחלט שונא את x86, זה גורם לי לכאבי ראש! :-)


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 3.0 עליו הוא מופץ.
Loading...