מגבלות

קובץ .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 על ידי זרימת בקרה.