{"id":43496612,"url":"https://github.com/quarkslab/qsynthesis","last_synced_at":"2026-02-03T10:38:36.535Z","repository":{"id":42172985,"uuid":"390976730","full_name":"quarkslab/qsynthesis","owner":"quarkslab","description":"Greybox Synthesizer geared for deobfuscation of assembly instructions.","archived":false,"fork":false,"pushed_at":"2025-02-16T13:24:15.000Z","size":6899,"stargazers_count":158,"open_issues_count":1,"forks_count":20,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-08-30T20:30:43.572Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://quarkslab.github.io/qsynthesis/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quarkslab.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}},"created_at":"2021-07-30T07:42:13.000Z","updated_at":"2025-08-01T14:44:30.000Z","dependencies_parsed_at":"2022-08-11T09:21:12.868Z","dependency_job_id":"9c0865af-4489-4483-854b-2ccb8e6402bb","html_url":"https://github.com/quarkslab/qsynthesis","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/quarkslab/qsynthesis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqsynthesis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqsynthesis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqsynthesis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqsynthesis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quarkslab","download_url":"https://codeload.github.com/quarkslab/qsynthesis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqsynthesis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29041866,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2026-02-03T10:38:33.605Z","updated_at":"2026-02-03T10:38:36.525Z","avatar_url":"https://github.com/quarkslab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Qsynthesis\n\nQSynthesis is a Python3 API to perform I/O based program synthesis\nof bitvector expressions. It aims at facilitating code deobfuscation.\nThe algorithm is greybox approach combining both a blackbox I/O based\nsynthesis and a whitebox AST search to synthesize sub-expressions *(if\nthe root node cannot be synthesized)*. \n\nThis algorithm as originaly been described at the BAR academic workshop:\n\n* [QSynth: A Program Synthesis based Approach for Binary Code Deobfuscation](https://archive.bar/pdfs/bar2020-preprint9.pdf)\n  (benchmark used are available: [here](https://github.com/werew/qsynth-artifacts))\n\nThe code has been release as part of the following Black Hat talk:\n\n* [Greybox Program Synthesis: A New Approach to Attack Dataflow Obfuscation](https://www.blackhat.com/us-21/briefings/schedule/index.html#greybox-program-synthesis-a-new-approach-to-attack-dataflow-obfuscation-22930)\n\n**Disclaimer: This framework is experimental, and shall only be used for experimentation purposes.\nIt mainly aims at stimulating research in this area.**\n\n\n## Documentation\n\nThe installation, examples, and API documentation is available on the dedicated documentation: [Documentation](https://quarkslab.github.io/qsynthesis)\n\n\n## Functionalities\n\nThe core synthesis is based on [Triton](https://triton.quarkslab.com) symbolic engine on which is built\nthe whole framework. It provides the following functionalities:\n\n* synthesis of bitvector expressions\n* ability to check through SMT the semantic equivalence of synthesized expressions\n* ability to synthesize constants *(if the expression encode a constant)*\n* ability to improve oracles (pre-computed tables) overtime through a learning mechanism\n* ability to reassemble synthesized expression back to assembly\n* ability to serve oracles through a REST API to facilitate the synthesis usage  \n* an IDA plugin providing an integration of the synthesis\n\n\n## Quick start\n\n### Installation\n\nIn order to work Triton first has to be installed: [install documentation](https://triton.quarkslab.com/documentation/doxygen/index.html#install_sec).\nTriton does not automatically install itself in a virtualenv, copy it in your venv or use --system-site-packages when configuring your venv.\n\nThen:\n\n    $ git clone https://github.com/quarkslab/qsynthesis.git\n    $ cd qsynthesis\n    $ pip3 install '.[all]'\n\nThe ``[all]`` will installed all dependencies *(see the documentation for a light install)*.\n\n### Table generation\n\nThe synthesis algorithm requires generating oracle tables derived from a grammar *(a\nset of variables and operators)*. Qsynthesis installation provides the utility ``qsynthesis-table-manager``\nenabling manipulating tables. The following command generate a table with 3 variables of 64 bits,\n5 operators using a vector of 16 inputs. We limit the generation to 5 million entries.\n\n    $ qsynthesis-table-manager generate -bs 64 --var-num 3 --input-num 16 --random-level 5 --ops AND,NEG,MUL,XOR,NOT --watchdog 80 --limit 5000000 my_oracle_table\n    Generate Table\n    Watchdog value: 80.0\n    Depth 2 (size:3) (Time:0m0.23120s)\n    Depth 3 (size:21) (Time:0m0.23198s)\n    Depth 4 (size:574) (Time:0m0.26068s)\n    Depth 5 (size:400858) (Time:0m21.23231s)\n    Threshold reached, generation interrupted\n    Stop required\n    Depth 5 (size:5000002) (Time:4m52.56009s) [RAM:9.52Gb]\n\n\n\nNote: The generation process is RAM consuming the ``--watchdog`` enables setting a\npercentage of the RAM above which the generation is interrupted.\n\n### Synthesizing a bitvector expression\n\nWe then can try simplifying a seemingly obfuscated expression with:\n\n```python\nfrom qsynthesis import SimpleSymExec, TopDownSynthesizer, InputOutputOracleLevelDB\n\nblob = b'UH\\x89\\xe5H\\x89}\\xf8H\\x89u\\xf0H\\x89U\\xe8H\\x89M\\xe0L\\x89E\\xd8H\\x8bE' \\\n       b'\\xe0H\\xf7\\xd0H\\x0bE\\xf8H\\x89\\xc2H\\x8bE\\xe0H\\x01\\xd0H\\x8dH\\x01H\\x8b' \\\n       b'E\\xf8H+E\\xe8H\\x8bU\\xe8H\\xf7\\xd2H\\x0bU\\xf8H\\x01\\xd2H)\\xd0H\\x83\\xe8' \\\n       b'\\x02H!\\xc1H\\x8bE\\xe0H\\xf7\\xd0H\\x0bE\\xf8H\\x89\\xc2H\\x8bE\\xe0H\\x01\\xd0' \\\n       b'H\\x8dp\\x01H\\x8bE\\xf8H+E\\xe8H\\x8bU\\xe8H\\xf7\\xd2H\\x0bU\\xf8H\\x01\\xd2' \\\n       b'H)\\xd0H\\x83\\xe8\\x02H\\t\\xf0H)\\xc1H\\x89\\xc8H\\x83\\xe8\\x01]\\xc3'\n\n# Perform symbolic execution of the instructions\nsymexec = SimpleSymExec(\"x86_64\")\nsymexec.initialize_register('rip', 0x40B160)  # arbitrary address\nsymexec.initialize_register('rsp', 0x800000)  # arbitrary stack\nsymexec.execute_blob(blob, 0x40B160)\nrax = symexec.get_register_ast(\"rax\")  # retrieve rax register expressions\n\n# Load lookup tables\nltm = InputOutputOracleLevelDB.load(\"my_oracle_table\")\n\n# Perform Synthesis of the expression\nsynthesizer = TopDownSynthesizer(ltm)\nsynt_rax, simp = synthesizer.synthesize(rax)\n\nprint(f\"expression: {rax.pp_str}\")\nprint(f\"synthesized expression: {synt_rax.pp_str} [{simp}]\")\n```\n\n## Limitations\n\n* synthesis accuracy limited by pre-computed tables exhaustivness\n* table generation limited by RAM consumption\n* reassembly cannot involve memory variable, destination is necessarily a register and\n  architecture depends on llvmlite *(thus mostly x86_64)*\n* the code references trace-based synthesis which is disabled *(as the underlying\n  framework is not yet open-source)*  \n\n## Authors\n\n* Robin David (@RobinDavid), Quarkslab\n\n## Contributors\n\nHuge thanks to contributors to this research:\n\n* Luigi Coniglio\n* Jonathan Salwan\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fqsynthesis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquarkslab%2Fqsynthesis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fqsynthesis/lists"}