कंस्ट्रेंट

.dex फ़ाइल, Dalvik बाइटकोड के लिए ट्रांसपोर्ट फ़ॉर्मैट है. किसी फ़ाइल को मान्य .dex फ़ाइल बनाने के लिए, उसमें कुछ सिंटैक्स और सिमेंटिक से जुड़ी पाबंदियां होती हैं. साथ ही, सिर्फ़ मान्य .dex फ़ाइलों के साथ काम करने के लिए, रनटाइम की ज़रूरत होती है.

.dex फ़ाइल की इंटिग्रिटी से जुड़ी सामान्य शर्तें

पूरी सुरक्षा से जुड़ी सामान्य पाबंदियां, .dex फ़ाइल के बड़े स्ट्रक्चर से जुड़ी होती हैं. इनके बारे में .dex फ़ॉर्मैट में पूरी जानकारी दी गई है.

पहचानकर्ता ब्यौरा
G1 .dex फ़ाइल का magic नंबर, वर्शन 35 के लिए dex\n035\0 होना चाहिए. इसके अलावा, यह बाद के वर्शन के लिए भी ऐसा ही होना चाहिए.
G2 यह चेकसम, magic और checksum फ़ील्ड को छोड़कर, पूरी फ़ाइल के कॉन्टेंट का Adler-32 चेकसम होना चाहिए.
G3 हस्ताक्षर, magic, checksum, और signature को छोड़कर, फ़ाइल के पूरे कॉन्टेंट का SHA-1 हैश होना चाहिए.
G4

file_size, बाइट में फ़ाइल के असल साइज़ से मेल खाना चाहिए. (v40 या उससे पहले का वर्शन)

file_size, कंटेनर में अगले हेडर पर या फ़िज़िकल फ़ाइल (कंटेनर) के आखिर में ले जाना चाहिए. अगर यह अगले हेडर पर ले जाता है, तो फ़ाइल का साइज़ चार-बाइट अलाइन होना चाहिए. सभी file_size फ़ील्ड का योग container_size होना चाहिए. (v41 या उसके बाद का वर्शन)

G5

header_size की वैल्यू यह होनी चाहिए: 0x70 (v40 या उससे पहले का वर्शन)

header_size की वैल्यू यह होनी चाहिए: 0x78 (v41 या उसके बाद का वर्शन)

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 फ़ील्ड, कंटेनर में होने चाहिए और उनका डेटा, उनके बारे में बताने वाले हेडर के बाद मौजूद होना चाहिए. (v41 या उसके बाद का वर्शन)

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 सेक्शन का मान्य रेफ़रंस होना चाहिए. (v40 या उससे पहले का वर्शन)

हर string_id_item के लिए, string_data_off फ़ील्ड को कंटेनर में ऑफ़सेट होना चाहिए. साथ ही, यह किसी ऐसे हेडर के बाद होना चाहिए जो इसका इस्तेमाल करता हो. (v41 या उसके बाद का वर्शन)

