שְׁאֵלָה:
PIN של אינטל: כיצד לגשת לאובייקט INS מתוך פונקציית ניתוח?
langlauf.io
2016-04-12 00:39:11 UTC
view on stackexchange narkive permalink

קטע קוד PIN טיפוסי נראה כך (נלקח מתוך המדריך הרשמי):

  // פונקציה זו נקראת לפני ביצוע כל הוראה // ו מדפיס את הדפוס IPVOID (VOID * ip) {fprintf (trace, "% p \ n", ip); } // Pin קורא לפונקציה זו בכל פעם שנתקלת בהוראה חדשה הוראת VOID (INS ins, VOID * v) {// הכניסו קריאה ל- printip לפני כל הוראה, והעבירו אותה ל- IP INS_InsertCall (ins, IPOINT_BEFORE, (AFUNPTR) printip , IARG_INST_PTR, IARG_END);}  

אני פשוט לא מצליח להבין איך לגשת לאובייקט ins מתוך printip (VOID * p) . להפך נראה קל, כלומר להשיג את ה- IP מאובייקט ins :

INS_Address (INS ins) (ראה כאן)

ניסיתי להעביר מצביע INS * ins ל printip (VOID * ip, INS * ins) ins דרך IARG_PTR , &ins אך זה הסתיים בשגיאות יציקה או בתקלות פילוח.

כיצד אוכל לגשת לאובייקט ins (סוג INS ) בתוך פונקציית ניתוח?

הערת צד: הגעתי לבעיה זו כשניסיתי להתקשר ל INS_Disassemble (INS ins) לכל הוראה שבוצעה.

שתיים תשובות:
Ta Thanh Dinh
2016-04-12 15:57:33 UTC
view on stackexchange narkive permalink

אתה יכול לציין ש printip הוא מצביע פונקציה, הוא נקרא בעצלתיים באופן פנימי על ידי Pin ; יתר על כן ins הוא משתנה אוטומטי (הוא מועבר ל הדרכה מהערימה). כתוצאה מכך, העברת &ins ל printip (דרך IARG_PTR ) ואז השימוש בה יוביל לתקלות פילוח.

הצמדת קוד> מצהירה על INS על ידי התמחות בתבנית הכיתה INDEX , שכן ניתן לראות את ההצהרה הבאה ב- type_core.TLH :

  / *! @ingroup INS_BASIC_APIHandle for INS * / typedef class INDEX<6> INS;  

כאשר בונים ומפעילי הקצאות של תבנית הכיתה INDEX שניהם כברירת מחדל אז, באופן עקרוני ^^, אנחנו תמיד יכולים להכריז על משתנה קבוע לחלוק אובייקט של INS בין פונקציות מכשור וניתוח, למשל:

  INS סטטי per_ins; ... הוראות VOID (INS ins, VOID * v) {per_ins = ins; ...} ... VOID printip (VOID * ip) {INS_Disassemble (per_ins);}  

שיטה זו לא עובדת, למרבה הצער, זו דוגמה ל"תוכנית שהוקלדה היטב עדיין יכול להשתבש "ב- C / C ++ ^^. מכיוון ש Pin אינו מתחייב שמשתנים פנימיים, אליהם מגיעים אובייקט מסוג INS , קיימים לאורך זמן ב זמן הניתוח, התוצאה של קריאה ל INS_Disassemble (per_ins) בפונקציה ניתוח יכול להיות חסר משמעות.

במקרה שלך, ייתכן שלא תרצה להתקשר ל INS_Disassemble (ins) קוד> בכל פעם ש- ins מבצע. אנחנו לא צריכים את זה, למשל, אם ins נמצא בלולאה אז פונקציה זו תיקרא מספר פעמים (עם אותו ins ) כדי לקבל את אותה התוצאה.

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

  std std :: unordered_map<ADDRINT, std :: string> str_of_ins_at; VOID Instruction (INS ins, VOID * v) {str_of_ins_at [INS_Address (ins )] = INS_Disassemble (ins); ...} פריפ VOID (VOID * ip, ADDRINT addr) {std :: string ins_str = str_of_ins_at [addr]; ...}  
תודה על התשובה המפורטת. רציתי למקם את 'INS_Disassemble (ins)' בפונקציית הניתוח כדי לבדוק (ידנית על ידי התבוננות בה) אם פונקציית הניתוח פועלת כמתוכנן. אם אני מכניס את 'INS_Disassemble (ins)' לפונקציית Instrumentation, הפלט של 'INS_Disassemble (ins)' מופרד מפלט פונקציית הניתוח. במילים אחרות: רציתי שהפלט של פונקציית הניתוח יהיה זכאי עם ההוראה לבדוק בקלות אם היא נכונה.
אתה צודק, אנחנו תמיד יכולים להשיג אופקוד של הוראות באמצעות 'PIN_SafeCopy' ו- 'INS_Size', ואז להשתמש בכל כלי הפירוק למשל. Capstone, או אפילו Xed של אינטל.
אה סליחה, מחקתי את התגובה שלי לגבי גישה זו מכיוון שהרעיון שלך לאחסן את המיתרים נראה לי אלגנטי יותר.
אבל בכל מקרה, הסבר נהדר על מה שקורה עם האובייקט הזה.
Heiner Litz
2017-07-20 00:12:07 UTC
view on stackexchange narkive permalink

class typef class INDEX<6> INS; מוגדר ב- types_core.TLH (סוגים שאינם סוגים). הקוד הבא עובד בשבילי לפרק בזמן הניתוח.

  disasmIns בטל (ADDRINT tid, ADDRINT insarg) {INS ins; ins.q_set (insarg); std :: cout << "פירוק:" << INS_Disassemble (ins) << std :: endl;} הדרכה VOID (INS ins, VOID * v) {INS_InsertCall (ins, ISA, (), IARG_END);}  


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