{"id":18746684,"url":"https://github.com/matrixeditor/pysmali","last_synced_at":"2025-08-11T14:42:01.034Z","repository":{"id":213334257,"uuid":"729835902","full_name":"MatrixEditor/pysmali","owner":"MatrixEditor","description":"Smali Source code interpreter + visitor API in Python3 and an emulator to execute code snippets.","archived":false,"fork":false,"pushed_at":"2025-05-23T13:50:05.000Z","size":5778,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-10T19:45:38.982Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://matrixeditor.github.io/pysmali/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MatrixEditor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-10T14:05:54.000Z","updated_at":"2025-06-25T18:36:11.000Z","dependencies_parsed_at":"2025-04-12T22:15:25.212Z","dependency_job_id":"1550aef5-ba66-49d9-be1e-693a9a2882a4","html_url":"https://github.com/MatrixEditor/pysmali","commit_stats":null,"previous_names":["matrixeditor/pysmali"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MatrixEditor/pysmali","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatrixEditor%2Fpysmali","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatrixEditor%2Fpysmali/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatrixEditor%2Fpysmali/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatrixEditor%2Fpysmali/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MatrixEditor","download_url":"https://codeload.github.com/MatrixEditor/pysmali/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatrixEditor%2Fpysmali/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269905666,"owners_count":24494313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T16:26:30.771Z","updated_at":"2025-08-11T14:42:00.966Z","avatar_url":"https://github.com/MatrixEditor.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PySmali\n\n[![python](https://img.shields.io/badge/python-3.9+-blue.svg?logo=python\u0026labelColor=lightgrey)](https://www.python.org/downloads/)\n![Status](https://img.shields.io:/static/v1?label=Status\u0026message=Pre-Release\u0026color=teal)\n![Platform](https://img.shields.io:/static/v1?label=Platforms\u0026message=Linux|Windows\u0026color=lightgrey)\n[![Build and Deploy Sphinx Documentation](https://github.com/MatrixEditor/pysmali/actions/workflows/sphinx.yml/badge.svg)](https://github.com/MatrixEditor/pysmali/actions/workflows/sphinx.yml)\n[![PyPI](https://img.shields.io/pypi/v/pysmali)](https://pypi.org/project/pysmali/)\n\n\nThe main functionalities of this repository cover creating and parsing Smali files with Python3 as well as interpret Smali source code files. There is also an interactive interpreter provided that acts as a Python-CLI.\n\n### Contributors\n\n[![TheZ3ro](https://img.shields.io:/static/v1?label=Fixer\u0026message=TheZ3ro)](https://github.com/TheZ3ro)\n[![serenees](https://img.shields.io:/static/v1?label=Patcher\u0026message=serenees)](https://github.com/serenees)\n[![metalcorpe](https://img.shields.io:/static/v1?label=Patcher\u0026message=metalcorpe)](https://github.com/metalcorpe)\n\n\n## Installation\n\nBy now, the only way to install the python module in this repository is by cloning it and running the following command:\n\n```bash\n$ cd ./pysmali \u0026\u0026 pip install .\n# Or with pip\n$ pip install pysmali\n```\n\n## Usage\n\nFor a more detailed explanation of the Smali Visitor-API use the [Github-Pages Docs](https://matrixeditor.github.io/pysmali/).\n\n\u003e **Info**: Make sure you are using ``pysmali\u003e=0.2.0`` as it introduces a user-friendly type system to mitigate possible issues from parsing type descriptors.\n\n### ISmali (Interactive Smali Interpreter)\n\nAs of version `0.1.2` the interactive interpreter can be used to execute Smali code directly:\n\n```bash\n$ ismali example.ssf\n# or start interactive mode\n$ ismali\n\u003e\u003e\u003e vars\n{'p0': \u003cSmaliObject@195f5c0da90\u003e}\n```\n\nSome notes:\n\n* ``p0``: This register always stores the root-instance where defined fields and methods will be stored.\n* ``vars``: This command can be used to print all registers together with their values\n* `L\u003cRoot\u003e;`: The name of the root-context class\n\nThe API [documentation](https://matrixeditor.github.io/pysmali/) provides some usage examples and usage hints.\n\n### Parsing Smali-Files\n\nThe simplest way to parse code is to use a `SmaliReader` together with a visitor:\n\n```python\nfrom smali import SmaliReader, ClassVisitor\n\ncode = \"\"\"\n.class public final Lcom/example/Hello;\n.super Ljava/lang/Object;\n# One line comment\n.source \"SourceFile\" # EOL comment\n\"\"\"\n\nreader = SmaliReader()\nreader.visit(code, ClassVisitor())\n```\n\nThere are a few options to have in mind when parsing with a `SmaliReader`:\n\n* `comments`: To explicitly parse comments, set this variable to True (in constructor or directly)\n* `snippet`: To parse simple code snippets without a .class definition, use the 'snippet' variable (or within the constructor). Use this property only if you don't have a '.class' definition at the start of the source code\n* `validate`: Validates the parsed code\n* `errors`: With values `\"strict\"` or `\"ignore\"` this attribute will cause the reader to raise or ignore exceptions\n\nActually, the code above does nothing as the `ClassVisitor` class does not handle any notification by the reader. For instance, to print out the class name of a parsed code, the following implementation could be used:\n\n```python\nfrom smali import SmaliReader, ClassVisitor, SVMType\n\nclass NamePrinterVisitor(ClassVisitor):\n    def visit_class(self, name: str, access_flags: int) -\u003e None:\n        # The provided name is the type descriptor, so we have to\n        # convert it:\n        cls_type = SVMType(name)\n        print('Class:', cls_type.pretty_name) # prints: com.example.Hello\n\nreader = SmaliReader()\nreader.visit(\".class public final Lcom/example/Hello;\", NamePrinterVisitor())\n```\n\n\u003e [!TIP]\n\u003e There is an example Smali file in this repository. If you want to print out **all**\n\u003e defined classes, you have to implement another method (based on the example above):\n\u003e ```python\n\u003e class NamePrinterVisitor(ClassVisitor):\n\u003e   # ... method from above does not change\n\u003e   def visit_inner_class(self, name: str, access_flags: int) -\u003e ClassVisitor:\n\u003e        cls_type = SVMType(name) # same as above\n\u003e        print(\"Inner Class:\", cls_type.pretty_name)\n\u003e        return self\n\u003e ```\n\n### Writing Smali-Files\n\nWriting is as simple as parsing files. To write the exact same document the has been parsed, the `SmaliWriter` class can be used as the visitor:\n\n```python\nfrom smali import SmaliReader, SmaliWriter\n\nreader = SmaliReader()\nwriter = SmaliWriter()\n\nreader.visit(\".class public final Lcom/example/Hello;\", writer)\n# The source code can be retrieved via a property\ntext = writer.code\n```\n\nTo create own Smali files, the pre-defined `SmaliWriter` can be used again:\n\n```python\nfrom smali import SmaliWriter, AccessType\n\nwriter = SmaliWriter()\n# create the class definition\nwriter.visit_class(\"Lcom/example/Hello;\", AccessType.PUBLIC + AccessType.FINAL)\nwriter.visit_super(\"Ljava/lang/Object;\")\n\n# create a field\nfield_writer = writer.visit_field(\"foo\", AccessType.PRIVATE, \"Ljava/lang/String\")\n\n# create the finished source code, BUT don't forget visit_end()\nwriter.visit_end()\ntext = writer.code\n```\n\n### Importing classes and execute methods\n\nAs of version `0.1.2` you can import Smali files and execute defined methods:\n\n```python\nfrom smali.bridge import SmaliVM, SmaliObject\n\nvm = SmaliVM()\n# Import class definition\nwith open('example.smali', 'r', encoding='utf-8') as fp:\n    smali_class = vm.classloader.load_class(fp, init=False)\n# Call \u003cclinit\u003e method\nsmali_class.clinit()\n\n# Create a new instance of the imported class\ninstance = SmaliObject(smali_class)\n# Call the object's constructor\ninstance.init()\n\n# Execute the method 'toString'\ntoString = instance.smali_class.method(\"toString\")\n# The instance must be always the first element (on\n# static methods this argument must be None)\nvalue = toString(instance)\nprint(value)\n```\n\n\n\n## License\n\nDistributed under the GNU GPLv3. See `LICENSE` for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatrixeditor%2Fpysmali","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatrixeditor%2Fpysmali","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatrixeditor%2Fpysmali/lists"}