Skip to content

🧩 Adaptors — smali 文本生成层

Adaptors 包是 baksmali 的核心输出层,包含所有负责将 dexlib2 数据结构转换为 smali 文本的"适配器"类。


📦 包结构

Adaptors/
├── MethodItem.java                   # 抽象基类(所有 smali 行元素)
├── LabelMethodItem.java              # :label_xxxx
├── BlankMethodItem.java              # 空行分隔
├── CommentMethodItem.java            # # 注释行
├── CommentedOutMethodItem.java       # 整块注释(包裹另一个 MethodItem)
├── CatchMethodItem.java              # .catch / .catchall
├── EndTryLabelMethodItem.java        # :try_end_xxxx
├── SyntheticAccessCommentMethodItem  # 访问器注释
├── PreInstructionRegisterInfoMethodItem  # 寄存器分析前注释
├── PostInstructionRegisterInfoMethodItem # 寄存器分析后注释
├── ClassDefinition.java              # 类级别输出
├── MethodDefinition.java             # 方法级别输出(含 LabelCache)
├── FieldDefinition.java              # 字段定义
├── AnnotationFormatter.java          # .annotation 块
├── RegisterFormatter.java            # v0 / p0 格式转换
├── ReferenceFormatter.java           # 字符串引用转义
├── CommentingIndentingWriter.java    # 将输出包装为注释
├── Format/                           # 指令格式子包
│   ├── InstructionMethodItem.java        # 核心(30+ 格式分支)
│   ├── InstructionMethodItemFactory.java # 分发工厂
│   ├── OffsetInstructionFormatMethodItem # 带偏移指令(goto/if)
│   ├── PackedSwitchMethodItem.java       # .packed-switch
│   ├── SparseSwitchMethodItem.java       # .sparse-switch
│   ├── ArrayDataMethodItem.java          # .array-data
│   └── UnresolvedOdexInstructionMethodItem
├── Debug/                            # 调试信息子包
│   ├── DebugMethodItem.java          # 工厂基类
│   ├── StartLocalMethodItem.java     # .local
│   ├── EndLocalMethodItem.java       # .end local
│   ├── RestartLocalMethodItem.java   # .restart local
│   ├── LineNumberMethodItem.java     # .line
│   ├── SetSourceFileMethodItem.java  # .source(运行时覆盖)
│   ├── BeginEpilogueMethodItem.java  # .epilogue
│   ├── EndPrologueMethodItem.java    # .prologue(结束)
│   └── LocalFormatter.java           # 变量名/类型格式化
└── EncodedValue/                     # 编码常量值子包
    ├── EncodedValueAdaptor.java          # 分发路由
    ├── AnnotationEncodedValueAdaptor.java # 注解值(嵌套)
    └── ArrayEncodedValueAdaptor.java      # 数组值

🏛️ 核心抽象:MethodItem

所有方法体内的文本元素(指令、标签、catch、debug info)都继承自 MethodItem

java
public abstract class MethodItem implements Comparable<MethodItem> {
    protected final int codeAddress;   // 字节码偏移(用于排序)

    public abstract double getSortOrder();  // 同地址时的次级排序键
    public abstract boolean writeTo(IndentingWriter writer) throws IOException;

    public int compareTo(MethodItem methodItem) {
        int result = ((Integer) codeAddress).compareTo(methodItem.codeAddress);
        if (result == 0){
            return ((Double)getSortOrder()).compareTo(methodItem.getSortOrder());
        }
        return result;
    }
}

各子类的 sortOrder 值设计:

类型sortOrder含义
BeginEpilogueMethodItem-4在大多数元素之前
EndPrologueMethodItem-4同上
SetSourceFileMethodItem-3源文件指令
LineNumberMethodItem-2行号
StartLocalMethodItem-1局部变量开始
LabelMethodItem0标签
CommentMethodItem负数注释(可配置)
InstructionMethodItem100普通指令
CatchMethodItem102catch 指令(在指令之后)

🗺️ 调用关系图


📋 子页面导航

页面说明
MethodItem所有方法体元素的抽象基类
InstructionMethodItem核心指令渲染,覆盖 30+ DEX 格式
InstructionMethodItemFactory按指令类型分发到具体 Item
DebugMethodItem调试信息工厂与各 debug Item
CatchMethodItemtry/catch 块渲染
RegisterFormatter寄存器格式转换器
EncodedValueAdaptor常量/注解值渲染路由

与 ZjDroid 的连接

ZjDroid 的 DexFileBuilder 在重新汇编修改后的 smali 时,生成的文本格式就由这套 Adaptors 决定。理解 Adaptors 输出格式,有助于排查脱壳后 smali 无法重汇编的问题。

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