3. Smali Shell (ISmali)

Introducing a new file format that combines the simplicity of shell scripts with the power of Smali-Code in version 0.1.1 of this project. This new format, which will be called Smali-Script is defined by the file suffix ".ssf". It is designed to allow users to create and run Smali-Code directly from a single file, using Smali’s syntax.

To use a Smali-Script file, users simply need to create a new file with the .ssf suffix and write their Smali-Code. They can then run it with ismali. This makes it an ideal format for executing small code snippets that can be used within deobfuscation.

$ ismali
ISmali $VERSION on $PLATFORM
>>> # put Smali instructions here

Before starting to execute Smali instructions, it is worth to know that there are some global variables that can be queried:

  • vars: This command will print out all registers with their values

  • label: Prints the name of the current label

  • fields: Prints all fields that have been defined in the root context

  • import: Loads a class defined in a *.smali file. The class can be used afterwards

Note

By now, only primitive types and String objects can be instantiated. Instances of other types can be created after importing the class. All instructions will be executed directly and fields will be stored in the root class named L<Root>;.

3.1. Define Smali-Fields

Fields can be defined rather easily. By now, only one-liner are accepted:

1>>> .field public static abc:Ljava/lang/String; = "Hello, World!"
2>>> # Retrieve the value via sget on static fields
3>>> sget v0, L<Root>;->abc:Ljava/lang/String;
4>>> vars
5{'p0': <SmaliObject@289e5e06fd0>, 'v0': 'Hello, World!'}

In the first line of the code above we defined a new static field with a pre-defined value "Hello, World!". Next, the value of our field is stored in the register v0 (actually, the name can be customized). Because we moved abc’s value into a register, we can see that value by typing vars.

3.2. Execute Smali-Methods

The next example illustrates how to simply invoke a method within the interpreter.

Warning

As of version 0.2.0 it is not possible two define methods in the root-context. This feature is proposed to be released in the next version.

1>>> invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
2>>> move-result-object v1
3>>> vars
4{'p0': <SmaliObject@25490b06fd0>,
5 'v1': '<SmaliObject@25490b06fd0 fields=0 type=<SmaliClass L<Root>;>'}

In this example we called Object.toString() within the root-context. As we can see, the first register stores the actual instance and the second (v0) a string representation of it.

3.3. Shell Components

Implementation of a “shell”-like interpreter that can be run interactively or can execute smali files.

The options the smali.shell module accept are the following:

file [file …]

The Smali-Script files (.ssf) to be interpreted. Note that files as input won’t result in interactive mode. Use the -i flag to run the interactive mode afterwards.

-i / –interactive

Runs the interactive mode after executing/importing input files.

class smali.shell.ISmaliShell

Implementation of an interactive Smali-Interpreter.

DEFAULT_PROMPT = '>>> '

The default prompt

INLINE_PROMPT = '... '

Prompt used for field and method definitions

change_prompt(new_prompt: str)

Changes the prompt (for later usage)

check_import: bool = True

Used to indicate whether this shell should verify each import

default(line: str) None

Handles the instruction or register name

Parameters:

line (str) – the input line

Prints copyright information

do_del(register)

usage: del <register>

Deletes the variable at the specified register. The root context at ‘p0’ can’t be deleted.

do_exit(_)

Exits the interpreter

do_fields(_)

usage: fields

Prints all fields that have been defined in the root context.

do_import(path: str) None

usage: import <file>

This command will try to import the given smali file or Smali-Script file (.ssf). Note that files with wrong suffixes will be ignored.

do_label(_)

:usage label

Prints the name of the active label.

do_vars(_)

usage: vars

Prints all variables with the help of pprint.

emulator: SmaliVM

The actual VM reference that will execute each method

precmd(line: str)

Hook method executed just before the command line is interpreted, but after the input prompt is generated and issued.

prompt: str = '>>> '

The prompt used by cmd.Cmd

reader: SmaliReader

The reader used to parse code snippets.

root: SmaliObject

The base context used to define fields and methods.

visitor: DefaultVisitor

The default visitor instance