{"id":37063258,"url":"https://github.com/quarkslab/qbindiff","last_synced_at":"2026-01-14T07:04:15.078Z","repository":{"id":199867669,"uuid":"611360123","full_name":"quarkslab/qbindiff","owner":"quarkslab","description":"Quarkslab Bindiffer but not only !","archived":false,"fork":false,"pushed_at":"2025-05-05T13:48:10.000Z","size":5540,"stargazers_count":208,"open_issues_count":13,"forks_count":12,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-09-29T09:16:56.580Z","etag":null,"topics":["binary-diffing","network-alignment","program-analysis","reverse-engineering","vulnerability-research"],"latest_commit_sha":null,"homepage":"https://diffing.quarkslab.com/qbindiff/doc/source/intro.html","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.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":"2023-03-08T17:02:00.000Z","updated_at":"2025-08-30T07:18:52.000Z","dependencies_parsed_at":"2023-12-01T15:28:24.108Z","dependency_job_id":"5894f8f5-db60-45ef-9564-56d3db72b10d","html_url":"https://github.com/quarkslab/qbindiff","commit_stats":null,"previous_names":["quarkslab/qbindiff"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/quarkslab/qbindiff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqbindiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqbindiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqbindiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqbindiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quarkslab","download_url":"https://codeload.github.com/quarkslab/qbindiff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fqbindiff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["binary-diffing","network-alignment","program-analysis","reverse-engineering","vulnerability-research"],"created_at":"2026-01-14T07:04:14.403Z","updated_at":"2026-01-14T07:04:15.067Z","avatar_url":"https://github.com/quarkslab.png","language":"Python","readme":"# QBinDiff\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/quarkslab/qbindiff/releases\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/v/release/quarkslab/qbindiff?logo=github\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/github/license/quarkslab/qbindiff\"/\u003e\n  \u003ca href=\"https://github.com/quarkslab/qbindiff/releases\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/quarkslab/qbindiff/release.yml\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/github/downloads/quarkslab/qbindiff/total\"/\u003e\n  \u003cimg src=\"https://img.shields.io/pypi/dm/qbindiff\"/\u003e\n\u003c/p\u003e\n\nQBinDiff is an experimental binary diffing tool addressing the diffing as a **Network Alignement Quadratic Problem**.\n\n\u003e But why developing yet another differ when Bindiff works well?\n\nBindiff is great, no doubt about it, but we have no control on the diffing process. Also, it works\ngreat on standard binaries but it lacks flexibility on some corner-cases (embedded firmwares,\ndiffing two portions of the same binary etc...).\n\nA key idea of QBinDiff is enabling tuning the diffing **programmatically** by:\n* writing its own feature\n* being able to enforce some matches\n* emphasizing either on the content of functions (similarity) or the links between them (callgraph)\n\nIn essence, the idea is to be able to diff by defining its own criteria which sometimes, is not the\ncontrol-flow and instructions but could for instance, be data-oriented.\n\nLast, QBinDiff as primarily been designed with the binary-diffing use-case in mind, but it can be\napplied to various other use-cases like social-networks. Indeed, diffing two programs boils down to\ndetermining the best alignment of the call graph following some similarity criterion.\n\nIndeed, solving this problem is APX-hard, that why QBinDiff uses a machine learning approach (more\nprecisely optimization) to approximate the best match.\n\nLike Bindiff, QBinDiff also works using an exported disassembly of program obtained from IDA.\nOriginally using [BinExport](https://github.com/google/binexport), it now also support\n[Quokka](https://github.com/quarkslab/quokka) as backend, which extracted files, are\nmore exhaustive and also more compact on disk (good for large binary dataset).\n\n\u003e [!NOTE]\n\u003e QBinDiff is an experimental tool for power-user where many parameters, features, thresholds\n\u003e or weights can be adjusted. Obtaining good results usually requires tuning these parameters.\n\n*(Please note that QBinDiff does not intend to be faster than other differs, but rather being more flexible.)*\n\n\u003e [!WARNING]\n\u003e QBinDiff graph alignment is very memory intensive (compute large matrices), it can fill RAM if not cautious. \n\u003e Try not diffing binaries larger than +10k functions. For large program use very high sparsity ratio (0.99). \n\n## Documentation\n\nThe documentation can be found on the [diffing portal](https://diffing.quarkslab.com/qbindiff/doc/source/intro.html)\nor can be manually built with\n\n    pip install .[doc]\n    cd doc\n    make html\n\nBelow you will find some sections extracted from the documentation. Please refer to the full\ndocumentation in case of issues.\n\n## Installation\n\nQBinDiff can be installed through pip with:\n\n    pip install qbindiff\n\nAs some part of the algorithm are very CPU intensive the installation\nwill compile some components written in native C/C++.\n\nAs depicted above, QBinDiff relies on some projects (also developed at Quarkslab):\n\n* [python-binexport](https://github.com/quarkslab/python-binexport), wrapper on the BinExport protobuf format.\n* [python-bindiff](https://github.com/quarkslab/python-bindiff), wrapper around bindiff (used to write results as Bindiff databases)\n* [Quokka](https://github.com/quarkslab/quokka), another binary exported based on IDA. Faster than binexport and more exhaustive (thus diffing more relevant)\n\n\n## Usage (command line)\n\nAfter installation, the binary ``qbindiff`` is available in the path.\nIt takes in input two exported files and start the diffing analysis. The result can then\nbe exported in a BinDiff file format.\nThe default format for input files is [BinExport](https://github.com/google/binexport),\nfor a complete list of backend loader look at the `-l1, --primary-loader` option in the help.\nThe complete command line options are:\n\n\n```commandline\n Usage: qbindiff [OPTIONS] \u003cprimary file\u003e \u003csecondary file\u003e                                                                                                                                    \n                                                                                                                                                                                              \n QBinDiff is an experimental binary diffing tool based on machine learning technics, namely Belief propagation.                                                                               \n Examples:                                                                                                                                                                                    \n - For Quokka exports: qbindiff -e1 file1.bin -e2 file2.bin file1.quokka file2.quokka                                                                                                         \n - For BinExport exports, changing the output path: qbindiff -o my_diff.bindiff file1.BinExport file2.BinExport                                                                               \n                                                                                                                                                                                              \n╭─ Output parameters ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n --output  -o   Output file path. (FILE) [default: qbindiff_results.csv]                                                                                                \n --format  -ff  Output file format. (bindiff|csv) [default: csv]                                                                                                        \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n╭─ Primary file options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n --primary-loader      -l1  Enforce loader type. (binexport|quokka|ida)                                                                                                \n --primary-executable  -e1  Path to the raw executable (required for quokka exports). (PATH)                                                                           \n --primary-arch        -a1  Enforce disassembling architecture. Format is like 'CS_ARCH_X86:CS_MODE_64'. (TEXT)                                                        \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n╭─ Secondary file options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n --secondary-loader      -l2  Enforce loader type. (binexport|quokka|ida)                                                                                              \n --secondary-executable  -e2  Path to the raw executable (required for quokka exports). (PATH)                                                                         \n --secondary-arch        -a2  Enforce disassembling architecture. Format is like 'CS_ARCH_X86:CS_MODE_64'. (TEXT)                                                      \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n╭─ Global options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n --verbose  -v  Activate debugging messages. (-v|-vv|-vvv)                                                                                                             \n --quiet    -q  Do not display progress bars and final statistics.                                                                                                     \n --help     -h  Show this message and exit.                                                                                                                            \n --version      Show the version and exit.                                                                                                                             \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n╭─ Diffing parameters ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n --feature         -f   Features to use for the binary analysis, it can be specified multiple times.                  (\u003cfeature\u003e)                                      \n                        Features may be weighted by a positive value (default 1.0) and/or compared with a                                                              \n                        specific distance (by default the option -d is used) like this \u003cfeature\u003e:\u003cweight\u003e:\u003cdistance\u003e.                                                  \n                        For a list of all the features available see --list-features.                                                                                  \n --list-features        List all the available features.                                                                                                               \n --normalize       -n   Normalize the Call Graph (can potentially lead to a partial matching).                                                                         \n --distance        -d   Available distances: (canberra|euclidean|cosine|haussmann) [default: haussmann]                                                                \n --tradeoff        -t   Tradeoff between function content (near 1.0) and call-graph information (near 0.0). (FLOAT) [default: 0.8]                                     \n --sparsity-ratio  -s   Ratio of least probable matches to ignore. Between 0.0 (nothing is ignored) to 1.0 (only perfect matches are considered) (FLOAT) [default: 0.6]\n --sparse-row      -sr  Whether to build the sparse similarity matrix considering its entirety or processing it row per row.                                           \n --epsilon         -e   Relaxation parameter to enforce convergence. (FLOAT) [default: 0.9]                                                                            \n --maxiter         -i   Maximum number of iteration for belief propagation. (INTEGER) [default: 1000]                                                                  \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n╭─ Passes parameters ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n│ --pass-feature-hash    Anchor matches when function have the same feature hash.                                                                                       \n│ --pass-user-defined    Anchor matches using user defined matches. Format is like 'primary-addr1:secondary-addr2,...'. (TEXT)                                          \n│ --pass-flirt-hash      Anchor matches using FLIRT/FunctionID like signatures.                                                                                         \n╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n```\n\n### Quokka example\n\nQuokka exporter needs the path of the executable file so one should also use ``-e1`` and ``-e2``.\n\n    $ qbindiff -e1 primary.exe -e2 secondary.exe primary.exe.Quokka secondary.exe.Quokka\n\nNote that we use default values for all parameters, but one can configure the different\nfeatures used and the various parameters used.\n\n    $ qbindiff -e1 primary.exe \\\n               -e2 secondary.exe \\\n               -f bnb \\             # basic block number\n               -f cc:3.0 \\          # cyclomatic complexity feature\n               -f cst:5.0 \\         # feature based on constants\n               --maxiter 100 \\      # maximum number of iterations \n               primary.exe.Quokka \\\n               secondary.exe.Quokka\n\n### BinExport example\n\nThe most simple example generating a diff file in a ``.BinDiff`` format is:\n\n    $ qbindiff primary.BinExport secondary.BinExport -ff bindiff -o out.BinDiff\n\nBinexport backend used, also relies on capstone for the disassembly of instructions and some features.\nThus for some architecture and especially ARM/thumb mode, one should provide the exact disassembly mode\nusing capstone naming for [architecture identifier](https://github.com/capstone-engine/capstone/blob/f81eb3affaa04a66411af12cf75522cb9649cf83/bindings/python/capstone/__init__.py#L207) and [mode identifiers](https://github.com/capstone-engine/capstone/blob/f81eb3affaa04a66411af12cf75522cb9649cf83/bindings/python/capstone/__init__.py#L231). Thus to diff two binexport files and specifying the exact architecture one can do:\n\n    $ qbindiff primary.BinExport secondary.BinExport -a1 CS_ARCH_ARM:CS_MODE_THUMB -a2 CS_ARCH_ARM:CS_MODE_THUMB\n\n\n## Library usage\n\nThe strength of qBinDiff is to be usable as a python library. The following snippet shows an example\nof loading to binexport files and to compare them using the mnemonic feature.\n\n```python\nfrom qbindiff import QBinDiff, Program\nfrom qbindiff.features import MnemonicTyped\nfrom pathlib import Path\n\np1 = Program(\"primary.BinExport\")\np2 = Program(\"secondary.BinExport\")\n\ndiffer = QBinDiff(p1, p2)\ndiffer.register_feature_extractor(MnemonicTyped, 1.0)\n# Add other features if you want to\n\ndiffer.process()\n\nmapping = differ.compute_matching()\noutput = {(match.primary.addr, match.secondary.addr) for match in mapping}\n```\n## Citing this work\nIf you use QBinDiff in your work, please consider to cite it using these references : \n\n```\n@inproceedings{CAIDQBinDiff,\n  author    = \"Cohen, Roxane and David, Robin and Mori, Riccardo and Yger, Florian and Rossi, Fabrice\",\n  title     = \"Improving binary diffing through similarity and matching intricacies\",\n  booktitle = \"Proc. of the 6th Conference on Artificial Intelligence for Defense\",\n  year      = 2024,\n}\n```\n\n```\n@misc{SSTICQBinDiff,\n  title        = \"QBinDiff: A modular differ to enhance binary diffing and graph alignment\",\n  author       = \"Cohen, Roxane and David, Robin and Mori, Riccardo and Yger, Florian and Rossi, Fabrice\",\n  howpublished = \"\\url{https://www.sstic.org/2024/presentation/qbindiff_a_modular_differ/}\",\n  year         = 2024,\n}\n```\n## Contributing \u0026 Contributors\n\nAny help, or feedback is greatly appreciated via Github issues, pull requests.\n\n**Current**:\n* Robin David\n* Riccardo Mori\n* Roxane Cohen\n\n**Past**:\n* Alexis Challande\n* Elie Mengin\n\n[**All contributions**](https://github.com/quarkslab/qbindiff/graphs/contributors)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fqbindiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquarkslab%2Fqbindiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fqbindiff/lists"}