ไฟล์ .dex
เป็นรูปแบบการขนส่งสําหรับไบต์โค้ด Dalvik ไฟล์ต้องมีข้อจำกัดทางไวยากรณ์และความหมายบางอย่างจึงจะเป็นไฟล์ .dex
ที่ถูกต้องได้ และรันไทม์ต้องรองรับเฉพาะไฟล์ .dex ที่ถูกต้องเท่านั้น
ข้อจำกัดทั่วไปเกี่ยวกับความสมบูรณ์ของ .dex
ข้อจำกัดความสมบูรณ์ทั่วไปเกี่ยวข้องกับโครงสร้างที่ใหญ่ขึ้นของไฟล์ .dex
ตามที่อธิบายไว้อย่างละเอียดใน.dex
ตัวระบุ | คำอธิบาย |
---|---|
G1 |
หมายเลข magic ของไฟล์ .dex ต้องเท่ากับ dex\n035\0 สำหรับเวอร์ชัน 35 หรือคล้ายกันสำหรับเวอร์ชันที่ใหม่กว่า
|
G2 |
Checksum ต้องเป็น checksum ของ Adler-32 สำหรับเนื้อหาทั้งหมดของไฟล์ ยกเว้นช่อง magic และ checksum
|
G3 |
ลายเซ็นต้องเป็นแฮช SHA-1 ของเนื้อหาไฟล์ทั้งหมด ยกเว้น magic ,
checksum และ signature
|
G4 |
|
G5 |
|
G6 |
endian_tag ต้องมีค่าเป็น ENDIAN_CONSTANT หรือ REVERSE_ENDIAN_CONSTANT
|
G7 |
สำหรับแต่ละส่วน
ฟิลด์ |
G8 |
ช่องออฟเซตทั้งหมดในส่วนหัวยกเว้น map_off ต้องจัดแนว 4 ไบต์
|
G9 |
ช่อง map_off ต้องเป็น 0 หรือชี้ไปยังส่วนข้อมูล ในกรณีหลัง ส่วน data ต้องมีอยู่
|
G10 |
ส่วน link , string_ids ,
type_ids , proto_ids , field_ids ,
method_ids , class_defs และ data ต้องไม่ทับซ้อนกันหรือทับส่วนหัว
|
G11 | หากมีแผนที่ รายการแผนที่แต่ละรายการต้องมีประเภทที่ถูกต้อง แต่ละประเภทจะปรากฏได้สูงสุด 1 ครั้ง |
G12 |
หากมีแผนที่ รายการแผนที่แต่ละรายการต้องมีออฟเซตและขนาดที่ไม่ใช่ 0 ส่วนออฟเซตต้องชี้ไปยังส่วนที่เกี่ยวข้องของไฟล์ (เช่น string_id_item ต้องชี้ไปยังส่วน string_ids ) และขนาดที่ชัดเจนหรือไม่ชัดเจนของรายการต้องตรงกับเนื้อหาและขนาดจริงของส่วน
|
G13 |
หากมีแผนที่อยู่ ออฟเซ็ตของรายการแผนที่ n+1 ต้องมากกว่าหรือเท่ากับออฟเซ็ตของรายการแผนที่ n plus than size of map entry n ซึ่งหมายความว่ารายการจะไม่ทับซ้อนกันและเรียงจากต่ำไปสูง
|
G14 |
รายการประเภทต่อไปนี้ต้องมีออฟเซตที่สอดคล้องกับการจํานวน 4 ไบต์ 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 สตริงที่อ้างอิงต้องเป็นตัวบ่งชี้ Shorty ที่ถูกต้อง นอกจากนี้ ฟิลด์ return_type_idx ต้องเป็นดัชนีที่ถูกต้องในส่วน type_ids และฟิลด์ parameters_off ต้องเป็น 0 หรือออฟเซตที่ถูกต้องซึ่งชี้ไปยังส่วน data หากไม่ใช่ 0 รายการพารามิเตอร์ต้องไม่มีรายการที่ว่างเปล่า
|
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 ต้องมีดัชนีเป็น 0
|
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 |
รีจิสเตอร์ทั้งหมดที่คำสั่งอ้างอิงในรูปแบบความกว้าง 2 เท่า (คู่) ต้องถูกต้องสำหรับเมธอดปัจจุบัน กล่าวคือ ดัชนีของรายการต้องไม่ติดลบและน้อยกว่า 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
|
B9 | อาร์กิวเมนต์จริงของเมธอดทั้งหมดต้องเข้ากันได้กับการกําหนดค่ากับอาร์กิวเมนต์อย่างเป็นทางการที่เกี่ยวข้อง |
บีเท็น | สำหรับการเรียกใช้เมธอดอินสแตนซ์แต่ละครั้ง อินสแตนซ์จริงต้องเข้ากันได้กับการกำหนดค่าของคลาสหรืออินเทอร์เฟซที่ระบุไว้ในวิธีการ |
B11 |
คำสั่ง return<kind> ต้องตรงกับประเภทผลลัพธ์ของเมธอด
|
วิตามินบี 12 | เมื่อเข้าถึงสมาชิกที่ได้รับการปกป้องของซุปเปอร์คลาส ประเภทจริงของอินสแตนซ์ที่เข้าถึงต้องเป็นคลาสปัจจุบันหรือคลาสย่อยคลาสใดคลาสหนึ่งของซุปเปอร์คลาสนั้น |
B13 | ประเภทของค่าที่เก็บไว้ในช่องแบบคงที่ต้องเข้ากันได้กับการกำหนดหรือแปลงเป็นประเภทของช่องได้ |
B14 | ประเภทของค่าที่จัดเก็บไว้ในช่องต้องเข้ากันได้กับการกำหนดหรือแปลงเป็นประเภทของช่องได้ |
B15 | ประเภทของค่าทุกค่าที่จัดเก็บไว้ในอาร์เรย์ต้องเข้ากันได้กับประเภทคอมโพเนนต์ของอาร์เรย์ |
B16 |
ออบเจ็กต์ A ของคำสั่ง throw ต้องเข้ากันได้กับ java.lang.Throwable ในแง่ของการกําหนดค่า
|
B17 |
คำสั่งสุดท้ายที่เข้าถึงได้ของเมธอดต้องเป็นคำสั่ง goto ย้อนกลับหรือสาขา, return หรือ throw จะต้องไม่สามารถออกจากอาร์เรย์ insns ที่ด้านล่าง
|
B18 | ระบบจะไม่อ่านครึ่งหนึ่งของคู่รีจิสเตอร์เดิมที่ไม่ได้กำหนด (ถือว่าไม่ถูกต้อง) จนกว่าจะมีการกำหนดใหม่โดยคำสั่งอื่น |
B19 |
คําสั่ง move-result<kind> ต้องอยู่ต่อจาก (ในอาร์เรย์ insns ) คําสั่ง 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 ไม่ได้
|