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
- 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:
- property signature: str¶
The signature of this member
- Returns:
the id for this member
- Return type:
str
- 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
- 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. ASmaliMethod
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
- 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-calledSmaliMethodBroker
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 withSmaliClass
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:
- 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:
- 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
- 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:
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