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 在 解析器实现
59 每月下载量
3.5MB
5K SLoC
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 比较
为了准备测试环境,应在您的路径上安装以下工具
- Rust
- Apktool
- xmllint
- colordiff
之后,您应该能够运行
./script/compare_apk.sh PATH_TO_APK
您应该看到,对于每个文件,库的输出是否与 Apktool 的输出匹配。如果有差异,它将打印输出的差异。
依赖项
~5–14MB
~151K SLoC