
vdex 文件反编译
发现问题
项目需求的缘故,需要参考合作方系统里某个系统应用的编写,作为挑选技术方案的参考。但对方的代码并不对我们开放,且沟通成本非常高。如果我们恰巧有系统的root权限,那么最快的方法就是反编译这个应用了。
以GE11项目 /system/app/HwCarresmanagerCar 目录下的座舱管家为例,进到这个目录会发现有 HwCarresmanagerCar.apk
文件和 oat
lib
文件夹。
使用 adb pull
将他们拉取到电脑上(需要root权限),再用熟悉的apk反编译工具将EasterEgg.apk
反编译。你会发现反编译出来的内容除了resources
资源目录以外对应代码的sources
目录下只有可怜的两个文件:
代码去哪儿了呢?
分析问题
我们打开oat/arm64
目录,发现两个文件:HwCarresmanagerCar.odex
, HwCarresmanagerCar.vdex
关于这两个文件格式和他们的作用如下:
Odex文件是早期Android版本中用于存储应用程序优化后的机器码的文件格式,而Vdex文件是Android 8.0及更高版本中引入的新格式,用于存储预优化信息,帮助ART在设备上进行更好的优化。 Vdex文件的引入使得ART在应用程序执行时可以更灵活和高效地进行优化,从而提高应用程序的性能。
而这台车机的系统版本为 Android10,所以代码应该在 HwCarresmanagerCar.vdex
文件里。
一般的反编译工具例如 apktool, jadx, d2j, JavaDecompiler 是针对没有经过优化的原始字节码dex文件进行反编译的,遇到odex/vdex这种机器码格式就无能为力了。
解决问题
万能的 GitHub 提供了解决方案:vdexExtractor
按照README
的指引,我clone代码到~/GitHub/Utilities/vdexExtractor/
并编译,然后在~/temp/.../oat/arm64
目录执行
~/GitHub/Utilities/vdexExtractor/bin/vdexExtractor -i *.vdex -o ./out
成功了!
兴冲冲地打开out目录一看,傻眼了—— dex文件没有出现,取而代之的是三个cdex格式的文件
好在贴心的开发者已经给出了解释和解决方案:
转换工具目前支持到 Android-29 也就是 Android 10,根据开发者的描述可以使用项目/tools/deodex
目录下的脚本进行一键转换。但我执行后报缺少共享库liblzma.so
找到issues里有专门讨论cdex格式转换的单子 ,根据讨论内容发现可以直接使用静态编译的单文件工具compact_dex_converters
直接对cdex文件进行转换。
推断是动态库版本的compact_dex_converters
在我的电脑上缺少依赖才导致执行失败,所以我单独下载了静态编译的版本的工具。
执行成功:
将依次转换完成的三个 .cdex.new
重命名为 .dex
文件。
后续的工作就很简单了,使用dex2jar工具将dex文件转换为jar文件,使用JavaDecompiler工具打开就可以看到源码了。
其他的反编译方法可以参考这个链接