קובץ .dex
הוא פורמט התחבורה של Dalvik bytecode. ישנם אילוצים תחביריים וסמנטיים מסוימים כדי שקובץ יהיה קובץ .dex
חוקי, ונדרשת זמן ריצה כדי לתמוך רק בקבצי .dex חוקיים.
אילוצי תקינות .dex כלליים
אילוצי יושר כלליים עוסקים במבנה הגדול יותר של קובץ .dex
, כפי שמתואר בפירוט בפורמט .dex
.
מזהה | תיאור |
---|---|
G1 | מספר magic של קובץ .dex חייב להיות dex\n035\0 או dex\n037\0 . |
G2 | סכום הבדיקה חייב להיות סכום בדיקה של Adler-32 של כל תוכן הקובץ למעט magic ושדה checksum . |
G3 | החתימה חייבת להיות Hash SHA-1 של כל תוכן הקובץ מלבד magic , checksum signature . |
G4 | file_size חייב להתאים לגודל הקובץ בפועל בבתים. |
G5 | ל- header_size חייב להיות הערך: 0x70 |
G6 | endian_tag חייב להיות הערך: ENDIAN_CONSTANT או REVERSE_ENDIAN_CONSTANT |
G7 | עבור כל אחד מקטעי link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs data , שדות offset size חייבים להיות אפס או שניהם לא אפס. במקרה האחרון, ההיסט חייב להיות מיושר לארבעה בתים. |
G8 | כל שדות ההיסט בכותרת מלבד map_off חייבים להיות מיושרים לארבעה בתים. |
G9 | השדה map_off חייב להיות אפס או נקודה לתוך קטע הנתונים. במקרה האחרון, קטע data חייב להתקיים. |
G10 | אף אחד מקטעי link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs data לא חייב לחפוף זה את זה או לכותרת. |
G11 | אם קיימת מפה, אז לכל ערך מפה חייב להיות סוג חוקי. כל סוג עשוי להופיע פעם אחת לכל היותר. |
G12 | אם קיימת מפה, אז כל ערך מפה חייב להיות בעל היסט וגודל שאינם אפס. ההיסט חייב להצביע על הקטע המתאים של הקובץ (כלומר string_id_item חייב להצביע אל הקטע string_ids ) והגודל המפורש או המרומז של הפריט חייב להתאים לתוכן ולגודל של הקטע בפועל. |
G13 | אם קיימת מפה, אזי ההיסט של ערך המפה n+1 חייב להיות גדול או שווה להיסט של ערך המפה n plus than size of map entry n . זה מרמז על ערכים שאינם חופפים וסדר נמוך עד גבוה. |
G14 | לסוגי הערכים הבאים חייב להיות היסט מיושר לארבעה בתים: string_id_item , type_id_item , proto_id_item , field_id_item , method_id_item , class_def_item , type_list , code_item , annotations_directory_item . |
G15 | עבור כל string_id_item , השדה string_data_off חייב להכיל הפניה חוקית למקטע data . עבור string_data_item שאליו מתייחסים, שדה data חייב להכיל מחרוזת MUTF-8 חוקית, וה- utf16_size חייב להתאים לאורך המפוענח של המחרוזת. |
G16 | עבור כל type_id_item , השדה descriptor_idx חייב להכיל הפניה חוקית לרשימת string_ids . המחרוזת המופנית חייבת להיות מתאר סוג חוקי. |
G17 | עבור כל proto_id_item , השדה shorty_idx חייב להכיל הפניה חוקית לרשימת string_ids . המחרוזת המופנית חייבת להיות תיאור קצר חוקי. כמו כן, השדה return_type_idx חייב להיות אינדקס חוקי למקטע type_ids , והשדה parameters_off חייב להיות אפס או היסט חוקי המצביע על מקטע data . אם אינו אפס, אסור לרשימת הפרמטרים להכיל ערכים בטל. |
G18 | עבור כל field_id_item , גם השדות class_idx ו- type_idx חייבים להיות מדדים חוקיים ברשימת type_ids . הערך שאליו מפנה class_idx חייב להיות סוג הפניה שאינו של מערך. בנוסף, השדה name_idx חייב להיות הפניה חוקית למקטע string_ids , והתוכן של הערך המופנה חייב להתאים למפרט MemberName . |
G19 | עבור כל method_id_item , השדה class_idx חייב להיות אינדקס חוקי למקטע type_ids , והערך שאליו מתייחסים חייב להיות סוג הפניה שאינו מערך. השדה proto_id חייב להיות הפניה חוקית לרשימת proto_ids . השדה name_idx חייב להיות הפניה חוקית למקטע string_ids , והתוכן של הערך המופנה חייב להתאים למפרט MemberName . |
G20 | עבור כל field_id_item , השדה class_idx חייב להיות אינדקס חוקי ברשימת type_ids . הערך המופנה חייב להיות סוג הפניה שאינו של מערך. |
אילוצי קוד בתים סטטיים
אילוצים סטטיים הם אילוצים על אלמנטים בודדים של קוד הבתים. בדרך כלל ניתן לבדוק אותם מבלי להשתמש בטכניקות בקרה או ניתוח זרימת נתונים.
מזהה | תיאור |
---|---|
A1 | מערך insns לא יכול להיות ריק. |
A2 | ה-opcode הראשון במערך insns חייב להיות אינדקס אפס. |
A3 | מערך insns חייב להכיל רק קודים חוקיים של Dalvik. |
A4 | מדד ההוראה n+1 חייב להיות שווה לאינדקס ההוראה n בתוספת אורך ההוראה n , תוך התחשבות באופרנדים אפשריים. |
A5 | ההוראה האחרונה במערך insns חייבת להסתיים באינדקס insns_size-1 . |
A6 | כל יעדי goto וה- if-<kind> חייבים להיות קודים באותה שיטה. |
A7 | כל היעדים של הוראה packed-switch חייבים להיות קודים באותה שיטה. הגודל ורשימת היעדים חייבים להיות עקביים. |
A8 | כל היעדים של הוראת sparse-switch חייבים להיות קודים באותה שיטה. הטבלה המתאימה חייבת להיות עקבית וממוינת מנמוך לגבוה. |
A9 | האופרנד B של ההוראות const-string ו- const-string/jumbo חייב להיות אינדקס חוקי למאגר הקבוע של המחרוזת. |
A10 | האופרנד C של ההוראות iget<kind> ו- iput<kind> חייב להיות אינדקס חוקי למאגר קבוע השדה. הערך המופנה חייב לייצג שדה מופע. |
A11 | האופרנד C של ההוראות sget<kind> ו- sput<kind> חייב להיות אינדקס חוקי למאגר קבוע השדה. הערך המופנה חייב לייצג שדה סטטי. |
A12 | האופרנד C של הפקודות invoke-virtual , invoke-super , invoke-direct ו- invoke-static חייב להיות אינדקס חוקי למאגר הקבוע של השיטה. |
A13 | האופרנד B של הפקודות invoke-virtual/range , invoke-super/range , invoke-direct/range ו- invoke-static/range חייבות להיות אינדקס חוקי למאגר הקבוע של השיטה. |
A14 | שיטה ששמה מתחיל ב-'<' חייבת להיות מופעלת באופן מרומז רק על ידי ה-VM, לא על ידי קוד שמקורו בקובץ .dex . היוצא מן הכלל היחיד הוא אתחול המופעים, שניתן להפעילו על ידי invoke-direct . |
A15 | האופרנד C של הוראת invoke-interface חייב להיות אינדקס חוקי למאגר הקבוע של השיטה. ה- method_id המופנה חייב להיות שייך לממשק (לא למחלקה). |
A16 | האופרנד B של הוראת ה- invoke-interface/range חייב להיות אינדקס חוקי למאגר הקבוע של השיטה. ה- method_id המופנה חייב להיות שייך לממשק (לא למחלקה). |
A17 | האופרנד B של const-class , check-cast , new-instance ו- filled-new-array/range חייב להיות אינדקס חוקי למאגר הקבוע של הסוג. |
A18 | האופרנד C של instance-of , new-array ומערך filled-new-array חייב להיות אינדקס חוקי לתוך מאגר קבוע הסוג. |
A19 | הממדים של מערך שנוצר על ידי הוראת new-array חייבים להיות פחות מ 256 . |
A20 | ההוראה new אינה יכולה להתייחס למחלקות מערך, ממשקים או מחלקות מופשטות. |
A21 | הסוג שאליו מתייחסים הוראת new-array חייב להיות סוג תקף ללא הפניה. |
A22 | כל הרשמים אליהם מתייחסים הוראה ברוחב יחיד (לא זוג) חייבים להיות תקפים עבור השיטה הנוכחית. כלומר, המדדים שלהם חייבים להיות לא שליליים וקטנים מ- registers_size . |
A23 | כל הרשמים שאליהם מתייחסים הוראה ברוחב כפול (זוג) חייבים להיות תקפים עבור השיטה הנוכחית. כלומר, המדדים שלהם חייבים להיות לא שליליים וקטנים מ- registers_size-1 . |
A24 | האופרנד method_id של ההוראות invoke-virtual ו- invoke-direct חייבות להיות שייכות למחלקה (לא ממשק). בקבצי Dex שלפני גרסה 037 אותו הדבר חייב להיות נכון לגבי הוראות של invoke-super ו- invoke-static . |
A25 | האופרנד method_id של ההוראות invoke-virtual/range ו- invoke-direct/range חייבות להיות שייכות למחלקה (לא ממשק). בקבצי Dex שלפני גרסה 037 אותו הדבר חייב להיות נכון לגבי הוראות invoke-super/range ו- invoke-static/range . |
אילוצי קוד בתים מבניים
אילוצים מבניים הם אילוצים על יחסים בין מספר אלמנטים של קוד הבתים. בדרך כלל לא ניתן לבדוק אותם ללא שימוש בטכניקות בקרה או ניתוח זרימת נתונים.
מזהה | תיאור |
---|---|
B1 | מספר וסוגי הארגומנטים (אוגרים וערכים מיידיים) חייבים תמיד להתאים להוראה. |
B2 | לעולם אסור לפרק זוגות רישום. |
B3 | יש להקצות אוגר (או זוג) תחילה לפני שניתן יהיה לקרוא אותו. |
B4 | הוראה invoke-direct של הפעלת מופע חייבת להפעיל אתחול מופע או שיטה רק במחלקה הנוכחית או באחת ממחלקות העל שלה. |
B5 | יש להפעיל אתחול של מופע רק במופע לא מאותחל. |
B6 | ניתן להפעיל שיטות מופע רק ב- וניתן לגשת לשדות מופע רק במופעים שכבר אותחלו. |
B7 | אין להשתמש בפנקס שמכיל את התוצאה של פקודה new-instance אם אותה פקודה new-instance מבוצעת שוב לפני אתחול המופע. |
B8 | מאתחל מופע חייב לקרוא לאתחל מופע אחר (אותה מחלקה או מחלקה על) לפני שניתן יהיה לגשת לחברי מופע כלשהו. יוצאים מן הכלל הם שדות מופעים שאינם עוברים בירושה, אותם ניתן להקצות לפני קריאה לאיתחול אחר, ולמחלקת Object באופן כללי. |
B9 | כל הארגומנטים של השיטה בפועל חייבים להיות תואמים להקצאה עם הארגומנטים הפורמליים שלהם. |
B10 | עבור כל הפעלת שיטת מופע, המופע בפועל חייב להיות תואם הקצאה למחלקה או לממשק שצוינו בהוראה. |
B11 | הוראת return<kind> חייבת להתאים לסוג ההחזרה של השיטה שלה. |
B12 | בעת גישה לחברים מוגנים של מחלקת-על, הסוג האמיתי של המופע אליו ניגשים חייב להיות המחלקה הנוכחית או אחת מתת-המחלקות שלה. |
B13 | סוג הערך המאוחסן בשדה סטטי חייב להיות תואם הקצאות או להמרה לסוג השדה. |
B14 | סוג הערך המאוחסן בשדה חייב להיות תואם הקצאות או להמרה לסוג השדה. |
B15 | הסוג של כל ערך המאוחסן במערך חייב להיות תואם הקצאה לסוג הרכיב של המערך. |
B16 | האופרנד A של הוראת throw חייב להיות תואם להקצאה עם java.lang.Throwable . |
B17 | ההוראה האחרונה שניתן להגיע אליה של שיטה חייבת להיות גישה goto או ענף, return או הוראת throw . אסור שיהיה אפשר להשאיר את מערך insns בתחתית. |
B18 | לא ניתן לקרוא את החצי הלא מוקצה של זוג אוגר לשעבר (נחשב לא חוקי) עד שהוא יוקצה מחדש על ידי הוראה אחרת. |
B19 | יש להקדים מיידית (במערך insns ) להוראה move-result<kind> הוראה של invoke-<kind> . היוצא מן הכלל היחיד הוא הוראת move-result-object , אשר עשויה להיות קודמת לה גם הוראה filled-new-array . |
B20 | יש להקדים מיד הוראת move-result<kind> (בזרימת בקרה בפועל) בהוראה תואמת return-<kind> (אסור לקפוץ אליה). היוצא מן הכלל היחיד הוא הוראת move-result-object , אשר עשויה להיות קודמת לה גם הוראה filled-new-array . |
B21 | הוראת move-exception חייבת להופיע רק כהוראה ראשונה במטפל חריג. |
B22 | אסור להגיע להוראות ה- packed-switch-data , sparse-switch-data ו- fill-array-data על ידי זרימת בקרה. |