القيود

ملف .dex هو تنسيق النقل لرمز Dalvik البرمجي. هناك قيود نحوية ودلالية معيّنة لكي يكون الملف صالحًا بتنسيق .dex، ويجب استخدام وقت تشغيل لتفعيل ملفات ‎ .dex الصالحة فقط.

القيود العامة لسلامة ملفات ‎ .dex

ترتبط قيود السلامة العامة بالبنية الأكبر لملف .dex، كما هو موضّح بالتفصيل في تنسيق .dex.

المعرّف الوصف
G1 يجب أن يكون رقم magic لملف .dex هو dex\n035\0 للإصدار 35 أو رقم مشابه للإصدارات الأحدث.
G2 يجب أن يكون الملخّص هو ملخّص Adler-32 لمحتوى الملف بالكامل باستثناء حقلَي magic وchecksum.
G3 يجب أن يكون التوقيع عبارة عن تجزئة SHA-1 لمحتوى الملف بالكامل باستثناء magic checksum وsignature.
G4

يجب أن يتطابق file_size مع حجم الملف الفعلي بالبايت. (الإصدار 40 أو الإصدارات الأقدم)

يجب أن يشير الرمز file_size إلى العنوان التالي في الحاوية، أو في نهاية الملف المادي (الحاوية). إذا كان يشير إلى العنوان التالي، يجب أن يكون حجم الملف مُحاذَى بـ 4 بايت. يجب أن يكون مجموع جميع حقول file_size مساويًا container_size. (الإصدار 41 أو الإصدارات الأحدث)

G5

يجب أن تكون قيمة header_size هي: 0x70 (الإصدار 40 أو الإصدارات الأقدم)

يجب أن تكون قيمة header_size هي: 0x78 (الإصدار 41 أو الإصدارات الأحدث)

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 كلاهما صفرًا أو كلاهما غير صفري. في الحالة الأخيرة، يجب أن تكون الإزاحة محاذية لأربعة بايت.

يجب أن يكون الحقلان offset وsize داخل الحاوية وأن يُشار بهما إلى البيانات التي تقع بعد العنوان الذي يحدّدهما. (الإصدار 41 أو الإصدارات الأحدث)

G8 يجب أن تكون جميع حقول البادئة في العنوان باستثناء map_off محاذية بأربعة بايت.
G9 يجب أن يكون حقل map_off إما صفرًا أو يشير إلى قسم data. في الحالة الأخيرة، يجب أن يكون قسم 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. (الإصدار 40 أو الإصدارات الأقدم)

يجب أن يكون الحقل string_data_off لكل string_id_item عبارة عن إزاحة داخل الحاوية وبعد أي عنوان يستخدمه بشكل تراكمي. (الإصدار 41 أو الإصدارات الأحدث)

بالنسبة إلى string_data_item المُشار إليه، يجب أن يحتوي الحقل data على سلسلة MUTF-8 صالحة، ويجب أن يتطابق utf16_size مع طول السلسلة بعد فك التشفير.

G16 يجب أن يحتوي الحقل descriptor_idx على مرجع صالح في قائمة string_ids لكل type_id_item. يجب أن تكون السلسلة المُشار إليها وصفًا صالحًا لنوع معيّن.
G17 يجب أن يحتوي الحقل shorty_idx على مرجع صالح في قائمة string_ids لكل proto_id_item. يجب أن تكون السلسلة المُشار إليها وصفًا مختصًا وصالحًا لرابط Shorty. يجب أيضًا أن يكون الحقل 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.
مجموعة العشرين يجب أن يكون الحقل class_idx فهرسًا صالحًا في قائمة type_ids لكل field_id_item. يجب أن يكون الإدخال المُشار إليه من نوع مرجع غير مصفوفة.

قيود الرمز البرمجي الثابت

القيود الثابتة هي قيود مفروضة على عناصر فردية من الرمز الثنائي. ويمكن عادةً التحقّق منها بدون استخدام أساليب التحكّم أو تحليل تدفق البيانات.

