smali

Crates.iosmali
lib.rssmali
version
sourcesrc
created_at2022-09-22 08:30:16.854302+00
updated_at2025-03-10 13:44:57.772195+00
descriptionA library to read and write Android disassembly smali files.
homepage
repositoryhttps://github.com/azw413/smali
max_upload_size
id671540
Cargo.toml error:TOML parse error at line 21, column 1 | 21 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Andrew Whaley (azw413)

documentation

README

Smali Crate

A pure rust implementation of a parser, writer and set of types for the smali file format.

Smali is used in the Android reversing community to examine and modify Android APK files. It's a human readable text format that represents the complete structure of a Dex VM class including all of its instructions.

With this crate you can use it in conjunction with apktool to perform analysis and/or patches to Android applications.

There is a simple example in examples/main.rs that illustrates this. The example, will invoke apktool to expand any application and then parse all the smali files looking for RootBeer (an open source root detection framework), it will then patch RootBeer's methods to always return false so that the app can be run on a rooted device. Finally, it calls apktool again to repackage the app.

Here's the simple example :-

/* Expand the APK and patch RootBeer */
fn process_apk(apk_file: &str) -> Result<(), Box<dyn Error>>
{
    // Call apktool to unpack the APK
    execute_command("apktool", &["decode", "-f", apk_file, "-o", "out"])?;

    // Load all the smali classes
    let mut p = PathBuf::from_str("out")?;
    p.push("smali");
    let mut classes = find_smali_files(&p)?;
    println!("{:} smali classes loaded.", classes.len());

    // Search for the RootBeer class
    for c in classes.iter_mut()
    {
        if is_rootbeer_class(&c)
        {
            // Patch all the methods returning a boolean
            for m in c.methods.iter_mut()
            {
                if m.signature.result == TypeSignature::Bool && m.signature.args.len() == 0
                {
                    let mut new_instructions = vec![];
                    new_instructions.push(Instruction(DexInstruction::Const4 { dest: v(0), value: 0 }));  // "const/4 v0, 0x0" - Set v0 to false
                    new_instructions.push(Instruction(DexInstruction::Return { src: v(0) }));  //  "return v0" - return v0
                    m.instructions = new_instructions;
                    m.locals = 1;
                    println!("{} method {} successfully patched.", c.name.as_java_type(), &m.name);
                }
            }
        }
        // Save all classes, even unmodified so we can thoroughly test parser and writer
        c.save()?;
    }

    // Repack the APK
    execute_command("apktool", &["build", "out", "-o", "out.apk"])?;

    Ok(())
}
Commit count: 13

cargo fmt