让 Blutter 支持 Windows Flutter:从 app.so 到 IDA 符号导出
Windows Flutter 桌面端逆向手记 · Blutter 适配思路与落地
本文记录把 Blutter 适配到 Windows Flutter 的思路和落地过程:从 data\app.so 特征,到 IDA 无符号困境,再到复用 Dart VM 导出符号。项目仍是可用 MVP,欢迎大佬接着完善。
学习研究用途,请支持正版。
一、起因:Windows 版小黄鸟也是 Flutter
我在逆向 Windows 版本「小黄鸟」过程中发现:这东西是 Flutter 写的,而且还是 Windows 桌面端。
特征很直接——在 data 目录下能看到 app.so:
图 1 data 目录:app.so / flutter_assets / icudtl.dat
二、问题:资料少,直接扔进 IDA 也读不动
网络上关于 Windows 版 Flutter 逆向的描述很少,几乎没什么现成工具和资料。但核心位置都在 app.so。
逆向这东西万变不离其宗:找到下手目标,用 IDA 打开、用 x64dbg 打开,直接逆就行了。可是用 IDA 打开后就发现——
图 2 IDA 打开 app.so:满屏 sub_xxx,几乎看不到可读字符串和系统 API
可以看到图上基本上都是一堆指针、函数,压根见不到什么字符串和系统函数。
原因: app.so 是 Dart 代码编译打包成目标平台的原生机器码。里面内容虽然是我们熟悉的汇编,但语义上却是当初那份 Dart 逻辑——大白话就是「用汇编来表达 Dart」。没有我们熟悉的符号表,东西全埋在 Dart 逻辑里。
三、加载流程与 AOT / 快照
3.1 加载流程
Windows Flutter 应用大致是这样跑起来的:
MyApp.exe
↓ 加载
flutter_windows.dll ← Flutter 引擎(里面带 Dart VM)
↓ 读取 / 映射
data\app.so ← Dart AOT 快照(代码 + 对象数据)
3.2 Dart 的两种执行方式
平时 Dart 有两种执行方式(这两种在 Java 里也经常见到):
JIT(Just-In-Time,调试模式)
Dart 源码 → 编译成 Dart 字节码 → 运行时由 Dart VM 边解释边编译成机器码。这就是为什么 flutter run 调试时支持热重载——代码还是「活」的,可以在运行时替换。
AOT(Ahead-of-Time,release 模式)
在打包构建阶段(flutter build),直接把所有 Dart 代码提前编译成目标平台的原生机器码(ARM64 / x64),而不是等到运行时才编译。app.so 装的就是这份编译结果。
快照(Snapshot)
把 Dart VM(Dart 语言的运行环境)运行时的一部分状态「冻结」并序列化到磁盘上;下次加载可以不用从头解析,直接把这块内存映射进来就能用。
所以要逆向,就得先把符号弄出来再导入 IDA,可读性才能上去;不然哪怕上 x64dbg,也经常无从下手。
四、思路:别重写,改现成框架
这时候问题来了:网上很少有 Windows Flutter 的资料。哪怕有 Blutter 可以把符号导出,它也不支持 Windows 版本。
我的思路是:尽量在现成框架上改,而不是自己从头搓。这个思路我觉得是通用的——缺工具时,先找个近似工具,在它的基础上改。
既然要改,就得先搞清楚两个问题:
- Blutter 的运行原理是什么?
- 为什么它不能支持 Windows 版 Flutter 的符号导出?
这两个问题想通了,就能写出我们想要的东西。
4.1 Blutter 一句话原理
拉一份同版本的 Dart VM,把 app.so 加载进来,再把里面的对象和代码符号全部导出来。
4.2 为什么原版进不了 Windows
不支持 Windows 的原因很简单:整条流水线都按 Android arm64 写死了,Windows 连门都进不去。
但要支持 Windows,不等于重写 Blutter。很多地方还能复用原有轮子,这能极大减少工作量。
五、落地:跟 AI 分阶段推进
于是我一步步引导 AI:先把思路捋清,再按阶段落地。(说话习惯会把它当人聊,看到勿怪。)
5.1 梳理思路与拆阶段
图 3 结论先说:值不值得 fork、是不是小改、最大坑在哪
图 4 继续对齐:Windows 路径、产物形态与可复用点
图 5 把改造拆成可落地的实现阶段
5.2 跑起来之后
开始实际运行之后:
图 6 构建 / 加载主路径开始跑通
图 7 中间产物与导出结果确认
图 8 继续验证:符号脚本与分析链路
5.3 使用效果:导入前后对比
最后直接拿去用。先看使用前:
图 9 使用前:伪代码里仍是 sub_xxx / v12,几乎没法读
图 10 使用前:函数窗口也是一片匿名符号
再看使用后:
图 11 使用后:出现 AllocateRangeErrorStub 等 Dart VM 语义名
图 12 使用后:批量命名落下,可读性明显提升
这些材料已经足够给 AI 接着分析和完善了。
六、当前水平与项目
这是最终实现到的水平:
图 13 能力对照:可用 MVP,主路径已通,完整体验仍待补齐
项目地址: https://github.com/1903247335/blutter-windows
需要的大佬可以自己拉下来让 AI 继续完善——我人比较懒。
— 完 —