1 反编译脚本集fox
反编译Android framework/app
需要使用多个逆向工具,为了简化使用、方便维护和部署,模仿 git 命令,编写了一组脚本,这就是 fox 的由来。
1.1 原理概述
1.1.1 格式
- apk
- dex
- odex
- oat
- art
关于dex/odex/oat
格式的一些必要知识点:
- dex 格式是 google 专为其 dalvik 虚拟机设计的格式。
- dex 由 dalvik 虚拟机解释执行,出于性能考虑,google 又开发了 odex 格式,该格式针对 dex 格式做了少许优化,引入了一些特殊指令(这些指令在标准dex格式中是非法的)。
- Android L 之后,google 开了一款新型虚拟机 Android Runtime(简称为 ART)取代 dalvik,同时引入 AOT技术,可以将 dex/odex 转换为 native 代码(ELF 格式),从而大大加快加载速度。并引入了两种新的格式,分别是 oat、art。其中 oat 是一种 elf 变种格式,出于兼容考虑,oat 文件中还内嵌一份 odex 格式代码,可使用第三方工具(如 dextra) 取出;art 格式则是运行时数据,供 ART 虚拟机使用
- Android N ROM 中的 dex、odex、oat 文件本质上都是 oat 格式。也就是说,单纯以后缀名区分实际格式并不准确。请使用
file
命令查看真正格式。
1.1.2 image 格式
- ramdisk 格式
boot.img 和 recovery.img 使用该格式。这是一种只读格式,常用作启动分区。
$ file boot.img
boot.img: Android bootimg, kernel (0x8000), ramdisk (0x2000000), page size: 4096, cmdline (console=null androidboot.hardware=qcom user_debug=31 msm_rtb.fi)
解压/生成该格式 image 可使用https://github.com/xiaolu/mkbootimg_tools
工具
- sparse image 格式
AOSP 编译完成后,out 目录下生成的 system.img/userdata.img/cache.img 等文件都为 sparse 格式,这是一种简单的压缩格式。因为 ext4 格式未经压缩,通常会含有大量的 0 字符填充,浪费存储空间。
ubuntu18.04上,使用file
识别:
file system.img
system.img: Android sparse image, version: 1.0, Total of 896469 4096-byte output blocks in 63 input chunks.```
ubuntu 14.04 上,使用`file`识别:
$ file system.img
system.img: data
说明:由于 ubuntu 14.04 中的`file`包太老,还没有增加对 android sparse 格式支持,附录提供了升级`file`的方法。
解压缩/生成该格式,可使用 AOSP 编译生成的 simg2img 命令将其转换为标准的 ext4 格式,位于`out/host/<linux/darwin/win>-x86/bin/`目录下:
$ simg2img userdata.img userdata.img.ext4
反之,可使用 img2simg 将 ext4 格式 image 转换为 sparse 格式
$ img2simg userdata.img.ext4 userdata.img
3. ext4 格式
$ file system.img
system.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)
这种格式可使用 mount 直接挂载,如下命令将`system.img`挂载到`/mnt`目录下,之后访问`/mnt`目录即可查看(或修改)`system.img`内容。
$ sudo mount -o loop -t ext4 system.img /mnt
### 1.2 安装
$ cd ~
$ git clone https://github.com/eliselong/fox.git
$ mkdir -p ~/bin; cd ~/bin
$ ln -fs ~/fox/fox
说明:一般 Linux 系统(如 ubuntu)默认将`~/bin`加入`PATH`中,如果其他系统,如 macOS,请手动将其加入`PATH`,并确保`fox`命令可以被正确执行。
首次运行`fox`之前,请执行`install`子命令,完成必要安装。
$ fox install
### 1.3 更新
因为`fox`可能存在 bug,更新会比较迅速,请及时执行`update`子命令。确保使用最新代码。
$ git pull
### 1.4 逆向 Android framework
逆向 android framework 需要 /system/framework 目录。可以使用两种方式得到:
- 连接待逆向手机,使用 adb pull /system/framework 得到 framework 目录。
- 从网络下载手机 rom,解压得到 system.img,转换为 ext4 格式,取出其中 framework 目录。
使用`decrom`命令的`all`参数一键逆向 framework
$ fox decrom all your-rom-directory
注意,`your-rom-directory`必须为`framework`目录的父目录,即该目录下必须有`framework`目录。
这里从手机中 pull 出 rom 并逆向的方式为例,整个过程步骤如下:
1. 连接手机,使能 adb 调试
2. pull 出代码
$ mkdir decompile-project; cd decompile-project
$ mkdir rom; cd rom
$ adb pull /system/framework
$ adb pull /system/priv-app
$ adb pull /system/app
3. 执行逆向
$ cd ../
$ mkdir decompile; cd decompile
$ fox decrom app ../rom
接下来生成`AndroidStuido`工程
### 1.5 逆向 app
#### 1.5.1 逆向代码
使用`decrom`命令的 app 参数一键逆向 app
$ fox decrom app your-rom-directory your-rom-app-directory
例如,逆向 SystemUI,假定 rom 目录下有 framework、priv-app、app 三个目录。
$ fox decrom app rom rom/priv-app/SystemUI
即可完成对 SystemUI.apk 的逆向,逆向完成后会自动生成 SystemUI 目录。
jadx 支持 fallback 模式,可以生成后缀为 jadx 的文件,风格类似于 smali,可读性更好。命令如下:
1. `fox decrom all-fallback your-rom-directory`
2. `fox decrom app-fallback your-rom-directory your-rom-app-directory`
#### 1.5.2 逆向资源
`decrom`命令内部使用 jadx 逆向 app,逆向出来的资源效果并不好。这时候可以使用 apktool 逆向资源。经过对比测试,在未保存退出的情况下,apktool 逆向的 app 资源可以直接使用。
更多内容可参考 apktool 官方文档:https://ibotpeaches.github.io/Apktool/documentation/
#### 1.5.3 修复代码
逆向出来的java代码,会出现很多常量,如下:
1. intent action 常量
action.equals(“android.intent.action.SCREEN_OFF”)
2. context service 常量
this.mFingerprintManager = (FingerprintManager) getApplicationContext().getSystemService(“fingerprint”);
3. intent flags 常量
intent.addFlags(268435456);
4. LayoutParams 常量
if ((lp.flags & 4194304) != 0 || (lp.flags & 524288) != 0) {
5. view visibility 常量
textView.setVisibility(8);
6. 其他
`fixsrc`命令可以将 java 代码中的这些常量替换为标准写法。用法如下:
$ fox fixsrc a file1.java file2.java …
批量修复某个目录下所有 java 代码,可使用:
$ find your-java-src -name “*.java” | xargs fox fixsrc a
除此之外,`fixsrc`命令还支持其他参数,分别是:
1. `fox fixsrc f_i <intent-flag-number>`,`intent-flag-number`支持 10/16 进制方式,输入`fox fixsrc f_i 10`查看效果
2. `fox fixsrc f_lp <layoutparams-flag-number>`,同理,不再赘述
## 2 常见反编译工具汇总
- jadx
- jeb
- apktool
- apkdb,http://idoog.me/?p=2933
- baksmali/smali
- dextra,http://newandroidbook.com/tools/dextra.html
- vdexExtractor
- SVADeodexerForArt,https://forum.xda-developers.com/galaxy-s5/general/tool-deodex-tool-android-l-t2972025
### 2.1 JEB
- https://github.com/pnfsoftware/jeb2-plugin-oat/releases
### 2.2 jadx
官方下载:github 搜索 jadx
GitHub 地址为:https://github.com/skylot/jadx
使用 jadx 反编译 Android7.0 会出现错误,拷贝`AOSP/out/host/linux-x86/framework/dx.jar`,覆盖`jadx/lib/dx-1.10.jar`即可。
反编译较大包时,jadx 会卡住,请在 jadx 脚本开头中加入如下代码:
JAVA_OPTS=“-server -Xms1024m -Xmx8192m -XX:PermSize=256m -XX:MaxPermSize=1024m”
基本用法是:
jadx --show-bad-code xxx.apk/xxx.dex
如果逆向被混淆的应用,建议添加`--deobf`参数。
jadx 它也有配套的图形化界面工具-----jadx-gui,这个使用起来更加方便,能直接以图形界面的方式打开一个 apk 文件。同时,jadx-gui 对反编译后得到的 java 代码和其他资源文件增加了高亮支持(就像在 IDE 中打开这些内容一样),还具有快速定位、引用搜索、全文搜索等功能。所以,我们往往直接使用 jadx-gui 完成一些反编译操作。
更多用法参考其自带 help
### 2.3 OTA 提取 dex
#### 2.3.1 dextra(<= Android N1)
官网:http://newandroidbook.com/tools/dextra.html
用法:
dextra.ELF64 -dextract xxx.odex
更多用法参考其自带说明
#### 2.3.2 vdexExtractor(Android O)
官网:https://github.com/anestisb/vdexExtractor
### 2.4 dex 转 smali
baksmali
地址:https://github.com/JesusFreke/smali
## 3 附录
### 3.1 升级 `file` 命令
ubuntu 14.04 自带的 file 版本为 5.14,无法识别很多新的文件类型,如 Android 的 sparse 格式,升级方法如下。
1. 下载 file5.28 deb 包,https://launchpad.net/ubuntu/zesty/amd64/file/1:5.28-2ubuntu1
2. 下载 libmagic1 5.28 deb 包,https://launchpad.net/ubuntu/zesty/amd64/libmagic1/1:5.28-2ubuntu1
sudo dpkg -i 分别安装`libmagic1`与`file`即可。
完整命令如下:
$ wget http://launchpadlibrarian.net/273183617/libmagic1_5.28-2ubuntu1_amd64.deb
$ wget http://launchpadlibrarian.net/273183615/file_5.28-2ubuntu1_amd64.deb
$ sudo dpkg -i libmagic1_5.28-2ubuntu1_amd64.deb
$ sudo dpkg -i file_5.28-2ubuntu1_amd64.deb