Flutter逆向系列-文件格式研究

简介

Flutter的逆向主要集中在如何反编译出源代码,解决这个问题需要先了解snapshots的文件格式,并能解析所有Objects。

旧版本的snapshots是独立存储在assets目录下,新版本的snapshots直接融合在libapp.so中,因此本文的研究重点将集中于libapp.so,而flutter运行引擎代码则位于libflutter.so中.

基础知识

Dart基础

Dart代码运行在isolate中

  • isolate
    • heap 内存管理,包括分配、垃圾回收等
    • objects 运行时对象、代码、数据等

运行方式

  • AOT
    • release版本,使用snapshot
  • JIT
    • debug版本,使用源代码
整数编码

编码方式: LEB128

例子:

0x4e46 8301 826d 9900

  1. 读取bytes,直到读取的值大于0x7F
    • 0x4e 46 83
  2. 反转bytes
    • 0x83 46 4e
    • 10000011 01000110 01001110
  3. 删除二进制的最高位
    • 0000011 1000110 1001110
  4. 转换成十进制
    • 58190 unsigned int
    • 58190 int 最高位决定正负
架构布局

libapp.so包含两个snapshots,分别包含代码段和数据段(heap)

  • VM isolate snapshots

    • _kDartVmSnapshotInstructions
    • _kDartVmSnapshotData
  • APP isolate snapshots

    • _kDartIsolateSnapshotInstructions
    • _kDartIsolateSnapshotData
libapp.so
├── ...
│
├── .text
│   └── _kDartVmSnapshotInstructions
├── .rodata
│   └── _kDartVmSnapshotData
├── .text.2
│   └── _kDartIsolateSnapshotInstructions
└── .rodata.2
    └── _kDartIsolateSnapshotData

Snapshot文件格式

Header 头部
OffsetTypeNameDescription
04Magic numbersnapshots的标志头,常量 0xf5f5dcdc
48SizeELF文件中snapshots的大小,以字节为单位
128Kind一个数字,用来标识snapshots的种类
2032Version使用的编译器版本,由make_version.py生成
52stringFeatures以Null结尾的特征字符串,它们用于标识snapshots是生产版本还是调试版本
unku_intBase objects基本对象的数量,由clustered_snapshot.cc的AddBaseObjects中定义
unku_intObjects对象的数量
unku_intClustersClusters的数量
unku_intField table length字段表的数量
Object serialization 对象序列化

对象序列化,对于每个Dart对象都可以分解为一组固定的字段,每个字段都有一个确定的值或者是对另一个对象的引用。序列化的过程,每个Dart对象都会为其分配一个ID

例子: 假设Mint的可视化编程为下面伪代码

class Mint{
	bool isCanonical;   //标志是否是规范化的值
	long values;        //具体的值
}

--> 值为7的非规范Mint对象的序列化为: 0x00 87

class Array {
    int length;
    bool isCanonical;
    TypeArguments typeArguments; // 对类型为TypeArguments对象的引用
    Object[length] data;  //对象引用的数组
}

假设:
--> Array[0] = Mint(7)
--> Array[1] = Mint(12)
--> Mint(7) 对象序列化ID=2
--> Mint(12) 对象序列化ID=3
则:
--> Array非规范化序列化为: 0x 82 00 81 82 83
  1. 怎么理解每一个Dart对象所处的内存布局?
  2. 怎么理解一段hex数据分别解析出每一个dart对象?
Clusters 对象族

Clusters是snapshot中共享通用Dart类型的一组对象。 在序列化过程中,Clusters按顺序序列化,并且每个簇都负责序列化其中的每个对象。可以理解为按Clusetrs进行序列化和反序列化。

Clusters序列化过程 clustered_snapshot.cc

  • Trace
    • 基本信息初始化
  • alloc
    • 遍历所有Clusters,并将reference ID分配给它们包含的每个对象,以及序列化有关的每个Clusters的基本信息。 通常,此基本信息只是Clusters的class ID,以及该Clusters包含的对象数或类似的信息
  • fill
    • 遍历所有Clusters,序列化其中的每个对象
Code objects 代码对象

Dart对象Code类型,其主要指向代码的偏移地址。

参考

[译]Android环境下的Flutter逆向工程
Reverse engineering Flutter for Android

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值