שְׁאֵלָה:
Ida Pro: ביטוי אופרנד מורכב עם ניתוח של Idapython
langlauf.io
2015-06-01 19:00:03 UTC
view on stackexchange narkive permalink

אמור בהתחשב בשורה הבאה ב- Ida Pro:

  mov [rsp + 3F8h + var_3F8], 0  

כיצד אוכל לנתח ולגשת אל פריטים בתוך [] ? מה ניסיתי:

  • idc.GetOpnd (addr, n) # מחזיר מחרוזת ' [rsp + 3F8h + var_3F8] '
  • idc.GetOperandValue (addr, n) # מחזירה 4 , שמוסבר ב קובץ idc.py כדלקמן

def GetOperandValue (ea, n): "" "
קבל מספר המשמש באופרה

פונקציה זו מחזירה מספר מיידי המשמש באופראנד

@param ea: כתובת ליניארית של הוראה @param n: מספר האופראנד

@ החזרה:

ערך אופרנד הוא ערך מיידי => ערך מיידי

אופרנד הוא בעל תזוזה => עקירה

אופראנד הוא זיכרון ישיר ref => כתובת זיכרון

אופרנד הוא רישום => מספר רישום

אופרנד הוא ביטוי רישום => מספר ביטוי

אחרת => -1 "" "

כיצד אוכל לגשת לאלמנטים של 'הביטוי', כלומר rsp , 3F8h ו- var_3F8 ? אני מחפש משהו כזה:

  my_op_phrase = idc.ParseOperandPhrase (ea, n) my_op_phrase [0] # -> 'rsp'my_op_phrase [0] .type # -> idaapi.o_regm_o [1] # -> 0x3F8hmy_op_phrase [1] .type # -> idaapi.o_immmy_op_phrase [2] # -> 'var_3F8' ...  

האם זה בכלל אפשרי או האם אני לא בסדר? / p>

שתיים תשובות:
Guntram Blohm supports Monica
2015-06-01 19:17:14 UTC
view on stackexchange narkive permalink

שים לב שהוראות ההרכבה המקוריות היו כנראה mov [rsp + 4], 0 (*). זו הסיבה ש idc.GetOperandValue מחזיר 4.

במיוחד עם מהדרים ישנים יותר, שהשתמשו הרבה ב push ו- pop , הערך של rsp משתנה באופן פרוע במהלך ביצוע הפונקציה. מה ש esp + 8 עכשיו יהיה esp + 12 לאחר דחיפה; מה יהיה rsp + 8 עכשיו יהיה rsp אחרי פופ. לכן, בזמן קריאת פיסת קוד הרכבה (רגיל) קשה מאוד לעקוב אחר מיקום הערימה שמגיע אליה מתי.

(זה השתפר לאחרונה; x64 משתמשת ברשומות כדי להעביר פרמטרים כך שהקוד לא 't לדחוף ו- pop עוד כמה זמן, ומהדרים כמו gcc מפנים מספיק מקום בערימה ומכניסים ישירות פרמטרים לכתובות ביחס ל- esp אפילו ב 32 סיביות, אז esp / rsp כבר לא משתנים כל כך הרבה. אבל בכל זאת, יש הרבה קוד ישן להפוך.)

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

mov [rsp + 8], raxsub rsp, 128mov [rsp + 136], rbxpush rcxmov [rsp + 144], rdx

הוא ניגש לאותה כתובת זיכרון בכל מקרה. אידה ממירה את זה ל

  mov [rsp + 0 + var_8], raxsub rsp, 128mov [rsp + 128 + var_8], rbxpush rcxmov [rsp + 136 + var_8], rdx  

עם זאת, שינויים אלה מוצגים בלבד, הם אינם משנים את הבינארי שלך! השגת אופרנדים עדיין תחזיר את 8 , 136 ו- 144 , ולא הערכים ש- ida מציג לך.

אם ברצונך לנתח זאת באופן אוטומטי, תוכל או לעקוב אחר קיזוז מצביע הערימה בעצמך, ולהתאים את התוצאה של GetOperandValue בהתאם, או יהיה עליך להשתמש בפונקציות מחרוזת הפיתון בפלט של GetOpnd , לזרוק את החלק האמצעי ולהשוות את החלק הנכון (שמות המשתנים).

(*) שנראה קצת מוזר עכשיו אני חושב על זה, מכיוון שברור שאתה משתמש ב 64 סיביות, שכן מצביע הערימה שלך הוא rsp , מה שרמז על יישור 8 בתים.

האם זו "דלתא הערימה הנוכחית" אליה אתה מתייחס? ניתן לאחזר אותו באמצעות 'GetSpd'.
@Guntram Blohm: האם אתה בטוח לגבי הסיבה ש- 'GetOperandValue ()' מחזיר 4? ה- 'idc.py' אומר: "אופרנד הוא ביטוי רישום => מספר ביטוי". אני מבין זאת כ: "אם יש 'ביטוי' רשום, 'GetOperandValue ()' מחזיר את * מספר הביטוי *." אינני יודע אם כי למה הכוונה * מספר הביטוי * הזה. מה אתה חושב?
כרגע אין לי גישה למחשב המשרדי שלי, שם IDA מותקן, אבל אני מניח ש- "ביטוי רישום" כמעט זהה ל"שם רישום ", ולכן לכל רשם מעבד מוקצה מספר, ועידא מחזירה המספר הזה אם האופרנד הוא שם רישום, או משהו דומה המציין רישום על חומרה אקזוטית.
Jason Geffner
2015-06-01 19:22:44 UTC
view on stackexchange narkive permalink

בהנחה ש- addr הוא ה- EA של mov [rsp + 3F8h + var_3F8], 0 :

  re.findall ('\ [(. *) \] ', idc.GetDisasm (addr)) [0]. split (' + ')  

מניב את הרשימה

  ['rsp', '3F8h', 'var_3F8']  
זה עובד עד שאתה פוגע בחיסור או בכפל, למשל. `mov edx, [eax + ecx * 4]`. רגקס היא לא ממש אפשרות מצוינת כאן, אך למרבה הצער לא נראה ש- IDA באמת נותנת לנו אפשרות רבה.
_ "זה עובד עד שאתה פוגע בחיסור או בכפל" _ - כן, אבל זה לא מה שהשאלה נשאלה :)
@JasonGeffner ** (a) ** קל יותר לעשות regex `GetOpnd (ea, 0)` == `[rsp + 3F8h + var_3F8]` ** (b) ** כיצד להשיג את הערך של var_x (* ניתן לנחש *) ו- arg_x (* לא הרבה) ** (c) ** במקרים כאלה (* רישום + תזוזה *) פשוט `GetOperandValue (ea, 1) אם GetOpType (ea, 1) == o_displ אחר אף אחד == '48'.
ניתן לזהות את @Polynomial: מסוג זה של אופרנד על ידי 'GetOpnd (ea, 1) == o_phrase' והוא כנראה הסוג היחיד של אופרנד שהיית משתמש בו ב- regex, למעט אולי עבור o_displ. אמנם, מכיוון שאתה לא יכול לפתור את זה לערך ממשי, סביר להניח שהוא לעולם לא יהפוך לבעיה.


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