5. Smali Components

Basic component classes when working with the Smali language.

5.1. Smali token

class smali.base.Token(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Defines all common token in a Smali file.

There are some special methods implemented to use constants of this class in the following situations:

>>> "annotation" == Token.ANNOTATION
True
>>> "local" != Token.LOCALS
True
>>> len(Token.ENUM)
4
>>> str(Token.ARRAYDATA)
'array-data'

5.2. Smali access modifiers

class smali.base.AccessType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Contains all access modifiers for classes, fields, methods and annotations.

There is also a possibility to use values of this class with an in statement:

>>> flags = AccessType.PUBLIC + AccessType.FINAL
>>> flags in AccessType.PUBLIC
True
>>> flags in AccessType.PRIVATE
False
static find(value: str) bool

Returns whether the given keyword is a valid modifier.

Parameters:

value (str) – the value to check

Returns:

True, if the given value represents an access modifier

Return type:

bool

static get_flags(values: list) int

Converts the given readable access modifiers into an integer.

Parameters:

values (list) – the keyword list

Returns:

an integer storing all modifiers

Return type:

int

static get_names(flags: int) list

Converts the given access modifiers to a human readable representation.

Parameters:

flags (int) – the access modifiers

Returns:

a list of keywords

Return type:

list

5.3. Smali type descriptors

class smali.base.SVMType(_SVMType__type: str)
class TYPES(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Represents the classification of a type descriptor.

property array_type: SVMType

Returns the underlying array type (if any)

>>> array = SVMType("[[B")
Returns:

the underlying array type instance

Return type:

SVMType

property dim: int

Returns the amount of array dimensions.

Returns:

the amount of array dimensions.

Return type:

int

property dvm_name: str

Returns the DVM representation of this type descriptor.

>>> cls = SVMType("Lcom/example/Class;")
>>> cls.dvm_name
'com/example/Class'

Arrays won’t be covered by this method, thus the returned value returns the full class name only:

>>> cls = SVMType("[[Lcom/example/Class;")
>>> cls.dvm_name
'com/example/Class'
Returns:

the full name without L and ;.

Return type:

str

property full_name: str

Returns the full name of this type descriptor (input value)

>>> cls = SVMType("com.example.Class")
>>> cls.full_name
'Lcom/example/Class;'
Returns:

the full name

Return type:

str

is_signature() bool

Returns whether this type instance is a method signature.

>>> t = SVMType("<init>(II)V")
>>> t.is_signature()
True
Returns:

True, if this instance represents a method signature

Return type:

bool

property pretty_name: str

Returns a prettified version of the class name.

>>> array = SVMType("[[Lcom/example/Class;")
>>> array.pretty_name
'com.example.Class[][]'
Returns:

full name without L and ;; / is replaced by a dot.

Return type:

str

property signature: Signature | None

Creates a Signature object from this type instance.

Returns:

the signature object or nothing if this type does not represent a method signature.

Return type:

Signature | None

property simple_name: str

Returns only the class name (not applicable to method signatures)

Returns:

the class’ name

Return type:

str

property svm_type: TYPES

Returns the descriptor classification (ARRAY, PRIMITIVE, METHOD or CLASS)

Returns:

the classification of this type instance

Return type:

SVMType.TYPES

class smali.base.Signature(_Signature__signature: str | SVMType)

Internal class to encapsulate method signatures.

CLINIT = '<clinit>'

Static block initializer

INIT = '<init>'

Constructor method

property declaring_class: SVMType | None

Returns the SVMType of the method’s declaring class.

>>> s1 = Signature("Lcom/example/Class;-><init>(II)V")
>>> str(s1.declaring_class)
'Lcom/example/Class;'
>>> s2 = Signature("<init>(II)V")
>>> str(s2.declaring_class)
'None'
Returns:

the method’s declaring class

Return type:

SVMType | None

property descriptor: str

Returns the method descriptor of this signature

>>> s = Signature("<init>(II)V")
>>> s.descriptor
'(II)V'
Raises:

ValueError – if there is no descriptor

Returns:

the method’s descriptor string

Return type:

str

property name: str

Returns the method name

>>> s = Signature("Lcom/example/Class;->getLength(Ljava/lang/String;)I")
>>> s.name
'getLength'
Returns:

the absolute method name

Return type:

str

property parameter_types: list[SVMType]

Returns the method parameter types.

>>> s = Signature("<init>(II)V")
>>> params: list[SVMType] = s.parameter_types
>>> [str(x) for x in params]
["I", "I"]
Returns:

the method parameters

Return type:

list

property return_type: SVMType

Retrieves the method’s return type

>>> s = Signature("<init>(II)V")
>>> str(s.return_type) # returns a SVMType instance
'V'
Raises:

TypeError – if there is no valid return type

Returns:

the return type’s descriptor

Return type:

str

property sig: str

Returns the fully qualified signature string.

>>> s = Signature("<init>(II)V")
>>> s.sig
'<init>(II)V'
Returns:

the input string

Return type:

str

5.4. Smali type

smali.smali_value(value: str) int | float | str | SVMType | bool

Parses the given string and returns its Smali value representation.

Parameters:

value (str) – the value as a string

Raises:

ValueError – if it has no valid Smali type

Returns:

the Smali value representation

Return type:

int | float | str | SVMType | bool

5.5. Utility components

class smali.base.Line(line: str)

Simple peekable Iterator implementation.

RE_EOL_COMMENT = re.compile('\\s*#.*')

Pattern for EOL (end of line) comments

cleaned: str

The cleaned line without any leading and trailing whitespace

eol_comment: str

The removed trailing EOL comment (if present)

has_eol() bool

Returns whether this line contains an EOL comment

Returns:

True, if the line contains an EOL comment

Return type:

bool

has_next() bool

Returns whether there as a following element.

Returns:

True if next() can be called safely

Return type:

bool

last() str

Returns the last element of this line without modifying the iterator.

Returns:

the last element

Return type:

str

peek(default: str = <object object>) str

Returns the current element if this line.

This method won’t move forwards.

Parameters:

default (str, optional) – the default value to return, defaults to _default

Raises:

StopIteration – if the end of this line has been reached

Returns:

the current value

Return type:

str

raw: str

The raw line as it was passed through the constructor.

reset(line: str = None) None

Resets this line and/or initialized it with the new value.

Parameters:

line (str, optional) – the next line, defaults to None

static split_line(cleaned: str, sep: str = ' ') list

Splits the line by the given delimiter and ignores values in strings

Parameters:
  • cleaned (str) – the input string

  • sep (str, optional) – the delimiter, defaults to ‘ ‘

Returns:

the splitted values

Return type:

list