रेफ़रंस वाले 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 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 const-string और const-string/jumbo निर्देशों का B ऑपरेंड, स्ट्रिंग कॉन्सटेंट पूल में एक मान्य इंडेक्स होना चाहिए.
A10 iget<kind> और iput<kind> निर्देशों का C ऑपरेंड, फ़ील्ड कॉन्स्टेंट पूल में एक मान्य इंडेक्स होना चाहिए. रेफ़रंस वाली एंट्री में, किसी इंस्टेंस फ़ील्ड की जानकारी होनी चाहिए.
A11 sget<kind> और sput<kind> निर्देशों का C ऑपरेंड, फ़ील्ड कॉन्स्टेंट पूल में एक मान्य इंडेक्स होना चाहिए. रेफ़रंस वाली एंट्री, स्टैटिक फ़ील्ड होनी चाहिए.
A12 invoke-virtual, invoke-super, invoke-direct, और invoke-static निर्देशों का C ऑपरेंड, मेथड कॉन्सटेंट पूल में एक मान्य इंडेक्स होना चाहिए.
A13 invoke-virtual/range, invoke-super/range, invoke-direct/range, और invoke-static/range निर्देशों का B ऑपरेंड, मेथड कॉन्स्टेंट पूल में एक मान्य इंडेक्स होना चाहिए.
A14 जिस तरीके का नाम '<' से शुरू होता है उसे सिर्फ़ वीएम के ज़रिए शुरू किया जाना चाहिए, न कि .dex फ़ाइल से जनरेट हुए कोड से. इसका एकमात्र अपवाद इंस्टेंस को शुरू करने वाला फ़ंक्शन है, जिसे invoke-direct से शुरू किया जा सकता है.
A15 invoke-interface निर्देश का C ऑपरेंड, मेथड कॉन्सटेंट पूल में एक मान्य इंडेक्स होना चाहिए. रेफ़रंस के तौर पर दिया गया method_id, किसी इंटरफ़ेस से जुड़ा होना चाहिए, न कि किसी क्लास से.
A16 invoke-interface/range निर्देश का B ऑपरेंड, मेथड कॉन्सटेंट पूल में एक मान्य इंडेक्स होना चाहिए. रेफ़रंस वाला method_id, किसी इंटरफ़ेस से जुड़ा होना चाहिए, न कि किसी क्लास से.
A17 const-class, check-cast, new-instance, और filled-new-array/range निर्देशों का B ऑपरेंड, टाइप कॉन्स्टेंट पूल में एक मान्य इंडेक्स होना चाहिए.
A18 instance-of, new-array, और filled-new-array के C ऑपरेंड, निर्देशों में टाइप कॉन्स्टेंट पूल में मान्य इंडेक्स होना चाहिए.
A19 new-array निर्देश से बनाए गए ऐरे के डाइमेंशन, 256 से कम होने चाहिए.
A20 new निर्देश में ऐरे क्लास, इंटरफ़ेस या ऐब्स्ट्रैक्ट क्लास का रेफ़रंस नहीं होना चाहिए.
A21 new-array निर्देश में बताए गए टाइप का रेफ़रंस नहीं होना चाहिए. साथ ही, यह टाइप मान्य होना चाहिए.
A22 किसी निर्देश में एक ही चौड़ाई (बिना जोड़े) वाले सभी रजिस्टर, मौजूदा तरीके के लिए मान्य होने चाहिए. इसका मतलब है कि उनके इंडेक्स, registers_size से छोटे और नॉन-नेगेटिव होने चाहिए.
A23 किसी निर्देश में डबल-विड्थ (पेयर) के तौर पर बताए गए सभी रजिस्टर, मौजूदा तरीके के लिए मान्य होने चाहिए. इसका मतलब है कि उनके इंडेक्स ऋणात्मक नहीं होने चाहिए और registers_size-1 से छोटे होने चाहिए.
A24 invoke-virtual और invoke-direct निर्देशों का method_id ऑपरेंड, किसी क्लास से जुड़ा होना चाहिए, न कि इंटरफ़ेस से. 037 वर्शन से पहले की Dex फ़ाइलों में, invoke-super और invoke-static निर्देशों के लिए भी यही बात लागू होनी चाहिए.
A25 invoke-virtual/range और invoke-direct/range निर्देशों का method_id ऑपरेंड, किसी क्लास से जुड़ा होना चाहिए, न कि इंटरफ़ेस से. 037 वर्शन से पहले की Dex फ़ाइलों में, invoke-super/range और invoke-static/range निर्देशों के लिए भी यही बात लागू होनी चाहिए.

स्ट्रक्चरल बाइटकोड की सीमाएं

स्ट्रक्चरल कंस्ट्रेंट, बाइटकोड के कई एलिमेंट के बीच के संबंधों पर पाबंदियां होती हैं. आम तौर पर, कंट्रोल या डेटा-फ़्लो विश्लेषण की तकनीकों का इस्तेमाल किए बिना, इनकी जांच नहीं की जा सकती.

