Skip to content

Repository files navigation

RE-harness

Windows PE static-analysis harness implemented as an OpenCode plugin and built specifically for Qwen 27B/35B models. It provides the model with structured read-only IDA/IDASQL tools.

This project was developed for macOS but can be ported to Linux.

Requirements

The following tools must already be installed before installing RE-harness:

Additional requirements:

  • Python 3.12;
  • CMake and Ninja for building the bundled NeverD/LLVM fallback.

IDA, Hex-Rays, IDASQL, and OpenCode are not distributed with the project.

Installation

git clone --recurse-submodules https://github.com/thatskriptkid/re-harness.git
cd re-harness
python3.12 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/re-harness init-config

The init-config command copies safe templates from config.example/ without overwriting existing settings. After that, specify your endpoint, model ID, artifact root, and allowed sample directories in config/providers.yaml and config/settings.yaml. API keys are stored only in the ignored .env.

Running

.venv/bin/re-harness v5 doctor
.venv/bin/re-harness v5 launch /path/to/sample.exe

v5 launch selects a PE, prepares an IDA database, generates a project-local opencode.json, and opens OpenCode with the re-static-v5-ida agent. Only the IDA tools from this profile are available in OpenCode. Model switching is configured in config/providers.yaml; running the command again regenerates opencode.json.

Verification

.venv/bin/ruff check .
.venv/bin/pytest -q tests
(cd .opencode && node --experimental-strip-types --test ../tests/opencode_v5_plugin.test.ts)

flirtdb is a separate submodule containing signatures; it is not modified by the harness. If the repository was cloned without --recurse-submodules, run:

git submodule update --init --recursive

Large functions: lift → simplify → IDA

V5 returns complete pseudocode for functions up to 40,000 characters long. Lifting is enabled when Hex-Rays fails or when the resulting pseudocode is too large to pass to the model in full. The harness lifts only that function through NeverD into LLVM IR, normalizes provable stack-relative addresses, runs LLVM O3, and redecompiles the resulting COFF in IDA. If the simplified function becomes medium-sized, it is returned to the model in full. The structural fallback is used only if the result still exceeds the full-output limit.

Direct-call and API names are taken from the original IDA database and transferred through a verified provenance map. For unusual callable globals, NeverD requires an exact match of the sequence of direct and indirect calls; if there is any mismatch, such names are not restored. Thus, the simplified pseudocode shows, for example, GetProcAddress and Sleep, but the harness does not guess names.

The LLVM optimizer sources and its regression fixtures are located in tools/large-function-lift. The bundled component can be built as follows:

cmake -S tools/large-function-lift \
  -B tools/large-function-lift/build \
  -G Ninja \
  -DLLVM_DIR=/path/to/neverd/llvm/lib/cmake/llvm
cmake --build tools/large-function-lift/build
ctest --test-dir tools/large-function-lift/build --output-on-failure

The exact modified version of NeverD is stored in third_party/NeverD. After cloning the repository, its large pinned dependencies and build are prepared as follows:

python scripts/bootstrap_neverd_dependencies.py
cmake -S third_party/NeverD -B third_party/NeverD/build -G Ninja \
  -DCMAKE_BUILD_TYPE=Release
cmake --build third_party/NeverD/build

The harness first looks for the project-local NeverD and cff-ir-analyze. Paths to another installation can be specified explicitly if necessary:

export RE_HARNESS_NEVERD=/path/to/neverd
export RE_HARNESS_LARGE_FUNCTION_OPTIMIZER=/path/to/cff-ir-analyze

Results are cached by the sample's SHA-256, the function address, and the hashes of both tools. The fallback can be disabled with large_function_lift_enabled: false in config/settings.yaml.

A separate pipeline version is used for 32-bit PEs. Function boundaries confirmed by IDA are passed to NeverD as numeric --func/--func-end values, LLVM generates i686-pc-windows-msvc and COFF IMAGE_FILE_MACHINE_I386, while accesses through FS are preserved as side-effecting TEB/SEH helpers. cdecl, stdcall, fastcall, and thiscall remain distinguishable; unknown VB6 runtime helpers are not assigned invented semantics.

Each attempt saves a local manifest.json, stage logs, and JSON diagnostics. Models see only a stable stage, reason, and short description. Failure statistics and a ranking of unsupported instructions can be generated without disclosing local paths:

.venv/bin/python scripts/audit_x86_lift_attempts.py \
  /path/to/run-root/v5-idasql/backend/cache \
  --output /path/to/x86-lift-audit.json

License and samples

RE-harness is distributed under AGPL-3.0-only. The modified NeverD is located in third_party/NeverD; its original license, upstream commit, and a description of the integration changes are stored alongside the code. Details are listed in THIRD_PARTY_NOTICES.md.

About

Harness fo malware analysis

Resources

Security policy

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages