A library for parsing and unparsing smali files for programatic modification
Project description
PySmali
PySmali is a Python library for parsing and unparsing smali files for programatic modification.
It is a line (not token) based parser. Its primary goal is for parsed files to maintain 100% equality with their original forms when reconstructed.
PySmali's main usage is for smali file patching. You are able to parse, search, extract, replace, and unparse blocks of a smali file.
Parsing is based on the ANTLR files found in the JesusFreke/smali repository.
Since this is a line, and not token, based parser, there are likely to be edge cases where PySmali fails to properly parse or unparse a file. There are currently 6,846 smali files that are used in the tests folder (tests/tests.tar.xz).
If you run into a smali file that does not parse or unparse properly, please submit a new issue with the complete smali file(s) attached as a zip or gz archive.
Requirements
- Python 3.8 or newer
Installation
pip install smali
Simple Example
import time
from smali import SmaliFile
from smali.statements import Statement
smali_file = SmaliFile.parse_file('/path/to/file.smali')
new_lines = Statement.parse_lines(f'''
# This file was modified by PySmali
# Modified: {time.ctime()}
''')
smali_file.root.extend(new_lines)
with open('/path/to/file.smali', 'w') as f:
f.write(str(smali_file))
Status
-
[UPCOMING] v0.4.0
- Complete parsing of body statements
-
[UPCOMING] v0.3.0
StatementandBlocksearching by method and field names- Simplified
StatementandBlockextraction and insertion
-
v0.2.5
- Removed all dependencies and reorganized utility code
-
v0.2.4
- Complete parsing and unparsing of non-body statements validated by current test suite
Methodology
- The smali file is ingested on a line by line basis
- Each line is parsed into one or more
Statementinstances.super Ljava/lang/Object;would become a singleStatementinstancevalue = { LFormat31c; }would become 4Statementinstancesvalue,{,LFormat31c;,}
- Each
Statementinstance is subclassed based on its type- E.g.
FieldStatementorMethodStatement
- E.g.
- A
Statementcan have zero or moreStatementAttributesthat indicate its intent and format- E.g.
BLOCK_START,ASSIGNMENT_LHS, orNO_BREAK
- E.g.
- Multiple
Statementinstances can be joined into aBlockand nested where appropriate- A
Blockexample would be a smali method, comprised of beginning, body, and endStatementinstances
- A
- A
Statementparses its source line, split by whitespace - Parsing is done in two passes. This is due to the fact that the same line can be the start of a block, or a solo line depending on the existence of a matching
EndStatement.- The first pass builds a flat list of
Statementinstances from the input lines. - A
Statementthat can be either aBlockstart or a solo line is marked with theMAYBE_BLOCK_STARTattribute - If an
EndStatementis generated, and matches a previously markedStatement, the markedStatementis switched fromMAYBE_BLOCK_STARTtoBLOCK_START. - After the first pass, any remaining
Statementinstances that are still marked withMAYBE_BLOCK_STARTare switched toSINGLE_LINE, - The second pass iterates over the flat list of
Statementinstances and groups them intoBlockinstances and nesting when appropriate based on theSINGLE_LINEandBLOCK_STARTattributes.
- The first pass builds a flat list of
- Unparsing is done in a single pass
- Each
Statementstringifies itself using its own local information - The
SmaliFileinstance uses the attributes of eachStatementto stitch lines together and indent blocks where necessary
- Each
License
OSS Attribution
JesusFreke/smali by Ben Gruver
Licensed Under: Various Licenses
Tests
Smali files used as tests in the tests/tests.tar.xz archive have been obtained from the following projects:
- Android
- AndroidX
- FasterXML
- Java
- JavaX
- OkHttp
- Smali
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smali-0.2.5.tar.gz.
File metadata
- Download URL: smali-0.2.5.tar.gz
- Upload date:
- Size: 13.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.24.0 setuptools/49.1.3 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bf6a5ead52552748e3314af472ca139bdff6600e861aa27c334b7b12c828a0b
|
|
| MD5 |
2be5fb5b61bc5e78f54d807e0c73581e
|
|
| BLAKE2b-256 |
4ba08cd067a054e4c2839bc2457b1736b62e22a304372b832f698122415a17c7
|
File details
Details for the file smali-0.2.5-py3-none-any.whl.
File metadata
- Download URL: smali-0.2.5-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.24.0 setuptools/49.1.3 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0c7046e57e386d82cdd8893001be510165900ca93dec99773f226d9e16e85d8
|
|
| MD5 |
75b2d788892d1e1a3c4911908a9dcedc
|
|
| BLAKE2b-256 |
0cae3795fa8c3bef7fc76b1031644e26f692595cc20b90fbc4be815b0ba65b28
|