From b963f73b26c27497feb6479483a73ed36f5c7614 Mon Sep 17 00:00:00 2001 From: Dan Phung Date: Thu, 24 Sep 2026 14:42:25 -0700 Subject: [PATCH 1/2] package the chb API for PyPI as codehawk-binary Replace setup.py with a PEP 621 pyproject.toml. - name: codehawk-binary (import name stays chb) - version read from chb/app/CHVersion.py - requires-python >=3.9 since six modules use builtin generics - no dependencies because the package is stdlib-only, - packages restricted to chb* - explicit package-data for bchsummaries.jar, bch_header.c, and the two opcodes_covered.json files that exist. ConfigLocal.py is gitignored local configuration that sits inside the package, so a wheel built from a working copy would embed a developer's absolute analyzer paths. This is excluded explicitly and release.yml builds from a fresh checkout. Also adds chb/py.typed, since the package is fully annotated and CI already runs mypy over it. The analyzer itself is deliberately not packaged: it is a separate OCaml build invoked over subprocess, and Config() keeps locating it through ConfigLocal.py. --- .github/workflows/release.yml | 68 +++++++++++++++++++++++++++++++++++ README.md | 17 +++++++-- chb/py.typed | 0 pyproject.toml | 56 +++++++++++++++++++++++++++++ setup.py | 10 ------ 5 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 chb/py.typed create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..a177afa2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: release + +# Builds the distribution on every pull request so packaging problems surface in +# review, and publishes to PyPI when a version tag is pushed. +on: + pull_request: + workflow_dispatch: + inputs: + publish_to_testpypi: + description: "Also publish the built distribution to TestPyPI" + type: boolean + default: false + push: + tags: ["v*"] + +jobs: + build: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v6 + with: + python-version: "3.11" + - name: Install build tooling + run: python -m pip install --upgrade build twine + - name: Build sdist and wheel + run: python -m build + - name: Check metadata + run: twine check dist/* + - name: Show what is in the wheel + run: python -m zipfile -l dist/*.whl + - uses: actions/upload-artifact@v7 + with: + name: dist + path: dist/ + + # Dry run, on demand: same artifact, TestPyPI instead of PyPI. TestPyPI keeps + # every version it has seen, so a repeat run needs a bumped chbversion. + publish-testpypi: + if: github.event_name == 'workflow_dispatch' && inputs.publish_to_testpypi + needs: build + runs-on: ubuntu-22.04 + environment: testpypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v7 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + publish: + # Tags only. Trusted publishing, so no API token is stored in the repository. + if: startsWith(github.ref, 'refs/tags/v') + needs: build + runs-on: ubuntu-22.04 + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v7 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index 5d78cd73..3355b9ef 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,21 @@ interface can be invoked as follows (adjust paths for actual location): This will show an [overview](doc/cli-output.txt) of the commands available. -At present the analyzer supports x86 (32-bits), both ELF and PE32, mips32, -and arm32 (both ARM and Thumb-2) binaries (ELF only); arm32 is stil under active +## Installing the python API + +The python API is published on PyPI, so a script that imports `chb` needs no +`PYTHONPATH`: + +``` +> pip install codehawk-binary +> python -c "import chb; print(chb.__file__)" +``` + +The distribution contains the python API only. Running an analysis additionally +needs the CodeHawk Binary Analyzer (see Requirements section). + +At present the analyzer supports x86 (32-bits), both ELF and PE32, mips32, and +arm32 (both ARM and Thumb-2) binaries (ELF only); arm32 is stil under active development and thus somewhat experimental. ### Requirements diff --git a/chb/py.typed b/chb/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..f42b4ea1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,56 @@ +[build-system] +requires = ["setuptools>=77"] +build-backend = "setuptools.build_meta" + +[project] +name = "codehawk-binary" +description = "Python API for the CodeHawk Binary Analyzer" +readme = "README.md" +license = "MIT" +license-files = ["LICENSE"] +requires-python = ">=3.9" +authors = [{ name = "Aarno Labs LLC", email = "codehawk@aarno-labs.com" }] +keywords = ["binary analysis", "reverse engineering", "static analysis", "abstract interpretation"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Security", + "Topic :: Software Development :: Disassemblers", + "Typing :: Typed", +] +# The package imports nothing outside the standard library. +dependencies = [] +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/static-analysis-engineering/CodeHawk-Binary" +Source = "https://github.com/static-analysis-engineering/CodeHawk-Binary" +Issues = "https://github.com/static-analysis-engineering/CodeHawk-Binary/issues" + +[tool.setuptools.dynamic] +version = { attr = "chb.app.CHVersion.chbversion" } + +# Include only the chb package in the distribution. Without this filter, package +# discovery also picks up doc/ and tests/ and installs them as importable +# top-level names in every environment that installs this package. +[tool.setuptools.packages.find] +include = ["chb*"] + +# ConfigLocal.py is gitignored local configuration that exists in most working +# copies. It is a .py file inside the package, so discovery would otherwise bake +# a developer's absolute analyzer paths into the distribution. +[tool.setuptools.exclude-package-data] +"chb.util" = ["ConfigLocal.py"] + +# Config() opens each of these by path inside the installed package, so they must +# be included in the wheel. A wheel holding only .py files imports fine and then +# fails at runtime with FileNotFoundError under site-packages. +[tool.setuptools.package-data] +"chb" = ["py.typed"] +"chb.summaries" = ["bchsummaries.jar", "bch_header.c"] +"chb.util" = ["localetable.json", "ConfigLocal.template"] +"chb.arm.opcodes" = ["opcodes_covered.json"] +"chb.pwr.opcodes" = ["opcodes_covered.json"] diff --git a/setup.py b/setup.py deleted file mode 100644 index 0067fcee..00000000 --- a/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, find_namespace_packages - -setup( - name="chb", - packages=find_namespace_packages(), - include_package_data=True, - zip_safe=False, - entry_points={}, - install_requires=[], -) From db46bff4f447d358aae15684d45a2d8b115920c7 Mon Sep 17 00:00:00 2001 From: Dan Phung Date: Fri, 25 Sep 2026 10:42:37 -0700 Subject: [PATCH 2/2] Update min python version in README to 3.9 Runtime floor is 3.9, set by three PEP 585 builtin generics in chb/cmdline/reportcmds.py: 1503: ... instr: "Instruction") -> tuple[Optional[int], str]: <- function signature 1620: intermediate_callgraph: Dict[str,List[tuple[str,...]]] = ... <- variable annotation 1796: os_cmd_construction: List[tuple[str, ...]] = [] <- variable annotation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3355b9ef..393ae058 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ development and thus somewhat experimental. Ensure you have `zip` installed. -The command-line interface requires python3.5 or higher. +The command-line interface requires python 3.9 or higher. Build instructions for the CodeHawk Binary Analyzer are available [here](https://github.com/static-analysis-engineering/codehawk/tree/master/CodeHawk).