#apk #android #xml-parser #parser #document #arsc

abxml

解析 APK 文件中的 resources.arsc 资源文件和二进制 XML 解压缩器

18 个版本

0.8.2 2019年11月3日
0.7.4 2019年10月23日
0.7.3 2019年6月1日
0.7.2 2019年1月2日
0.1.0 2017年3月25日

#1602解析器实现

Download history 36/week @ 2024-02-29 29/week @ 2024-03-07 13/week @ 2024-03-14 8/week @ 2024-03-21 15/week @ 2024-03-28 6/week @ 2024-04-04 11/week @ 2024-04-11 9/week @ 2024-04-18 9/week @ 2024-04-25 4/week @ 2024-05-02 4/week @ 2024-05-09 9/week @ 2024-05-16 15/week @ 2024-05-23 11/week @ 2024-05-30 16/week @ 2024-06-06 15/week @ 2024-06-13

59 每月下载量

MIT/Apache

3.5MB
5K SLoC

Coverage Status Build Status

ABXML

ABXML 是一个能够在 Rust 中解码 APK 文件的库。它试图简化与 APK 文件内部找到的二进制文档的交互。它能够解码包含的 resources.arsc 以及 res/ 文件夹中包含的所有二进制 XML 文档。它还公开了一些结构以在较低级别进行工作,供感兴趣者使用。

代码深受 Apktool 启发:没有它,这个库就不会存在。

快速示例

使用这个库的最简单方法是使用辅助结构 APK 来解压缩并将其解码到文件系统中。

use std::path::Path;
use abxml::apk::Apk;

fn main() {
    let path = Path::new("path_to.apk");
    let mut apk = Apk::new(path).unwrap();
    apk.export(Path::new("/tmp/apk_output/"), false).unwrap();
}

Apk::new 将创建一个处理程序,允许将其导出到文件系统。此时,它将加载 APK 到内存中,解压缩它并解析包含的 resources.arsc。如果此过程成功,使用 export 方法,它将开始导出所有包含的文件。如果它找到 Android 二进制 XML,则将其转换为字符串版本;否则,将直接将其移动到文件系统。在 export 函数的第二个参数用于强制删除第一个参数上给出的路径。在这种情况下,此片段的第二次调用将失败,因为目录将不为空。

访问者

这个库使用访问者模式来访问二进制文件的内容。有一个名为 Executor 的辅助结构,它负责给定一个二进制文件的内容,在给定的访问者上调用相应的函数。以下示例将打印出每个找到的字符串表的消息

use abxml::visitor::{Executor, ChunkVisitor};

pub struct PrintVisitor;

impl<'a> ChunkVisitor<'a> for PrintVisitor {
    fn visit_string_table(&mut self, string_table: StringTableWrapper<'a>, origin: Origin) {
        println!("Found string table with origin: {:?}", origin);
    }
}

fn main() {
    let data = [];
    let mut visitor = PrintVisitor;

    Executor::xml(&data, &mut visitor);
}

Executor 包含两个公共方法,根据输入类型使用:使用 arsc 解码 resources.arsc,对于二进制 XML 使用 xml。这种拆分的原因是因为文件头不同(resources.arsc 有 12 字节的头,而二进制 XML 有 8 字节)。

包装器、缓冲区和特质

在模型命名空间中,有几个特质暴露了库如何与二进制文件背后的每个概念交互。每个特质通常都由包装器和缓冲区实现。为什么有这种区分?

包装器提供表示的数据块的只读视图。这样,库仅在访问时分配数据。另一方面,Buf 结构是所有者,并打算作为可变使用。

所有包装器都有转换为缓冲区的函数(to_buffer),所有缓冲区都有创建作为字节的编码视图的函数(通过 OwnedBuf 特质)。这意味着可以进行双向转换。

与 Apktool 比较

为了准备测试环境,应在您的路径上安装以下工具

  1. Rust
  2. Apktool
  3. xmllint
  4. colordiff

之后,您应该能够运行

./script/compare_apk.sh PATH_TO_APK

您应该看到,对于每个文件,库的输出是否与 Apktool 的输出匹配。如果有差异,它将打印输出的差异。

依赖项

~5–14MB
~151K SLoC