Batasan

File .dex adalah format transport untuk bytecode Dalvik. Ada batasan sintaksis dan semantik tertentu agar file menjadi file .dex yang valid, dan runtime diperlukan untuk hanya mendukung file .dex yang valid.

Batasan integritas .dex umum

Batasan integritas umum berkaitan dengan struktur file .dex yang lebih besar, seperti yang dijelaskan secara rinci dalam format .dex .

Pengidentifikasi Keterangan
G1 Angka magic file .dex harus dex\n035\0 atau dex\n037\0 .
G2 Checksum harus berupa checksum Adler-32 dari seluruh isi file kecuali bidang magic dan checksum .
G3 Tanda tangan harus berupa hash SHA-1 dari seluruh isi file kecuali magic , checksum , dan signature .
G4 file_size harus sesuai dengan ukuran file sebenarnya dalam byte.
G5 header_size harus memiliki nilai: 0x70
G6 endian_tag harus memiliki nilai: ENDIAN_CONSTANT atau REVERSE_ENDIAN_CONSTANT
G7 Untuk masing-masing bagian link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs , dan data , bidang offset dan size harus sama-sama nol atau keduanya bukan nol. Dalam kasus terakhir, offset harus selaras dengan empat byte.
G8 Semua bidang offset di header kecuali map_off harus selaras dengan empat byte.
G9 Bidang map_off harus bernilai nol atau mengarah ke bagian data. Dalam kasus terakhir, bagian data harus ada.
G10 Tak satu pun dari bagian link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs , dan data harus saling tumpang tindih atau header.
G11 Jika ada peta, maka setiap entri peta harus memiliki tipe yang valid. Setiap jenis dapat muncul paling banyak satu kali.
G12 Jika ada peta, maka setiap entri peta harus memiliki offset dan ukuran bukan nol. Offset harus mengarah ke bagian file yang sesuai (yaitu string_id_item harus mengarah ke bagian string_ids ) dan ukuran item secara eksplisit atau implisit harus sesuai dengan konten dan ukuran sebenarnya dari bagian tersebut.
G13 Jika ada peta, maka offset entri peta n+1 harus lebih besar atau sama dengan offset entri peta n plus than size of map entry n . Hal ini berarti entri yang tidak tumpang tindih dan pengurutan dari rendah ke tinggi.
G14 Jenis entri berikut harus memiliki offset selaras empat byte: 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 Untuk setiap string_id_item , kolom string_data_off harus berisi referensi yang valid ke bagian data . Untuk string_data_item yang direferensikan, bidang data harus berisi string MUTF-8 yang valid, dan utf16_size harus cocok dengan panjang string yang didekodekan.
G16 Untuk setiap type_id_item , bidang descriptor_idx harus berisi referensi yang valid ke dalam daftar string_ids . String yang direferensikan harus berupa deskriptor tipe yang valid.
G17 Untuk setiap proto_id_item , bidang shorty_idx harus berisi referensi yang valid ke dalam daftar string_ids . String yang direferensikan harus berupa deskriptor pendek yang valid. Selain itu, bidang return_type_idx harus berupa indeks yang valid pada bagian type_ids , dan bidang parameters_off harus berupa nol atau offset valid yang mengarah ke bagian data . Jika bukan nol, daftar parameter tidak boleh berisi entri kosong apa pun.
G18 Untuk setiap field_id_item , bidang class_idx dan type_idx harus berupa indeks yang valid ke dalam daftar type_ids . Entri yang direferensikan oleh class_idx harus berupa tipe referensi non-array. Selain itu, kolom name_idx harus menjadi referensi yang valid ke bagian string_ids , dan konten entri yang direferensikan harus sesuai dengan spesifikasi MemberName .
G19 Untuk setiap method_id_item , bidang class_idx harus berupa indeks yang valid di bagian type_ids , dan entri yang direferensikan harus berupa tipe referensi non-array. Bidang proto_id harus menjadi referensi yang valid ke dalam daftar proto_ids . Bidang name_idx harus menjadi referensi yang valid ke bagian string_ids , dan konten entri yang direferensikan harus sesuai dengan spesifikasi MemberName .
G20 Untuk setiap field_id_item , bidang class_idx harus berupa indeks yang valid ke dalam daftar type_ids . Entri yang direferensikan harus berupa tipe referensi non-array.

