Flutter零碎

Flutter零碎(一)如何从apk中还原flutter源码?



零、背景描述

一个Flutter APP遗留项目,前同事留下了一堆源码,没有说明文档。项目分别编译成了Android版和iOS版,平时用户也就那么几个,所以不太关注。

最近有一些新需求要添加,好不容易搞定了Gradle版本和插件版本不兼容问题、各种库的冲突问题、Maven依赖问题……把源码折腾得能跑了,用了2周时间把新功能也上线了。

就在以为可以万事大吉的时候,电脑网卡坏了。一通操作后,恩,电脑很顺利的不能进入操作系统了。重做系统时,我那1000度的近视顺利让我把存放源码的磁盘分区格式化了。

不过源码在gitlab上是有备份的,恢复源码一看,新加的功能没有及时上传gitlab,源码和APP差了两次重要更新,难道要再花2周时间搞一次?问题是新需求随时有可能来,时间也不允许呀?

所以,还是要想办法恢复源码,反编译了解一下。iOS版app的反编译不知道有没有人搞过,反正我没有。所以果断选择android的apk反编译。(其实apk的反编译也没搞过_


一、apktool了解一下

据说,apktool可以从apk中完整的提取出resource、dex、manifest、xml等文件,还可以把这些文件重新打包成一个apk。我只需要它可以提取源码就心满意足了,至于其它功能,以后用到了再研究。

apktool在github和gitee上都可以下载到,地址如下(尽量走官方渠道,你懂的):
github地址
gitee地址

随便哪个地址,下载最新版的apktool,我下载的版本是v2.6.1:
在这里插入图片描述

二、apktool使用步骤

1.获取apktool的帮助信息

进入apktool所在目录,在命令行中运行:java -jar apktool_2.6.1.jar

>java -jar apktool_2.6.1.jar 
Apktool v2.6.1 - a tool for reengineering Android apk files
with smali v2.5.2 and baksmali v2.5.2
Copyright 2010 Ryszard Wi?niewski <brut.alll@gmail.com>
Copyright 2010 Connor Tumbleson <connor.tumbleson@gmail.com>

usage: apktool
 -advance,--advanced   prints advance information.
 -version,--version    prints the version then exits
usage: apktool if|install-framework [options] <framework.apk>
 -p,--frame-path <dir>   Stores framework files into <dir>.
 -t,--tag <tag>          Tag frameworks using <tag>.
usage: apktool d[ecode] [options] <file_apk>
 -f,--force              Force delete destination directory.
 -o,--output <dir>       The name of folder that gets written. Default is apk.out
 -p,--frame-path <dir>   Uses framework files located in <dir>.
 -r,--no-res             Do not decode resources.
 -s,--no-src             Do not decode sources.
 -t,--frame-tag <tag>    Uses framework files tagged by <tag>.
usage: apktool b[uild] [options] <app_path>
 -f,--force-all          Skip changes detection and build all files.
 -o,--output <dir>       The name of apk that gets written. Default is dist/name.apk
 -p,--frame-path <dir>   Uses framework files located in <dir>.

For additional info, see: https://ibotpeaches.github.io/Apktool/
For smali/baksmali info, see: https://github.com/JesusFreke/smali

其它命令先不管,重点关注以下这段:

usage: apktool d[ecode] [options] <file_apk>
 -f,--force              Force delete destination directory.
 -o,--output <dir>       The name of folder that gets written. Default is apk.out
 -p,--frame-path <dir>   Uses framework files located in <dir>.
 -r,--no-res             Do not decode resources.
 -s,--no-src             Do not decode sources.
 -t,--frame-tag <tag>    Uses framework files tagged by <tag>.

先看用法里的d,表示 解码,即反编译,最后要跟一个apk文件。要把反编译的文件输出到一个目录下,还需要一个-o <dir>选项。

2.反编译apk

为了操作方便,把apktool_2.6.1.jar和V1.0.17_27_2022_05_10_16_42_21_debug.apk放到同一个目录下,通过命令行进入到该目录下,运行如下命令:

>java -jar apktool_2.6.1.jar d -o ./source ./V1.0.17_27_2022_05_10_16_42_21_debug.apk
I: Using Apktool 2.6.1 on V1.0.17_27_2022_05_10_16_42_21_debug.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: \apktool\framework\1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Baksmaling classes17.dex...
I: Baksmaling classes7.dex...
I: Baksmaling classes6.dex...
I: Baksmaling classes10.dex...
I: Baksmaling classes11.dex...
I: Baksmaling classes9.dex...
I: Baksmaling classes12.dex...
I: Baksmaling classes8.dex...
I: Baksmaling classes4.dex...
I: Baksmaling classes13.dex...
I: Baksmaling classes5.dex...
I: Baksmaling classes14.dex...
I: Baksmaling classes15.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes16.dex...
I: Baksmaling classes3.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

将源文件提取到同一个目录下的source文件夹里,如下图所示:
在这里插入图片描述

Flutter的源码在assets/flutter_assets/kernel_blob.bin中,不要问我怎么知道的,也不要问我为什么。反正我就是知道。

在这里插入图片描述

3.提取源码

kernel_blob.bin是一个二进制的文件,不知道大家有没有更好的办法来提取源码,我用的是strings,一个字符串分析工具。
下载地址

用法:
 strings [-a] [-f offset] [-b bytes] [-n length] [-o] [-q] [-s] [-u] <file or directory>

-a 仅限 Ascii 的搜索 (Unicode 和 Ascii 是默认)  
-b 要扫描的文件字节数 
-f 开始扫描的文件偏移量。 
-o 文件字符串中的打印偏移量已找到 
-n 默认值为 3) 的最小字符串长度 ( 
-s Recurse 子目录 
-u 仅 Unicode 搜索 (Unicode 和 Ascii 默认为)  
-nobanner 不显示启动横幅和版权消息。 

kernel_blob.bin拷贝到strings.exe同一目录下,运行以下命令:

>strings.exe -a ./kernel_blob.bin > demo.dart

Strings v2.54 - Search for ANSI and Unicode strings in binary images.
Copyright (C) 1999-2021 Mark Russinovich
Sysinternals - www.sysinternals.com

将源码提取到demo.dart文件中,不知道为什么?我提取出来的源码存在大量乱码,猜测可能是源码文件中存在大量中文注释无法正常显示。

接下来就可以用import、dart、main或者其它你记得的类名去demo.dart中定位源码了。

推荐使用notepad++搜索源码,飞快。
在这里插入图片描述


三、总结

本文简单介绍了如何通过apktool、strings等工具从调试版的apk中提取flutter源码的过程。也算是一次不大不小的教训和警示,以后在开发过程中一定要及时上传更新的源码。

留四个问题给自己(慢慢琢磨):
1.如何从发布版的apk中提取源码?
2.恢复的源码文件中所有中文备注都变成了乱码,怎么解决?
3.恢复的源码文件,所有源码都在一个文件里,能不能分开?(可以针对源码做一个分析工具_
4.Flutter源码是如何变成apk安装包的?


本人老李,混迹IT行业10多年,做过程序员、技术经理、项目经理、产品经理,在三家公司担任过CTO。目前在一家民营企业担任技术VP,技术样样通,但门门稀松,算是一个不太正经的ITer。平时喜欢研究一些小问题,喜欢和人聊天,vx:kj3115526。欢迎大家找我交流。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值