{"id":34066763,"url":"https://github.com/oriori1703/sigmatcher","last_synced_at":"2025-12-14T06:48:33.664Z","repository":{"id":241638816,"uuid":"805916964","full_name":"oriori1703/sigmatcher","owner":"oriori1703","description":"Write signatures to automatically match java classes and methods between versions","archived":false,"fork":false,"pushed_at":"2025-12-11T11:53:57.000Z","size":604,"stargazers_count":11,"open_issues_count":1,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-12T08:20:09.328Z","etag":null,"topics":["android","apk","java","reverse-engineering"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oriori1703.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-25T20:52:17.000Z","updated_at":"2025-12-11T11:54:00.000Z","dependencies_parsed_at":"2024-05-29T12:48:42.307Z","dependency_job_id":"9a181377-6f61-4017-b83a-b6e46d51ea52","html_url":"https://github.com/oriori1703/sigmatcher","commit_stats":null,"previous_names":["oriori1703/sigmatcher"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/oriori1703/sigmatcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oriori1703%2Fsigmatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oriori1703%2Fsigmatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oriori1703%2Fsigmatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oriori1703%2Fsigmatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oriori1703","download_url":"https://codeload.github.com/oriori1703/sigmatcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oriori1703%2Fsigmatcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27720211,"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-12-14T02:00:11.348Z","response_time":56,"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":["android","apk","java","reverse-engineering"],"created_at":"2025-12-14T06:48:30.019Z","updated_at":"2025-12-14T06:48:33.654Z","avatar_url":"https://github.com/oriori1703.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sigmatcher\n\n[![PyPI - Version](https://img.shields.io/pypi/v/sigmatcher.svg)](https://pypi.org/project/sigmatcher)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sigmatcher.svg)](https://pypi.org/project/sigmatcher)\n\n-----\n\nSigmatcher is a powerful tool designed to automate the process of matching Java classes and methods across different\nversions of an application.\nIt leverages signature on the smali (disassembled java code) to identify and correlate code elements, making it an\ninvaluable resource for long-running reverse engineering projects.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Usage](#quick-usage)\n- [Creating Signature Files](#creating-signature-files)\n  - [Signature File JSON Schema](#signature-file-json-schema)\n  - [Structure of a Signature File](#structure-of-a-signature-file)\n  - [Using Macros in Signatures](#using-macros-in-signatures)\n- [License](#license)\n\n## Installation\n\nBefore installing `sigmatcher`, ensure you have the following prerequisites installed:\n\n- `ripgrep`: A command-line search tool that recursively searches your current directory for a regex pattern.\n  Install `ripgrep` by following the instructions on its [GitHub page](https://github.com/BurntSushi/ripgrep).\n- `apktool`: A tool for reverse engineering and disassembling Android apk files.\n  Install `apktool` by following the instructions on its [official website](https://ibotpeaches.github.io/Apktool/install/).\n\n```console\ngit clone https://github.com/oriori1703/sigmatcher.git\npip install ./sigmatcher\n```\n\n## Quick Usage\n\nTo get started with sigmatcher, follow these steps:\n\n1. **Create a Signature File**: Signature files (.yaml) define the patterns and signatures that Sigmatcher will use to\n   analyze the APK files.\n   These files should specify the classes, methods, and fields you're interested in, along with any version-specific\n   information. See the [Creating Signature Files](#creating-signature-files) section example for the format.\n2. **Analyze an APK**: With your signature file ready, you can now analyze an APK to find matches for your signatures.\n   Use the sigmatcher analyze command, specifying the path to the APK and the signature file(s):\n\n   ```shell\n   sigmatcher analyze path/to/your/app.apk --signatures path/to/your/signature_file.yaml\n   ```\n\n   This command will decode the APK, apply the signatures, and output the analysis results, highlighting matched\n   classes, methods and fields.\n\n## Creating Signature Files\n\nSignature files are YAML formatted documents that `sigmatcher` uses to identify and match Java classes, methods, and\nfields in APK files. These files allow you to specify the elements you're interested in tracking across different\nversions of an application.\n\n### Signature File JSON Schema\n\nTo help you create a signature file `sigmatcher` provides a JSON schema that you can use to validate your signature, and\nget autocompletion and intellisense from your IDE.\nYou can get it by running the following command:\n\n```shell\nsigmatcher schema --output definitions.schema.json\n```\n\nYou can add the one of the following comments to the top of your signature file depending on your IDE:\n\nIntellij IDEs:\n\n```yaml\n# $schema: ./definitions.schema.json\n```\n\nyaml-language-server IDEs (vs-code, neovim, etc):\n\n```yaml\n# yaml-language-server: $schema=./definitions.schema.json\n```\n\nYou can also combine them to support both:\n\n```yaml\n# $schema: ./definitions.schema.json\n# yaml-language-server: $schema=./definitions.schema.json\n```\n\n### Structure of a Signature File\n\nA signature file consists of a list of definitions, where each definition represents a class, method, or field you want\nto match. Each definition can include one or more signatures, which are patterns `sigmatcher` will use to find matches\nin the smali code.\n\nHere's a basic example of what a signature file looks like:\n\n```yaml\n# $schema: ./definitions.schema.json\n# yaml-language-server: $schema=./definitions.schema.json\n\n- name: \"ConnectionManager\"\n  package: \"com.example.package.network\"\n  signatures:\n    - signature: 'ConnectionManager/openConnection: could not open connection due to a DNS error'\n      type: regex\n      count: 1\n  methods:\n    - name: \"read\"\n      signatures:\n        - signature: 'const-string v\\d+, \"Failed to read data from the server\"'\n          type: regex\n          count: 1\n          version_range: \"\u003e=1.0.0, \u003c1.3.7\"\n        - signature: 'const-string v\\d+, \"Failed to read data because of a network error\"'\n          type: regex\n          count: 1\n          version_range: \"\u003e=1.3.7\"\n  fields:\n    - name: \"socket\"\n      signatures:\n        - signature: '^\\.field private final (?P\u003cmatch\u003e.+:Ljava/net/Socket;)'\n          type: regex\n          count: 1\n```\n\n#### Key Components\n\n- name: The name of the class, method, or field.\n- methods: A list of method definitions within a class. Follows a similar structure to the class definition.\n- fields: A list of field definitions within a class. Follows a similar structure to the class definition.\n- exports: A list of export definitions within a class. Exports can be any string in the code. They are mainly used in\n  combination with macros to create more complex signatures.\n- signatures: A list of signatures for the class, method, or field. Each signature includes:\n  - type: The type of signature (for now only `regex` and `glob`).\n  - signature: The pattern to match, depending on the signature type.\n      For classes and methods they just need to match anywhere within the class/method. For fields and exports, they\n      need to match the full field expression/export string, i.e. using the `match` capture group for regex signatures.\n  - count: The number of times the signature should appear to be considered a match. Can be either an integer or a string of the form \"min-max\". Defaults to 1.\n  - version_range: Optional. Specifies the application versions this signature applies to, using version specifiers\n      like those used by pip and described in\n      [PEP-440](https://packaging.python.org/en/latest/specifications/version-specifiers/#version-specifiers).\n      This could also contains a list of specifers, which act like a the logical \"or\" operator.\n\nMost of those fields are optional, and you can use them as needed.\n\n### Using Macros in Signatures\n\nMacros allow you to reference properties from other matched results within your signatures,\nenabling dynamic and context-aware pattern matching.\nMacros are particularly useful when you need to create signatures that depend on information\nfrom previously matched classes, methods, fields, or exports.\n\n#### Macro Syntax\n\nMacros use the format `${\u003cresult_name\u003e.\u003cproperty\u003e}`, where:\n\n- `result_name` is the name of another definition in your signature file\n- `property` is a property of the matched result object\n\n#### Available Properties\n\nDepending on the type of result, different properties are available:\n\n**For Classes:**\n\n- `name`: The class name (e.g., \"ConnectionManager\")\n- `package`: The package name (e.g., \"com.example.package.network\")\n- `full_name`: The complete class name with package (e.g., \"com.example.package.network.ConnectionManager\")\n- `java`: The Java representation (e.g., \"Lcom/example/package/network/ConnectionManager;\")\n- `fields.FieldName`: Access to specific field results (e.g., `fields.socket` returns the matched field object)\n- `methods.MethodName`: Access to specific method results (e.g., `methods.read` returns the matched method object)\n- `exports.ExportName`: Access to specific export results (e.g., `exports.someExport` returns the matched export object)\n\n**For Methods:**\n\n- `name`: The method name (e.g., \"read\")\n- `argument_types`: The method argument types (e.g., \"Ljava/lang/String;\")\n- `return_type`: The method return type (e.g., \"V\")\n- `java`: The complete Java representation (e.g., \"read(Ljava/lang/String;)V\")\n\n**For Fields:**\n\n- `name`: The field name (e.g., \"socket\")\n- `type`: The field type (e.g., \"Ljava/net/Socket;\")\n- `java`: The complete Java representation (e.g., \"socket:Ljava/net/Socket;\")\n\n**For Exports:**\n\n- `value`: The exported string value\n\n#### Macro Example\n\nHere's an example showing how macros can be used to create interdependent signatures:\n\n```yaml\n# $schema: ./definitions.schema.json\n# yaml-language-server: $schema=./definitions.schema.json\n\n- name: \"ConnectionManager\"\npackage: \"com.example.package.network\"\nsignatures:\n - signature: 'ConnectionManager/openConnection: could not open connection due to a DNS error'\n   type: regex\n   count: 1\nfields:\n - name: \"socket\"\n   signatures:\n     - signature: '^\\.field private final (?P\u003cmatch\u003e.+:Ljava/net/Socket;)'\n       type: regex\n       count: 1\n\n- name: \"NetworkHandler\"\npackage: \"com.example.package.network\"\nsignatures:\n - signature: 'new-instance v\\d+, ${ConnectionManager.java}'\n   type: regex\n   count: 1\nmethods:\n - name: \"handleConnection\"\n   signatures:\n     - signature: 'iget-object v\\d+, v\\d+, ${ConnectionManager.fields.socket.java}'\n       type: regex\n       count: 1\n```\n\nIn this example:\n\n- The `NetworkHandler` class uses a macro to reference the Java representation of the `ConnectionManager` class\n- The `handleConnection` method uses a macro to reference the socket field from the `ConnectionManager` class\n\n#### Important Notes\n\n- **Definition Order Doesn't Matter**: Sigmatcher automatically sorts the dependency graph, so macros can reference results that are defined later in the YAML file\n- Macros are resolved at analysis time after the dependency graph is sorted\n- If a macro references a result that cannot be matched, the signature will fail to match\n- Use the `java` property when you need the complete Java/Smali representation of a class, method, or field\n- Macros work with both `regex` and `glob` signature types\n\n## License\n\n`sigmatcher` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foriori1703%2Fsigmatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foriori1703%2Fsigmatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foriori1703%2Fsigmatcher/lists"}