Batasan bytecode statis

Batasan statis adalah batasan pada masing-masing elemen bytecode. Mereka biasanya dapat diperiksa tanpa menggunakan teknik kontrol atau analisis aliran data.

Pengidentifikasi Keterangan
A1 Array insns wajib diisi.
A2 Opcode pertama dalam array insns harus memiliki indeks nol.
A3 Array insns hanya boleh berisi opcode Dalvik yang valid.
A4 Indeks instruksi n+1 harus sama dengan indeks instruksi n ditambah panjang instruksi n , dengan mempertimbangkan kemungkinan operan.
A5 Instruksi terakhir dalam array insns harus diakhiri pada indeks insns_size-1 .
A6 Semua target goto dan if-<kind> harus berupa opcode dalam metode yang sama.
A7 Semua target dari instruksi packed-switch harus berupa opcode dalam metode yang sama. Ukuran dan daftar target harus konsisten.
A8 Semua target instruksi sparse-switch harus berupa opcode dalam metode yang sama. Tabel terkait harus konsisten dan diurutkan dari rendah ke tinggi.
A9 Operan B dari instruksi const-string dan const-string/jumbo harus berupa indeks yang valid ke dalam kumpulan konstanta string.
A10 Operan C dari instruksi iget<kind> dan iput<kind> harus berupa indeks yang valid ke dalam kumpulan konstanta bidang. Entri yang direferensikan harus mewakili bidang contoh.
A11 Operan C dari instruksi sget<kind> dan sput<kind> harus berupa indeks yang valid ke dalam kumpulan konstanta bidang. Entri yang direferensikan harus mewakili bidang statis.
A12 Operan C dari instruksi invoke-virtual , invoke-super , invoke-direct dan invoke-static harus berupa indeks yang valid ke dalam kumpulan konstanta metode.
A13 Operan B dari instruksi invoke-virtual/range , invoke-super/range , invoke-direct/range , dan invoke-static/range harus berupa indeks yang valid ke dalam kumpulan konstanta metode.
A14 Metode yang namanya dimulai dengan '<' hanya boleh dipanggil secara implisit oleh VM, bukan dengan kode yang berasal dari file .dex . Satu-satunya pengecualian adalah penginisialisasi instance, yang dapat dipanggil oleh invoke-direct .
A15 Operan C dari instruksi invoke-interface harus berupa indeks yang valid ke dalam kumpulan konstanta metode. method_id yang direferensikan harus milik antarmuka (bukan kelas).
A16 Operan B dari instruksi invoke-interface/range harus berupa indeks yang valid ke dalam kumpulan konstanta metode. method_id yang direferensikan harus milik antarmuka (bukan kelas).
A17 Operan B dari const-class , check-cast , new-instance , filled-new-array/range harus berupa indeks yang valid ke dalam kumpulan konstanta tipe.
A18 Operan C dari instruksi instance-of , new-array , dan filled-new-array harus berupa indeks yang valid ke dalam kumpulan konstanta tipe.
A19 Dimensi array yang dibuat oleh instruksi new-array harus kurang dari 256 .
A20 Instruksi new tidak boleh mengacu pada kelas array, antarmuka, atau kelas abstrak.
A21 Tipe yang diacu oleh instruksi new-array haruslah tipe non-referensi yang valid.
A22 Semua register yang dirujuk oleh instruksi dengan cara lebar tunggal (non-pasangan) harus valid untuk metode saat ini. Artinya, indeksnya harus non-negatif dan lebih kecil dari registers_size .
A23 Semua register yang dirujuk oleh instruksi dengan lebar ganda (berpasangan) harus valid untuk metode saat ini. Artinya, indeksnya harus non-negatif dan lebih kecil dari registers_size-1 .
A24 Operan method_id dari instruksi invoke-virtual dan invoke-direct harus milik suatu kelas (bukan antarmuka). Dalam file Dex sebelum versi 037 hal yang sama juga berlaku untuk instruksi invoke-super dan invoke-static .
A25 Operan method_id dari instruksi invoke-virtual/range dan invoke-direct/range harus milik suatu kelas (bukan antarmuka). Dalam file Dex sebelum versi 037 hal yang sama juga berlaku untuk instruksi invoke-super/range dan invoke-static/range .

