rust-apk 1.0.0

Build, align, sign, verify, and inspect Android APKs in pure Rust
Documentation

apk-rs

This independent crate is derived from the apk package in rust-mobile/xbuild, commit e67b501cbe0e9ca5436c223aa7ec0fe5e27544d1 (apk 0.4.0).

Welcome to apk-rs. you can build, sign, verfify, read, etc. Android APKs. Pure rust. you can probably get the rest from the code apis at docs.rs

Building a native app

use apk::prelude::*;

let mut app = ApkBuilder::native_activity("org.example.game".parse()?, "game".parse()?);
app.label("Game")
    .version(VersionCode::try_new(7)?, "1.0.7")
    .localized_string("app_name", "fr".parse()?, "Jeu")?
    .icon(Density::XXXHDPI, std::fs::read("icon.png")?)?
    .native_library(Abi::Arm64V8a, "target/aarch64-linux-android/release/libgame.so")?
    .sign_with(Signer::new(SigningIdentity::from_pem_file("release.pem")?));
app.write("game.apk")?;
# Ok::<(), Box<dyn std::error::Error>>(())
# use apk::prelude::*;
# let mut app = ApkBuilder::native_activity("org.example.game".parse()?, "game".parse()?);
let activity = app.manifest_mut().application_mut().element_mut("activity").unwrap();
activity.set_attr(attr::SCREEN_ORIENTATION, attr::SCREEN_ORIENTATION.parse("sensorLandscape")?);
# Ok::<(), Box<dyn std::error::Error>>(())

Manifest::parse accepts a hand-written AndroidManifest.xml instead.

Signing and verifying

use apk::sign::{Keystore, Signer, verify};

let identity = Keystore::open("release.p12", "store password")?.identity("upload", None)?;
Signer::new(identity).sign_file("app.apk")?;
let verification = verify("app.apk")?;
println!("{:?} by {}", verification.schemes, verification.certificate().subject());
# Ok::<(), apk::Error>(())

Reading

use apk::Apk;
use apk::res::ResourceTable;

let mut apk = Apk::open("app.apk")?;
println!("{}", apk.manifest()?);
let bytes = apk.read("resources.arsc")?;
print!("{}", ResourceTable::parse(&bytes)?);
# Ok::<(), apk::Error>(())

Scope

It does mostly everything except for

  • ZIP64 archives, which APK signature schemes cannot cover.
  • Signing key rotation: v3.1 blocks and proof-of-rotation lineages are rejected rather than trusted unverified. APK Signature Scheme v4 and DSA signatures and verity digests are not supported. RSA, P-256, and P-384 keys are supported.
  • Bag resources (styles, arrays, plurals, attributes) and nine-patch images are not compiled; ONLY simple values, files, and XML documents are. Reading supports simple values and bags; styled string spans are not exposed. I would probably take this as a PR though!

Verification establishes signature integrity and SDK scheme coverage. But certainly does not establish certificate trust or guarantee installation: DEX validity, device policy, and native symbol availability still depend on the app and device.

Framework attribute and resource IDs come from API 35 (src/android/framework.txt). To update them, run tools/gen-framework against a newer SDK platform:

cd tools/gen-framework && cargo run -- $ANDROID_HOME/platforms/android-36

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.