2. Smali Bridge API

2.1. Execution Frame

Execution frame objects are used within method calls the Smali emulator. They store the current opcode position, label and values of all registers in the current context.

On top of that, Frame objects store method return values (sub- calls) as well as the final return value. If any errors occur, they will be stored in a separate variable.

class smali.bridge.frame.Frame

Class to represent execution frames.

There are different special functions implemented to simplify the process of getting and setting register values:

>>> value = frame["v0"]
0
>>> "v0" in frame
True
>>> frame["v0"] = 1
>>> for register_name in frame:
...     value = frame[register_name]
array_data: dict

Stores all array-data objecs mapped to their label.

catch: dict

Stores all try-catch handlers.

Note that teh stored handlers will be tuples with the exception type and the handler block

error: ExecutionError

Defines the current execution error

finished: bool = False

Stores whether te current frame has been executed.

label: str

The current label context

labels: dict = {}

A mapping with labels to their execution position.

method_return: object = None

Stores the latest method return value

opcodes: list = []

Stores all parsed opcodes with their arguments

parent: Frame = None

Parent execution context (mainly used for backtracking)

pos: int = 0

The current position in opcode list

registers: dict

Stores values for the current registers.

reset() None

Resets this frame and removes execution information.

return_value: object = None

Stores a return value of the current method.

switch_data: dict

Stores packed and sparse-switch data

vm = None

VM reference

2.2. Language members

The module lang of the provided Smali bridge defines classes that can be used to mimic Java’s reflection at runtime of the SmaliVM.

All members of a Smali class inherit functionalities of __eq__, __ne__, as well as hash value calculation and string representation of objects.

Hint

Some properties are modifiable like SmaliField.value or the name of a SmaliClass object. It is recommended to leave them how they are and let the VM make chenges to them.

class smali.bridge.lang.SmaliMember(type_: str, parent: SmaliMember, signature: str, modifiers: int, base_class: type, annotations: list = None)

Base class for Python classes of the Smali language.

All members must provide a signature to be identified with.

property annotations: list

The declared annotations of this member

Returns:

all declared annotations

Return type:

list

get_annotations(a_type: str) list

Returns all declared annnotations of the given type.

Parameters:

a_type (str | SVMType) – the annotation’s type descriptor

Returns:

a list of declared annotations

Return type:

list

is_annotation_present(a_type: str) bool

Returns whether the given annotation is present.

Parameters:

a_type (str) – the annotation’s type descriptor

Returns:

True, if present; False otherwise

Return type:

bool

property modifiers: int

The modifiers for this member

Returns:

the modifiers

Return type:

int

property parent: SmaliMember

Returns the declaring class or annotation member.

Returns:

the parent of this member

Return type:

SmaliMember

property signature: str

The signature of this member

Returns:

the id for this member

Return type:

str

property type: SVMType

Returns the type of this member

Returns:

the type instance

Return type:

SVMType

class smali.bridge.lang.SmaliAnnotation(parent: SmaliMember, signature: str, modifiers: int, annotations: list = None, attr=None)

Class that represents Smali annotations (and subannotations).

This class mimics the behaviour of a dict object, so it can be used as follows:

>>> annotation = SmaliAnnotation(...)
>>> annotation['age'] = 30
>>> age = annotation['age']
30
>>> 'age' in annotation
True
Parameters:
  • signature (str) – the annotation’s type descriptor

  • modifiers (int) – the annotation’s visibility

  • annotations (list, optional) – a list of declared annotations, defaults to None

  • attr (dict, optional) – the annotation’s attributes, defaults to None

attr: dict

The attributes of this annotation (key-value map).

class smali.bridge.lang.SmaliField(_type: str, parent, signature: str, modifiers: int, name: str, annotations: list = None, value=None)

Python class that represents fields in Smali.

Parameters:
  • signature (str) – the field’s signature (name:type)

  • modifiers (int) – the field’s access modifiers

  • annotations (list, optional) – the field’s annotations, defaults to None

  • value (int | float | str | SVMType | bool, optional) – the field’s value, defaults to None

property name: str

Returns the name of this field

Returns:

the name

Return type:

str

property value: int | float | str | SVMType | bool

Returns the value of this field.

Returns:

the value as a SmaliValue

Return type:

int | float | str | SVMType | bool

class smali.bridge.lang.SmaliMethod(vm, parent: SmaliMember, signature: str, modifiers: int, annotations: list = None)

Implementation of a Smali method

Instances of this class are callable with pre-defined arguments. For example, a method with the signature "add(II)I" has two integet arguments and an integer as return value. A SmaliMethod can be executed as follows:

# Our example method with signature := "add(II)I"
method = SmaliMethod(...)
instance = SmaliObject(...)
result = method(instance, 1, 2)

The instance of the object that defines the method is always needed except for static method. They can bbe called with None as the instance parameter.

property locals: int

Returns the amount of local variables.

property name: str

Returns the name of this method

Returns:

the method’s name

Return type:

str

property parameters: list[SVMType]

Returns the parameters of this method as type descriptor strings

Returns:

the parameters of this method

Return type:

list

property return_type: SVMType

Returns the method’s return type

Returns:

the return type

Return type:

SVMType

class smali.bridge.lang._MethodBroker(name: str, methods: list)

Custom implementation of an additional layer between class and method.

This class is used to delegate method execution when multiple methods with the same name are present. It supports __call__ to execute defined methods and __iadd__ to add new methods. In order to iterate over defined methods, __iter__ is implemented as well:

>>> broker = SmaliMethodBroker(methods)
>>> broker += SmaliMethod(...)
>>> broker(object_instance, p0=1, p1=2)
<result> # in case we defined a method with two parameters
>>> for method in broker:
...     print(str(method))

