Skip to content

📐 Dalvik 指令格式体系

dexlib2 将 Dalvik 指令格式系统化地编码为 Format 枚举,并为每种格式提供 iface/instruction/formats/ 下的接口约束和 immutable/instruction/ 下的实现。

格式命名解码

格式名 FormatABC 中:

位置含义示例
A指令字节数 / 2(即 code unit 数)1 = 2字节,2 = 4字节,3 = 6字节
B寄存器规格0=无,1=1个,2=2个,x=无寄存器,r=寄存器范围
C操作数类型x=无,c=常量池引用,s=有符号立即数,t=跳转偏移,i=立即数

完整格式速查表

格式字节寄存器额外操作数典型指令
10x20nop, return-void
10t208-bit 偏移goto
11n214-bit 立即数const/4
11x21return, throw, monitor-enter
12x22move, neg-int, array-length
20t4016-bit 偏移goto/16
21c4116-bit 引用const-string, new-instance, sget
21s4116-bit 有符号整数const/16, const-wide/16
21t4116-bit 跳转偏移if-eqz, if-nez
22c4216-bit 引用instance-of, iget, iput
22s4216-bit 有符号整数add-int/lit16
22t4216-bit 跳转偏移if-eq, if-ne, if-lt
22x42move/from16
23x43add-int, aget, aput
30t6032-bit 偏移goto/32
31c6132-bit 引用const-string/jumbo
31i6132-bit 整数const, const-wide/32
31t6132-bit 偏移packed-switch, sparse-switch, fill-array-data
35c6最多516-bit 引用invoke-virtual, invoke-static, invoke-direct
3rc6范围16-bit 引用invoke-virtual/range, filled-new-array/range
51l10164-bit 字面量const-wide

iface/instruction/formats 接口层

每种格式在 iface/instruction/formats/ 下都有对应接口,声明该格式特有的操作数 getter:

java
// Instruction21c.java
public interface Instruction21c extends OneRegisterInstruction, ReferenceInstruction {
    // 继承自 OneRegisterInstruction: int getRegisterA()
    // 继承自 ReferenceInstruction: Reference getReference(), int getReferenceType()
}

// Instruction35c.java
public interface Instruction35c extends FiveRegisterInstruction, ReferenceInstruction {
    // 继承自 FiveRegisterInstruction:
    // int getRegisterCount(), getRegisterC/D/E/F/G()
}

指令格式与寄存器编号范围

格式寄存器编号范围说明
1x(nibble)0~154-bit 编码
1x(byte)0~2558-bit 编码
2x(short)0~6553516-bit 编码,move/from16
35c0~15每个寄存器 4-bit
3rc0~6553516-bit startRegister

ZjDroid 中的格式判断

在遍历方法体时,通过 instruction.getOpcode().formatinstanceof 检查快速判断格式,然后强转为对应接口取操作数:

java
if (instruction instanceof Instruction21c) {
    Reference ref = ((Instruction21c) instruction).getReference();
}

📌 小结

理解 Dalvik 指令格式体系是理解 dexlib2 指令模型、InstructionWriter 写出逻辑和 MethodAnalyzer 分析逻辑的基础。ZjDroid 在 smali 重建和脱壳输出阶段,需要正确处理每种格式的操作数才能生成语义正确的 .smali 文件。

格式命名解码与接口分层

基于 MIT 协议发布 · 本文档仅用于安全研究与教学目的