पहचानकर्ता ब्यौरा
B1 आर्ग्युमेंट (रजिस्टर और इमीडिएट वैल्यू) की संख्या और टाइप, हमेशा निर्देश से मेल खाने चाहिए.
B2 रजिस्टर किए गए पेयर को कभी अलग नहीं किया जाना चाहिए.
B3 किसी रजिस्टर (या पेयर) को पढ़ने से पहले, उसे असाइन करना होगा.
B4 invoke-direct निर्देश में, सिर्फ़ मौजूदा क्लास या उसकी किसी एक सुपरक्लास में, किसी इंस्टेंस को शुरू करने वाले फ़ंक्शन या तरीके को शुरू करना चाहिए.
B5 इंस्टेंस को शुरू करने वाले फ़ंक्शन को सिर्फ़ ऐसे इंस्टेंस पर शुरू किया जाना चाहिए जिसे शुरू नहीं किया गया है.
B6 इंस्टेंस के तरीकों को सिर्फ़ इंस्टेंस पर और इंस्टेंस फ़ील्ड को सिर्फ़ पहले से शुरू किए गए इंस्टेंस पर ऐक्सेस किया जा सकता है.
B7 अगर किसी new-instance निर्देश को फिर से चलाया जाता है, तो उस रजिस्टर का इस्तेमाल नहीं किया जाना चाहिए जिसमें new-instance निर्देश का रिज़ल्ट सेव होता है. ऐसा तब किया जाना चाहिए, जब इंस्टेंस को शुरू करने से पहले ही new-instance निर्देश को फिर से चलाया जाता है.
B8 किसी इंस्टेंस के सदस्यों को ऐक्सेस करने से पहले, इंस्टेंस को शुरू करने वाले फ़ंक्शन को किसी दूसरे इंस्टेंस को शुरू करने वाले फ़ंक्शन (एक ही क्लास या सुपरक्लास) को कॉल करना होगा. अपवाद, ऐसे इंस्टेंस फ़ील्ड होते हैं जिन्हें इनहेरिट नहीं किया जाता. इन्हें किसी दूसरे इनिशलाइज़र और आम तौर पर Object क्लास को कॉल करने से पहले असाइन किया जा सकता है.
B9 सभी असली तरीके के आर्ग्युमेंट, उनके संबंधित औपचारिक आर्ग्युमेंट के साथ असाइनमेंट के मुताबिक होने चाहिए.
B10 हर इंस्टेंस मेथड को कॉल करने के लिए, असल इंस्टेंस, निर्देश में बताई गई क्लास या इंटरफ़ेस के साथ असाइनमेंट के लिहाज़ से काम का होना चाहिए.
B11 return<kind> निर्देश, उसके तरीक़े के रिटर्न टाइप से मेल खाना चाहिए.
B12 किसी सुपरक्लास के सुरक्षित मेंबर को ऐक्सेस करते समय, ऐक्सेस किए जा रहे इंस्टेंस का असल टाइप, मौजूदा क्लास या उसकी किसी सबक्लास का होना चाहिए.
B13 स्टैटिक फ़ील्ड में सेव की गई वैल्यू का टाइप, असाइनमेंट के साथ काम करने वाला या फ़ील्ड के टाइप में बदला जा सकने वाला होना चाहिए.
B14 किसी फ़ील्ड में सेव की गई वैल्यू का टाइप, फ़ील्ड के टाइप के साथ काम करने वाला या उसमें बदला जा सकने वाला होना चाहिए.
B15 ऐरे में सेव की गई हर वैल्यू का टाइप, ऐरे के कॉम्पोनेंट टाइप के साथ असाइनमेंट के लिहाज़ से काम करना चाहिए.
B16 throw निर्देश का A ऑपरेंड, असाइनमेंट के लिए 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 स्यूडो-निर्देशों को कंट्रोल फ़्लो से ऐक्सेस नहीं किया जा सकता.