Constraints
Constraints
A .dex file is the transport format for Dalvik Bytecode. There are certain syntactical and semantical constraints for a file to be a valid .dex file, and a runtime is required to support only valid .dex files.
General .dex integrity constraints
General integrity constraints are concerned with the larger structure of a .dex file, as described in detail in .dex format.
| Identifier | Description |
|---|---|
| G1 | The magic number of the .dex file must be: dex\n035\0 |
| G2 | The checksum must be an Adler-32 checksum of the whole file contents except magic and checksum field. |
| G3 | The signature must be a SHA-1 hash of the whole file contents except magic, checksum, and signature. |
| G4 | The file_size must match the actual file size in bytes. |
| G5 | The header_size must have the value: 0x70 |
| G6 | The endian_tag must have either the value: ENDIAN_CONSTANT or REVERSE_ENDIAN_CONSTANT |
| G7 | For each of the link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs, and data sections, the offset and size fields must be either both zero or both non-zero. In the latter case, the offset must be four-byte-aligned. |
| G8 | All offset fields in the header except map_off must be four-byte-aligned. |
| G9 | The map_off field must be either zero or point into the data section. In the latter case, the data section must exist. |
| G10 | None of the link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs and data sections must overlap each other or the header. |
| G11 | If a map exists, then each map entry must have a valid type. Each type may appear at most once. |
| G12 | If a map exists, then each map entry must have a non-zero offset and size. The offset must point into the corresponding section of the file (i.e. a string_id_item must point into the string_ids section) and the explicit or implicit size of the item must match the actual contents and size of the section. |
| G13 | If a map exists, then the offset of map entry n+1 must be greater or equal to the offset of map entry n plus than size of map entry n. This implies non-overlapping entries and low-to-high ordering. |
| G14 | The following types of entries must have an offset that is four-byte-aligned: 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 | For each string_id_item, the string_data_off field must contain a valid reference into the data section. For the referenced string_data_item, the data field must contain a valid MUTF-8 string, and the utf16_size must match the decoded length of the string. |
| G16 | For each type_id_item, the descriptor_idx field must contain a valid reference into the string_ids list. The referenced string must be a valid type descriptor. |
| G17 | For each proto_id_item, the shorty_idx field must contain a valid reference into the string_ids list. The referenced string must be a valid shorty descriptor. Also, the return_type_idx field must be a valid index into the type_ids section, and the parameters_off field must be either zero or a valid offset pointing into the data section. If non-zero, the parameter list must not contain any void entries. |
| G18 | For each field_id_item, both the class_idx and type_idx fields must be valid indices into the type_ids list. The entry referenced by class_idx must be a non-array reference type. In addition, the name_idx field must be a valid reference into the string_ids section, and the contents of the referenced entry must conform to the MemberName specification. |
| G19 | For each method_id_item, the class_idx field must be a valid index into the type_ids section, and the referenced entry must be a non-array reference type. The proto_id field must be a valid reference into the proto_ids list. The name_idx field must be a valid reference into the string_ids section, and the contents of the referenced entry must conform to the MemberName specification. |
| G20 | For each field_id_item, the class_idx field must be a valid index into the type_ids list. The referenced entry must be a non-array reference type. |
Static bytecode constraints
Static constraints are constraints on individual elements of the bytecode. They usually can be checked without employing control or data-flow analysis techniques.
| Identifier | Description |
|---|---|
| A1 | The insns array must not be empty. |
| A2 | The first opcode in the insns array must have index zero. |
| A3 | The insns array must contain only valid Dalvik opcodes. |
| A4 | The index of instruction n+1 must equal the index of instruction n plus the length of instruction n, taking into account possible operands. |
| A5 | The last instruction in the insns array must end at index insns_size-1. |
| A6 | All goto and if-<kind> targets must be opcodes within the same method. |
| A7 | All targets of a packed-switch instruction must be opcodes within the same method. The size and the list of targets must be consistent. |
| A8 | All targets of a sparse-switch instruction must be opcodes within the same method. The corresponding table must be consistent and sorted low-to-high. |
| A9 | The B operand of the const-string and const-string/jumbo instructions must be a valid index into the string constant pool. |
| A10 | The C operand of the iget<kind> and iput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent an instance field. |
| A11 | The C operand of the sget<kind> and sput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent a static field. |
| A12 | The C operand of the invoke-virtual, invoke-super, invoke-direct and invoke-static instructions must be a valid index into the method constant pool. In all cases, the referenced method_id must belong to a class (not an interface). |
| A13 | The B operand of the invoke-virtual/range, invoke-super/range, invoke-direct/range, and invoke-static/range instructions must be a valid index into the method constant pool. In all cases, the referenced method_id must belong to a class (not an interface). |
| A14 | A method the name of which starts with a '<' must only be invoked implicitly by the VM, not by code originating from a .dex file. The only exception is the instance initializer, which may be invoked by invoke-direct. |
| A15 | The C operand of the invoke-interface instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class). |
| A16 | The B operand of the invoke-interface/range instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class). |
| A17 | The B operand of the const-class, check-cast, new-instance, and filled-new-array/range instructions must be a valid index into the type constant pool. |
| A18 | The C operand of the instance-of, new-array, and filled-new-array instructions must be a valid index into the type constant pool. |
| A19 | The dimensions of an array created by a new-array instruction must be less than 256. |
| A20 | The new instruction must not refer to array classes, interfaces, or abstract classes. |
| A21 | The type referred to by a new-array instruction must be a valid, non-reference type. |
| A22 | All registers referred to by an instruction in a single-width (non-pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size. |
| A23 | All registers referred to by an instruction in a double-width (pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size-1. |
Structural bytecode constraints
Structural constraints are constraints on relationships between several elements of the bytecode. They usually can't be checked without employing control or data-flow analysis techniques.
| Identifier | Description |
|---|---|
| B1 | The number and types of arguments (registers and immediate values) must always match the instruction. |
| B2 | Register pairs must never be broken up. |
| B3 | A register (or pair) has to be assigned first before it can be read. |
| B4 | An invoke-direct instruction must invoke an instance initializer or a method only in the current class or one of its superclasses. |
| B5 | An instance initializer must be invoked only on an uninitialized instance. |
| B6 | Instance methods may be invoked only on and instance fields may only be accessed on already initialized instances. |
| B7 | A register that holds the result of a new-instance instruction must not be used if the same new-instance instruction is again executed before the instance is initialized. |
| B8 | An instance initializer must call another instance initializer (same class or superclass) before any instance members can be accessed. Exceptions are non-inherited instance fields, which can be assigned before calling another initializer, and the Object class in general. |
| B9 | All actual method arguments must be assignment-compatible with their respective formal arguments. |
| B10 | For each instance method invocation, the actual instance must be assignment-compatible with the class or interface specified in the instruction. |
| B11 | A return<kind> instruction must match its method's return type. |
| B12 | When accessing protected members of a superclass, the actual type of the instance being accessed must be either the current class or one of its subclasses. |
| B13 | The type of a value stored into a static field must be assignment-compatible with or convertible to the field's type. |
| B14 | The type of a value stored into a field must be assignment-compatible with or convertible to the field's type. |
| B15 | The type of every value stored into an array must be assignment-compatible with the array's component type. |
| B16 | The A operand of a throw instruction must be assignment-compatible with java.lang.Throwable. |
| B17 | The last reachable instruction of a method must either be a backwards goto or branch, a return, or a throw instruction. It must not be possible to leave the insns array at the bottom. |
| B18 | The unassigned half of a former register pair may not be read (is considered invalid) until it has been re-assigned by some other instruction. |
| B19 | A move-result<kind> instruction must be immediately preceded (in the insns array) by an invoke-<kind> instruction. The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction. |
| B20 | A move-result<kind> instruction must be immediately preceded (in actual control flow) by a matching return-<kind> instruction (it must not be jumped to). The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction. |
| B21 | A move-exception instruction must appear only as the first instruction in an exception handler. |
| B22 | The packed-switch-data, sparse-switch-data, and fill-array-data pseudo-instructions must not be reachable by control flow. |
本文来自博客园,作者:dolinux,未经同意,禁止转载

浙公网安备 33010602011771号