0x0
对于常年有加解压apk的移动开发来说,都需要一款压缩/解压工具,不奢求能有什么强大的解压功能,只求简简单单支持好压缩/解压/文件更新功能即可。
而Gnome下则已自带了一款解压软件Archive-Manager,对于我来说,其实就已经够用了。然而,每次打开apk文件时,都会提示”Archive type not supported”
这简直是不能忍的,等了好多个版本也不见有支持的迹象,没办法,只能自己动手。
0x01
因为apk本质上来说也只是一个zip压缩包,原理上来说跟解压zip文件没啥区别,事实上,apk改了后缀后,一样也可以正常打开,所以排除了archive-manager不支持apk的判断。
使用file命令查看普通的apk是长什么样的
1 | [ligs@ligs 0409]$ file xxx.apk |
也是一个非常普通的zip类型文件而已。
遂果然只能下源码。
0x02
第一步,是找出archive-manager的源码,之所以这一步也要说实在是……archive-manager其实不见archive-manager,它本名是叫file-roller……不知道是怎么想的,波折了一番找到了地址
下面就已经有安装的指南了,但作为备忘还是说一下编译的过程。
克隆下来后就可以直接cd进去编译了,编译的步骤如下:
1 | mkdir build |
在build目录中使用meson来构建,在这个过程中会提示各种依赖
1 | Native dependency glib-2.0 found: YES 2.54.3 |
其他的都还好,就是这个magic总是找不到依赖,提示
meson.build:60:2: ERROR: C library ‘magic’ not found
dnf了好久都没找到,后来才知道这个是在file-devel的包里。
dnf install file-devel
然后meson通过后,就可以直接
1 | ninja |
编译好就可以直接使用了,会自动帮我们放到系统的目录中
0x03
那么是如何让Archive-Manager直接打开apk呢?首先我们先定位到”Archive type not supported”的提示是在哪里提示的,使用find和xargs直接找到对应的位置,定义在
./src/dlg-package-installer.c
1 | static void |
查看上下文,判断的依据就是工具尝试使用读取的mime_type去判断这个文件是否能够是在可识别的类型范围内,如果不是,就直接调用package_installer_terminated 弹出提示,然后终止运行。
这时我马上使用file命令再去看一下apk的mime是什么类型的
[ligs@ligs 0409]$ file –mime-type xxx.apk
xxx.apk: application/zip
果不其然只是单纯的application/zip类型,跟zip是一样的。
而工具判断哪些类型是可识别的,哪些不行,是定义在
./src/fr_init.c
可以看到这个文件里就定义了哪些文件可以识别,以及它们对应的处理器是什么,类型注册是在
1 | static void |
以zip文件为例,搜索可以看到,FR_TYPE_COMMAND_ZIP是定义在./src/fr-command-zip.h当中,顺便也可以看到,其他类型的定义也都以相同的命名格式放在同一路径下。
打开./src/fr-comand-zip.c下,可以找到zip有注册的mime_type类型
1 | const char *zip_mime_type[] = { "application/x-cbz", |
可以看到,application/zip是有注册的,那按理来说apk文件应该是可以按zip的方式打开才对,那为什么打不开呢?
于是我还是采用笨方法,在file_buffer_ready_cb函数里,将文件的mime-type输了出来,结果发现,对于 apk 而言,mime-type根本就不是application/zip,而是 application/vnd.android.package-archive 。
0x04
知道了这个差别后,那就比较好解决了。
我们知道 apk 本质上是zip,那可以让Archive-Manager以zip的方式打开apk就行了,那只需要把apk的mime-type注册到zip的处理器里就可以了
1 | const char *zip_mime_type[] = { "application/x-cbz", |
重新编译安装后就能支持。