There is a pre-defined alias for this class named SmaliMethodBroker in the . same module.

class smali.bridge.lang.SmaliClass(parent: SmaliMember, signature: str, modifiers: int, annotations: list = None)

Internal class for storing imported class data.

2. Annotations of a class

All declared annotations are stored within the annotations field and can be edited via the list type. it is also possible to check, wheter an anntation with a specific type descriptor is present. The present annotations can be retirievend via another method:

>>> smali_class: SmaliClass = ...
>>> smali_class.is_annotation_present("Lcom/dalvik/Signature;")
True
>>> for annotation in smali_class.get_annotations("Lcom/dalvik/Signature;")
...     # Dict behaviour is implemented here
...     annotation: SmaliAnnotation

2. Fields of a class

Field definitions are stored in a dict to enable quick access to all of them. Static fields contain values at class level and the values of normal fields will be stored in separate SmaliObject instances. A field that belongs to a class should be retrieved via the following method:

>>> field = smali_class.field("foo")
<SmaliField 'foo:Ljava/lang/String;'>

It is also possible to retrieve the SmaliField via a dict-like access:

>>> field = smali_class["foo"]

Important

Only fields are accessable via subcription, annotations, methods and implemented interfaces must e queried with other methods.

Fields can be added via a dict-set operation:

>>> smali_class["foo"] = SmaliField(...)

2. Methods of a class

Smali methods are mapped to their name and can be retrieved by either providing their name or signature directly:

>>> method = smali_class.method("<init>")
<SmaliMethod '<init> at ...>

In this example we queried the method named <init>, which is the constructor method of this class. If there is more than one definition, a so-called SmaliMethodBroker is returned:

>>> method = smali_class.method("getString")
<_MethodBroker of 'getString' at ...>

These objects store all methods with the same name and will choose the best method according to the given arguments when trying to execute one method.

Like SmaliField objects, methods can be added via dic-set as well:

>>> smali_class["getString"] = SmaliMethod(...)

2. Interfaces of a class

The implemented interfaces and super class will be stored as simple string objects. As the option lookup_missing can be set to false, these values won’t be initialized with SmaliClass instances to enable import of whole class files wihtout having all classes defined.

2. Inner classes defined inside a SmaliClass

Inner classes are stored like fields or methods - in a dict. They can’t be queried directly, but the dictionary storing all classes is accessable:

>>> smali_class["LMyInnerClass;"] = SmaliClass(...)
clinit() None

Calls the static-block initializer method (<clinit>)

If no static-block is defined, this method won’t have any further action to take.

field(name: str) SmaliField

Returns the field with the given name.

Parameters:

name (str) – the field’s name

Raises:

NoSuchFieldError – if no field with the goven name is defined

Returns:

the SmaliField instance

Return type:

SmaliField

fields(access_type: AccessType = None)

Returns all fields that match the given access type.

If no access type is given, all fields will be returned.

Parameters:

access_type (AccessType, optional) – the access type to filter, defaults to None

get_declared_methods(access_type: AccessType = None) list[SmaliMethod]

Returns all declared methods in this class,

Parameters:

access_type (AccessType, optional) – an extra filter, defaults to None

Returns:

the list of defined smali methods

Return type:

list[SmaliMethod]

inner_class(name: str) SmaliClass

Returns an inner class by its name.

Parameters:

name (str) – the name (type descrptor)

Raises:

NoSuchClassError – if no inner class with the given name is defined

Returns:

the SmaliClass instance of the inner class

Return type:

SmaliClass

property inner_classes: dict[str, SmaliClass]

Returns all inner classes

Returns:

all defined inner classes

Return type:

dict

property interfaces: list[SVMType]

Returns all implemented interfaces (type descriptors)

Returns:

all implemented interfacea in a list

Return type:

list

method(signature: str) SmaliMethod

Searches for the given method signature or name.

Parameters:

signature (str) – the name or signature of the method

Raises:

NoSuchMethodError – if no method with a name or wignature equal to the given could be found

Returns:

the method or method-broker if multiple methods with the same name exist.

Return type:

SmaliMethod | SmaliMethodBroker

property name: str

Returns the name of this class with the package (with dots)

property simple_name: str

Returns the name of this class.

Returns:

the class name

Return type:

str

property super_cls: SVMType

Returns the super class of this class

Returns:

the super class name

Return type:

SVMType | SmaliClass

class smali.bridge.lang.SmaliObject(clazz: SmaliClass)

Python objects that store data of a Smali object.

This class implements dict-like access to all fields’ values and static fields will be directly references if possible.

Caution

Smali objects of interfaces or abstract classes can’t be created.

__class: SmaliClass

The prototype class.

__field_values: dict

The object’s field values.

init(*args)

Calls the constructor of this object.

property smali_class: SmaliClass

Returns the prototype SmaliClass object

Returns:

the smali class this object is an instance of

Return type:

SmaliClass

2.3. Common error classes

The following classes are defined in the smali.bridge.errors module:

class smali.bridge.errors.NoSuchClassError

The class is not defined or wasn’t found

class smali.bridge.errors.NoSuchMethodError

The method is not defined

class smali.bridge.errors.NoSuchFieldError

The requested field is not defined

class smali.bridge.errors.NoSuchOpcodeError

The opcode does not exists or no implementation is present

class smali.bridge.errors.InvalidOpcodeError

The opcode is invalid

class smali.bridge.errors.NoSuchRegisterError

Unknown register was requested to be read

class smali.bridge.errors.ExecutionError(name: str, *args: object)

Wrapper class for runtime exceptions.

name: str

The exception class name