apk链接提取应用名称及包名

根据apk链接获取apk包名应用名

  • 最近有个需求,根据apk链接获取apk的包名和应用名。

  • 正常手段是这样,下载完整的apk,然后利用apktool解压分析,完事。这样的操作,一方面需要大量时间下载,一方面也浪费磁盘空间(需要解压)。

  • 进一步的思路是,不利用apktool解压。因为apk文件是zip压缩格式,于是我们可以根据zip格式来分析apk二进制文件(不需要解压了)。

  • 现在基本上apk都支持流下载,那么我们也可以做个流解压提取我们的信息。

  • 查阅apk和zip压缩格式,主要得到以下几个信息。

zip压缩格式:

本地文件头1
文件数据1
数据描述符1

以上重复若干次

本地文件头 n
文件数据 n
数据描述符n

archive decryption header(EFS) 
archive extra data record (EFS)
中央目录
zip64的中央目录记录结束
zip64的中央目录定位结束
中央目录记录结束

本地文件头的格式如下:

本地文件头签名      4个字节(0x04034b50)
需要提取的版本     2个字节
通用位标志          2个字节
压缩方法           2个字节
最后的mod文件时间   2个字节
最后的mod文件日期   2个字节
crc-32             4个字节
压缩大小           4个字节
解压缩大小         4个字节
文件名长度         2个字节
额外字段长度       2个字节
  • 由上述信息,我们知道了,对二进制数据,找到文件头标签即可判断这是个文件开头。注意这是小端存放,因此用 (b’\x50\x4b\x03\x04’)来判定寻找文件头。并且文件的压缩大小也给出了,结合上面的字段既可找到下一个文件的开头,不断循环即可。这样利用requests库的流下载,既可做到迭代寻找下一个新文件对其操作。设置个chunk即可。

  • 上面的方法只是解决了不需要解压的问题,如果我们想要的文件在apk存放在靠后位置,依然会浪费比较多的时间,有没有一个更好的方案呢?

  • 肯定有,找到如下资料

    Central directory structure:

    [file header 1]
    .
    .
    . 
    [file header n]
    [digital signature] 
    
    File header:
    
      central file header signature   4 bytes  (0x02014b50)
      version made by                 2 bytes
      version needed to extract       2 bytes
      general purpose bit flag        2 bytes
      compression method              2 bytes
      last mod file time              2 bytes
      last mod file date              2 bytes
      crc-32                          4 bytes
      compressed size                 4 bytes
      uncompressed size               4 bytes
      file name length                2 bytes
      extra field length              2 bytes
      file comment length             2 bytes
      disk number start               2 bytes
      internal file attributes        2 bytes
      external file attributes        4 bytes
      relative offset of local header 4 bytes
    
      file name (variable size)
      extra field (variable size)
      file comment (variable size)
    

总结:

  • 可以看出这样就有了文件的起始字段和文件压缩大小,既可以从http请求头部直接定义字段,取到自己需要的文件即可。
  • 通常情况下AndroidManifest.xml和resources.arsc是我们需要的文件
  • apktool解压出来有个string文件,里面有apk的应用名称,通过看apk源码我们可知,是由resource.arsc提取。这两个文件中都含有package name,所以目标找到resource.arsc文件处于的字节段即可。
  • 方法就有了,我们先发一个请求url链接后1M的数据,拿到中央目录,找到resource.arsc文件对于的url中的位置。这里需要注意一下,找到的起始位置是文件头开始,会有额外字段,因此compressed size需要加个1kb。
  • 代码整理后另外上传吧 (做成分2部分 1流式下载apk 2根据url提取名称)