المعرّف الوصف
الإكسسوار 1 يجب ألا تكون صفيف insns فارغًا.
الإكسسوار 2 يجب أن يكون فهرس الأوامر البرمجية الأولى في مصفوفة insns هو صفر.
الإكسسوار 3 يجب أن تحتوي مصفوفة insns على أوامر التشغيل الصالحة فقط لنظام Dalvik.
الإكسسوار 4 يجب أن يكون فهرس التعليمة n+1 مساويًا لفهرس التعليمة n بالإضافة إلى طول التعليمة n، مع الأخذ في الاعتبار المُعامِلات المحتمَلة.
الإكسسوار 5 يجب أن تنتهي التعليمة الأخيرة في صفيف insns عند الفهرس insns_size-1.
الإكسسوار 6 يجب أن تكون جميع استهدافات goto وif-<kind> رموزًا تشغيلية ضمن الطريقة نفسها.
الإكسسوار 7 يجب أن تكون جميع استهدافات تعليمات packed-switch هي أوامر تشغيل ضمن الطريقة نفسها. يجب أن يكون حجم الاستهدافات وقائمة الاستهدافات متّسقَين.
الإكسسوار 8 يجب أن تكون جميع استهدافات تعليمات sparse-switch هي أوامر تشغيل ضمن الطريقة نفسها. يجب أن يكون الجدول المقابل متسقًا ومُرتَّبًا من الأدنى إلى الأعلى.
الإكسسوار 9 يجب أن يكون الم Operand B لتعليمات const-string و const-string/jumbo فهرسًا صالحًا في مجموعة الثوابت السلاسل.
الإكسسوار 10 يجب أن يكون المُشغِّل C لتعليمات iget<kind> و iput<kind> فهرسًا صالحًا في مجموعة الثوابت للحقول. يجب أن يمثّل الإدخال المُشار إليه حقل مثيل.
الإكسسوار 11 يجب أن يكون المُشغِّل C لتعليمات sget<kind> و sput<kind> فهرسًا صالحًا في مجموعة الثوابت للحقول. يجب أن يمثّل الإدخال المُشار إليه حقلًا ثابتًا.
الإكسسوار 12 يجب أن يكون الم Operand C لتعليمات invoke-virtual و invoke-super وinvoke-direct و invoke-static فهرسًا صالحًا في مجموعة الثوابت الخاصة بالطريقة.
الإكسسوار 13 يجب أن يكون الم Operand B لتعليمات invoke-virtual/range invoke-super/range وinvoke-direct/range invoke-static/range فهرسًا صالحًا في مجموعة الثوابت الخاصة بالطريقة.
الإكسسوار 14 يجب ألا يتم استدعاء أسلوب يبدأ اسمه بـ '<' إلا بشكل ضمني من خلال الآلة الافتراضية، وليس من خلال رمز برمجي مصدره ملف .dex. الوحيد هو مثبّت المثيل الذي يمكن استدعاؤه باستخدام invoke-direct.
الإكسسوار 15 يجب أن يكون الم Operand C لتعليمات invoke-interface فهرسًا صالحًا في مجموعة الثوابت الخاصة بالطريقة. يجب أن ينتمي الرمز المرجعيmethod_id إلى واجهة (وليس إلى صف).
الإكسسوار 16 يجب أن يكون الم Operand B لتعليمات invoke-interface/range فهرسًا صالحًا في مجموعة الثوابت الخاصة بالطريقة. يجب أن ينتمي العنصر method_id المُشار إليه إلى واجهة (وليس فئة).
الإكسسوار 17 يجب أن يكون المعامل B لتعليمات const-class check-cast وnew-instance filled-new-array/range فهرسًا صالحًا في مجموعة الثابتة للأنواع.
الإكسسوار 18 يجب أن يكون المعامل C لتعليمات instance-of new-array وfilled-new-array فهرسًا صالحًا في مجموعة الثابتة للأنواع.
الإكسسوار 19 يجب أن تكون أبعاد الصفيف الذي تم إنشاؤه باستخدام new-array أقل من 256.
الإكسسوار 20 يجب ألا يشير 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 يجب عدم استدعاء عنصر تنشيط العنصر إلا على مثيل لم يتم إعداده.
ب6 لا يمكن استدعاء طرق المثيل إلا على حقول المثيل، ولا يمكن الوصول إليها إلا على المثيلات التي سبق بدء تشغيلها.
B7 يجب عدم استخدام السجلّ الذي يحتوي على نتيجة new-instance إذا تم تنفيذ new-instance التوجيه نفسه مرة أخرى قبل بدء تشغيل المثيل.
B8 يجب أن يستدعي مُنشئ مثيل مُنشئ مثيل آخر (النوع نفسه أو الفئة الفائقة) قبل الوصول إلى أيٍّ من أعضاء المثيل. الاستثناءات هي حقول المثيل غير المُكتسَبة، والتي يمكن تعيينها قبل استدعاء أداة إعداد أخرى، وObject class بشكل عام.
B9 يجب أن تكون جميع وسيطات الطريقة الفعلية متوافقة مع عملية التحديد مع الوسائط الرسمية المقابلة لها.
B10 في كلّ استدعاء لطريقة مثيل، يجب أن يكون المثيل الفعلي متوافقًا مع القيمة المحدّدة في العبارة في عملية الربط بالفئة أو الواجهة.
B11 يجب أن تتطابق تعليمات return<kind> مع نوع القيمة المعروضة في طريقة الإجراء.
ب12 عند الوصول إلى الأعضاء المحمية في فئة رئيسية، يجب أن يكون النوع الفعلي للمثيل الذي يتم الوصول إليه هو إما الفئة الحالية أو أحد الفئات الفرعية لها.
B13 يجب أن يكون نوع القيمة المخزّنة في حقل ثابت متوافقًا مع نوع الحقل أو قابلاً للتحويل إليه.
B14 يجب أن يكون نوع القيمة المخزّنة في حقل متوافقًا مع عملية التحديد أو قابلاً للتحويل إلى نوع الحقل.
B15 يجب أن يكون نوع كل قيمة مخزّنة في مصفوفة متوافقًا مع نوع مكوّنات المصفوفة من حيث التخصيص.
B16 يجب أن يكون الم Operand A لتعليمات throw متوافقًا مع java.lang.Throwable من حيث التخصيص.
B17 يجب أن يكون آخر تعليمات يمكن الوصول إليها في إحدى الطرق إما تعليمات goto أو فرع return أو throw. يجب ألا يكون من الممكن ترك صفيف insns في أسفل الصفحة.
B18 قد لا تتم قراءة النصف غير المحدَّد من زوج السجلّ السابق (يُعتبَر غير صالح) إلى أن تتم إعادة تحديده من خلال بعض التعليمات الأخرى.
ب19 يجب أن يسبق move-result<kind> مباشرةً (في صفيف insns) invoke-<kind> (في صفيف insns). الاستثناء الوحيد هو الأمر 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.