Batasan bytecode struktural

Batasan struktural adalah batasan hubungan antara beberapa elemen bytecode. Mereka biasanya tidak dapat diperiksa tanpa menggunakan teknik kontrol atau analisis aliran data.

Pengidentifikasi Keterangan
B1 Jumlah dan jenis argumen (register dan nilai langsung) harus selalu sesuai dengan instruksi.
B2 Pasangan register tidak boleh dipecah.
B3 Sebuah register (atau pasangan) harus ditetapkan terlebih dahulu sebelum dapat dibaca.
B4 Instruksi invoke-direct harus memanggil penginisialisasi instance atau metode hanya di kelas saat ini atau salah satu superkelasnya.
B5 Penginisialisasi instance harus dipanggil hanya pada instance yang belum diinisialisasi.
B6 Metode instance hanya dapat dipanggil pada dan field instance hanya dapat diakses pada instance yang sudah diinisialisasi.
B7 Register yang menyimpan hasil dari instruksi new-instance tidak boleh digunakan jika instruksi new-instance yang sama dieksekusi lagi sebelum instance diinisialisasi.
B8 Penginisialisasi instance harus memanggil penginisialisasi instance lain (kelas atau superkelas yang sama) sebelum anggota instance mana pun dapat diakses. Pengecualian adalah bidang instance yang tidak diwarisi, yang dapat ditetapkan sebelum memanggil penginisialisasi lain, dan kelas Object secara umum.
B9 Semua argumen metode aktual harus sesuai dengan penugasan dengan argumen formal masing-masing.
B10 Untuk setiap pemanggilan metode instance, instance sebenarnya harus kompatibel dengan penugasan dengan kelas atau antarmuka yang ditentukan dalam instruksi.
B11 Instruksi return<kind> harus cocok dengan tipe pengembalian metodenya.
B12 Saat mengakses anggota superkelas yang dilindungi, tipe sebenarnya dari instance yang diakses harus berupa kelas saat ini atau salah satu subkelasnya.
B13 Jenis nilai yang disimpan ke dalam bidang statis harus kompatibel dengan penugasan atau dapat dikonversi ke jenis bidang tersebut.
B14 Tipe nilai yang disimpan ke dalam kolom harus kompatibel dengan penugasan atau dapat dikonversi ke tipe kolom.
B15 Tipe setiap nilai yang disimpan ke dalam array harus sesuai dengan penugasan dengan tipe komponen array.
B16 Operan A throw instruksi harus kompatibel dengan penugasan java.lang.Throwable .
B17 Instruksi terakhir yang dapat dijangkau dari suatu metode harus berupa instruksi goto atau cabang mundur, return , atau throw . Tidak mungkin meninggalkan susunan insns di bagian bawah.
B18 Setengah dari pasangan register sebelumnya yang belum ditetapkan tidak dapat dibaca (dianggap tidak valid) sampai ia ditugaskan kembali oleh beberapa instruksi lain.
B19 Instruksi move-result<kind> harus segera didahului (dalam array insns ) dengan instruksi invoke-<kind> . Satu-satunya pengecualian adalah instruksi move-result-object , yang juga dapat didahului dengan instruksi filled-new-array .
B20 Instruksi move-result<kind> harus segera didahului (dalam aliran kontrol sebenarnya) dengan instruksi return-<kind> yang cocok (tidak boleh dilompati). Satu-satunya pengecualian adalah instruksi move-result-object , yang juga dapat didahului dengan instruksi filled-new-array .
B21 Instruksi move-exception harus muncul hanya sebagai instruksi pertama dalam pengendali pengecualian.
B22 Instruksi semu packed-switch-data , sparse-switch-data , dan fill-array-data tidak boleh dijangkau oleh aliran kontrol.