فایل .dex قالب انتقال برای بایتکد Dalvik است. برای اینکه فایلی بهعنوان فایل .dex معتبر شناخته شود، محدودیتهای نحوی و معنایی خاصی وجود دارد و زمان اجرا برای پشتیبانی از فایلهای .dex معتبر الزامی است.
محدودیتهای کلی تمامیت .dex
محدودیتهای یکپارچگی عمومی به ساختار بزرگتر فایل .dex مربوط میشود، همانطور که بهطور مفصل در قالب .dex شرح داده شده است.
| شناسه | شرح |
|---|---|
| G1 |
عدد magic در فایل .dex باید
dex\n035\0 برای نسخه ۳۵، یا مشابه آن برای نسخههای بعدی باشد.
|
| G2 |
مجموع کنترل باید مجموع کنترل Adler-32 از کل محتوای فایل بهجز فیلدهای magic و checksum باشد.
|
| G3 |
امضا باید درهمسازی SHA-1 از کل محتوای فایل بهجز magic،
checksum، و signature باشد.
|
| G4 |
|
| G5 |
|
| G6 |
endian_tag باید یکی از مقادیر زیر را داشته باشد:
ENDIAN_CONSTANT یا REVERSE_ENDIAN_CONSTANT
|
| G7 |
برای هریک از بخشهای
فیلدهای |
| 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 |
برای هر برای هر برای |
| 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 |
اولین کد عملیات در آرایه 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 |
روشی که نام آن با «<» شروع میشود باید فقط بهطور ضمنی توسط ماشین مجازی فراخوانی شود، نه توسط کدی که از فایل .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 |
دستورالعمل move-result<kind> باید بلافاصله
قبلاز دستورالعمل 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 نباید ازطریق جریان کنترل
قابلدسترسی باشند.
|