ไฟล์ .dex
เป็นรูปแบบการขนส่งสำหรับรหัสไบต์ Dalvik มีข้อจำกัดทางวากยสัมพันธ์และความหมายบางประการสำหรับไฟล์ที่จะเป็นไฟล์ .dex
ที่ถูกต้อง และจำเป็นต้องมีรันไทม์เพื่อรองรับเฉพาะไฟล์ .dex ที่ถูกต้องเท่านั้น
ข้อจำกัดความสมบูรณ์ของ .dex ทั่วไป
ข้อจำกัดด้านความสมบูรณ์ทั่วไปเกี่ยวข้องกับโครงสร้างที่ใหญ่กว่าของไฟล์ .dex
ดังที่อธิบายรายละเอียดใน รูปแบบ .dex
ตัวระบุ | คำอธิบาย |
---|---|
G1 | เลข magic ของไฟล์ .dex ต้องเป็น dex\n035\0 หรือ dex\n037\0 |
G2 | เช็คซัมต้องเป็นเช็คซัมของ Adler-32 ของเนื้อหาไฟล์ทั้งหมด ยกเว้นฟิลด์ magic และ checksum |
G3 | ลายเซ็นต้องเป็นแฮช SHA-1 ของเนื้อหาไฟล์ทั้งหมด ยกเว้น magic , checksum และ signature |
G4 | file_size ต้องตรงกับขนาดไฟล์จริงในหน่วยไบต์ |
G5 | header_size ต้องมีค่า: 0x70 |
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 ต้องเป็นทั้งศูนย์หรือทั้งสองไม่เป็นศูนย์ ในกรณีหลัง ออฟเซ็ตจะต้องจัดชิดสี่ไบต์ |
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 สำหรับ 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 | opcode แรกในอาร์เรย์ insns ต้องมีดัชนีเป็นศูนย์ |
A3 | อาร์เรย์ insns ต้องมีเฉพาะ opcode ของ Dalvik ที่ถูกต้องเท่านั้น |
A4 | ดัชนีของคำสั่ง n+1 ต้องเท่ากับดัชนีของคำสั่ง n บวกกับความยาวของคำสั่ง n โดยคำนึงถึงตัวถูกดำเนินการที่เป็นไปได้ |
A5 | คำสั่งสุดท้ายในอาร์เรย์ insns ต้องสิ้นสุดที่ดัชนี insns_size-1 |
A6 | เป้าหมาย goto และ if-<kind> ทั้งหมดต้องเป็น opcodes ภายในวิธีการเดียวกัน |
A7 | เป้าหมายทั้งหมดของคำสั่ง packed-switch ต้องเป็น opcodes ภายในวิธีการเดียวกัน ขนาดและรายการเป้าหมายจะต้องสอดคล้องกัน |
A8 | เป้าหมายทั้งหมดของคำสั่ง sparse-switch ต้องเป็น opcodes ภายในวิธีการเดียวกัน ตารางที่เกี่ยวข้องจะต้องสอดคล้องกันและเรียงลำดับจากต่ำไปสูง |
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 |
ก15 | ตัวถูกดำเนินการ 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 |
ก20 | คำสั่ง new ต้องไม่อ้างอิงถึงคลาสอาร์เรย์ อินเทอร์เฟซ หรือคลาสนามธรรม |
A21 | ประเภทที่อ้างอิงโดยคำสั่ง new-array ต้องเป็นประเภทที่ถูกต้องและไม่ใช่ประเภทอ้างอิง |
A22 | รีจิสเตอร์ทั้งหมดที่อ้างอิงโดยคำสั่งในรูปแบบความกว้างเดียว (ไม่ใช่คู่) จะต้องถูกต้องสำหรับวิธีการปัจจุบัน นั่นคือ ดัชนีจะต้องไม่ติดลบและเล็กกว่า registers_size |
ก23 | รีจิสเตอร์ทั้งหมดที่อ้างอิงโดยคำสั่งในรูปแบบ double-width (คู่) จะต้องถูกต้องสำหรับวิธีการปัจจุบัน นั่นคือ ดัชนีจะต้องไม่ติดลบและเล็กกว่า registers_size-1 |
A24 | ตัวถูกดำเนินการ method_id ของคำสั่ง invoke-virtual และ invoke-direct จะต้องเป็นของคลาส (ไม่ใช่อินเทอร์เฟซ) ในไฟล์ Dex ก่อนหน้าเวอร์ชัน 037 จะต้องเป็นจริงเช่นเดียวกันกับคำสั่ง invoke-super และ invoke-static |
ก25 | ตัวถูกดำเนินการ method_id ของคำสั่ง invoke-virtual/range และ invoke-direct/range จะต้องเป็นของคลาส (ไม่ใช่อินเทอร์เฟซ) ในไฟล์ Dex ก่อนเวอร์ชัน 037 สิ่งเดียวกันจะต้องเป็นจริงสำหรับคำสั่ง invoke-super/range และ invoke-static/range |
ข้อจำกัดของโค้ดไบต์เชิงโครงสร้าง
ข้อจำกัดทางโครงสร้างเป็นข้อจำกัดเกี่ยวกับความสัมพันธ์ระหว่างองค์ประกอบต่างๆ ของโค้ดไบต์ โดยปกติแล้วจะไม่สามารถตรวจสอบได้โดยไม่ต้องใช้เทคนิคการควบคุมหรือการวิเคราะห์กระแสข้อมูล
ตัวระบุ | คำอธิบาย |
---|---|
B1 | จำนวนและประเภทของอาร์กิวเมนต์ (รีจิสเตอร์และค่าทันที) จะต้องตรงกับคำสั่งเสมอ |
บี2 | คู่ทะเบียนจะต้องไม่แตกหัก |
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 | ครึ่งหนึ่งของคู่รีจิสเตอร์เดิมที่ยังไม่ได้กำหนดอาจไม่สามารถอ่านได้ (ถือว่าไม่ถูกต้อง) จนกว่าจะถูกกำหนดใหม่โดยคำสั่งอื่น |
บี19 | คำสั่ง move-result<kind> จะต้องนำหน้าทันที (ในอาร์เรย์ insns ) ด้วยคำสั่ง invoke-<kind> ข้อยกเว้นเพียงอย่างเดียวคือคำสั่ง move-result-object ซึ่งอาจนำหน้าด้วยคำสั่ง filled-new-array |
บี20 | คำสั่ง move-result<kind> จะต้องนำหน้าทันที (ในโฟลว์การควบคุมจริง) ด้วยคำสั่ง return-<kind> ที่ตรงกัน (ต้องไม่ข้ามไป) ข้อยกเว้นเพียงอย่างเดียวคือคำสั่ง move-result-object ซึ่งอาจนำหน้าด้วยคำสั่ง filled-new-array |
บี21 | คำสั่ง move-exception จะต้องปรากฏเป็นคำสั่งแรกในตัวจัดการข้อยกเว้นเท่านั้น |
บี22 | คำสั่ง packed-switch-data , sparse-switch-data และ fill-array-data จะต้องไม่สามารถเข้าถึงได้โดยโฟลว์การควบคุม |