Skip to content

Latest commit

 

History

886 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

retrace

Build Alpine MSYS2 OHOS FreeBSD Nix checkpatch Coverity Scan

retrace is a userspace security and vulnerability discovery tool that intercepts libc calls in dynamically-linked binaries. It works by preloading a shared library into the target process (LD_PRELOAD on ELF, DYLD_INSERT_LIBRARIES on Darwin, inline hooking on Windows) and either logging or rewriting each intercepted call’s arguments and return value.

Use cases: reverse engineering, debugging, fuzzing (malloc failure injection, getenv buffer-overflow / format-string / garbage fuzzing, incomplete I/O), redirecting network connect() calls, redirecting file open() paths, faking OpenSSL verify results, and more.

Supported platforms (v2.3.3)

OS Architecture Interposition Status

Linux (glibc)

x86_64, aarch64

LD_PRELOAD

Production

Linux (musl / Alpine)

x86_64, aarch64

LD_PRELOAD

Production

Linux (musl / OHOS)

aarch64

LD_PRELOAD

Cross-compile + signed

macOS

arm64 (Apple Silicon)

DYLD_INSERT_LIBRARIES

Production (printf fixed in v2.1.0)

macOS

x86_64 (Intel)

DYLD_INSERT_LIBRARIES

Production (init + FP varargs fixed in v2.1.0)

Android

arm64, x86_64

LD_PRELOAD (wrap.sh / Magisk)

Cross-compile via NDK

FreeBSD / OpenBSD / NetBSD

x86_64

LD_PRELOAD

Production

Windows (MSVC)

x86_64, arm64

Inline hook (from scratch, ADR-0009)

Production

Windows (MinGW)

x86_64

Inline hook

Production

Linux (statically linked)

x86_64, aarch64

ptrace(2)

Production

Pre-built binaries for every platform are attached to each release. Install with one command:

$ curl -sSL https://raw.githubusercontent.com/riboseinc/retrace/main/scripts/install.sh | sh

Quick start

# Install
$ curl -sSL https://raw.githubusercontent.com/riboseinc/retrace/main/scripts/install.sh | sh

# Trace libc calls (text output)
$ retrace trace malloc,free -- /bin/ls

# Trace libc calls (interactive HTML)
$ retrace trace malloc --html -- /bin/ls

# Fuzz malloc at 10% failure rate
$ retrace fuzz malloc --rate 0.1 -- ./your-program

# Mock a return value
$ retrace mock getuid 0 -- ./check-root

# Or use a JSON config for advanced scenarios
$ retrace run --config docs/cookbook/09-fuzz-malloc.json -- ./your-program

See the cookbook for 20+ recipes covering tracing, fuzzing, mocking, redirection, security auditing, and CI integration.

What’s new in v2.4.0

  • Native process attach — retrace attach <pid> — attach to an already-running process via ptrace and trace its syscalls until it exits. No LD_PRELOAD, no restart, no control of the launch required. This reaches the targets the preload backends structurally cannot: any running PID (and static binaries after they started). Output is the same JSON format and feeds the same downstream tools. New public API: retrace_attach_process(pid) and retrace_list_backends(). See the CLI reference.

  • retrace backends — lists the interposition backends compiled into the library (preload-elf, preload-macho, preload-msvc, ptrace, …​).

What’s new in v2.3.x

The v2.3.x series turns retrace from a single CLI into a tools ecosystem: one shared-library backend, plus standalone tools that all consume the same JSON log format.

  • Lock-free SPSC ring logger — per-thread ring with atomic head/tail; a single background flusher thread drains at 1ms cadence. Hot path is now a non-blocking push instead of a mutexed fwrite. Env-gated via RETRACE_LOGGER_RING (default on; disable for OHOS/QEMU).

  • capture_buffer action — post-call memory observation: reads N bytes from a pointer param and logs as hex or string.

  • call_hash — per-thread FNV-1a rolling hash of intercepted libc calls; surfaces as coverage feedback for libFuzzer via a custom mutator.

  • retrace-audit — compliance audit tool. Apply a policy file (baseline / PCI-DSS / HIPAA / ISO 27001 / custom) and emit findings as JSON, SARIF 2.1.0 (GitHub Code Scanning / Azure DevOps), or printable PDF. See cookbook 24.

  • retrace-diff — differential trace analysis. Per-function count + duration diff with --threshold pct=N for CI gating, LCS-based call-order diff (--order), and statistical significance (--stats z-score against N baselines). See cookbook 25 and cookbook 26.

  • retrace-replay — interactive TUI for traces. Step forward/backward, jump to any index, regex search. See cookbook 27.

  • retrace-ws — WebSocket streamer for live traces with a built-in browser viewer at http://localhost:8765/. See cookbook 28.

  • Frida bridge (frida-bridge/retrace-frida.js) — emits retrace-compatible JSON from inside Frida. The escape hatch when LD_PRELOAD can’t reach the target: iOS apps, static binaries, attach to a running PID. See cookbook 29.

  • eBPF bridge (ebpf-bridge/retrace-ebpf.bpf.c) — kernel-level observation of every openat / close syscall on the system. Observation only (eBPF cannot modify calls). See cookbook 30.

  • VS Code extension — renders a retrace JSON log in a webview pane inside the editor; doubles as a retrace-ws client for live streams. See cookbook 31.

  • Grafana data source plugin — loads a retrace JSON log (over HTTP) and exposes events as a Grafana frame. Cache TTL enables self-updating dashboards. See cookbook 32.

  • fuzz-replay CLI subcommand — replay a libFuzzer crash input through the matching harness for quick triage.

  • Nightly fuzz workflow — matrix of 5 fuzzers, 5 minutes each, against the seed corpus. Crash artifacts uploaded for download.

  • Parson OOM hardening — allocation budget (input_len * 1000) on the comment-stripping path; eliminates the OOM vector found by the nightly fuzz workflow.

  • Website features — Decision Wizard, Recipe Builder, Cmd-K search palette, Glossary, Community section, Back-to-top.

See CHANGELOG.md for the full diff per release (v2.3.0 / v2.3.1 / v2.3.2 / v2.3.3).

What’s new in v2.2.0

  • Network function interception — 27 BSD-sockets functions now intercepted (socket, connect, bind, listen, accept, send/recv/sendto/recvfrom, setsockopt/getsockopt, socketpair/accept4/shutdown/sendmsg/recvmsg, the resolver and inet families, getpeername/getsockname).

  • addr_deny action — network deny-list (the address-space counterpart of sandbox). Specs support "host:port", ":443", "[::1]:443", "/var/run/x.sock", "" (deny all).

  • Per-return-address routing — new caller_matches array on each intercept_script. Three match kinds: address, symbol (via dladdr), offset_in_module (ASLR-safe). OR-semantics; any match wins.

  • Per-process dladdr cache — repeat-lookup cost ~10us → ~1us for symbol/module-offset matching.

  • Engine MECE refactor — engine.c split into five single- concern modules (thread_context, reentrance_guard, cleanup, script_resolver, action_runner). New docs/engine-state-machine.md documents the 16-state per-call lifecycle.

  • Property-based test suite — ~26 properties across parson, sockaddr_inspect, actions, script_resolver, caller_match (~26,000 evaluations per ctest run).

  • Action unit-test sweep — all 13 built-in actions have unit tests; the test pyramid now spans unit / property / stress / fuzz / perf.

  • libFuzzer harnessesfuzz_config_parse + fuzz_script_resolve. Opt in via -DRETRACE_BUILD_FUZZERS=ON (clang-only). Smoke runs: 369K and 1.99M iterations respectively, both clean.

  • Stress test frameworkstress_threads: 8 threads x 100K iters x 4 calls/iter = 3.2M intercepted calls per family.

  • Performance benchmark harness — 4 micro-benchmarks with percentile reporting (script_resolve, caller_match, log_params, call_real).

  • Cookbook recipe 17 — per-return-address routing with three working examples.

See CHANGELOG.md for the full diff.

What’s new in v2.1.0

  • Quick CLI subcommandsretrace trace malloc — /bin/ls, retrace fuzz malloc --rate 0.1 — ./server, retrace mock getuid 0, retrace slow open --ms 100. No JSON needed for the 90% use case. Plus retrace pp (built-in text pretty-printer) and retrace html (interactive HTML trace viewer).

  • Built-in HTML trace viewerretrace trace --html — /bin/ls generates a self-contained interactive HTML page. No Python, no git clone. Summary cards, category breakdown, filterable call table.

  • Docker integration — one-line tracing/fuzzing for any container: RUN curl …​ -o /usr/lib/libretrace.so. Pre-built image at ghcr.io/riboseinc/retrace:latest.

  • Binary releases — pre-built .so/.dylib/.dll for 8 platforms. Install via scripts/install.sh (detects OS + arch, downloads the right binary). Stable URLs for Dockerfiles.

  • 12 built-in actions — log_params, call_real, modify_in_param_*, modify_return_value_int, memory_fuzz, incomplete_io, fuzzing_seed, delay (latency injection), call_count_limit (resource exhaustion), sandbox (runtime path deny-list).

  • Android support — cross-compile via NDK for arm64-v8a and x86_64.

  • Engine MECE refactor — engine.c split into thread_context, script_resolver, action_runner (ADR-0013).

  • macOS Intel fixed — dlsym(RTLD_NEXT) fallback for ld64’s silent symbol-drop bug. Intel macOS is now fully production.

  • FP varargs on x86_64 — xmm0..7 saved in trampoline; printf("%f") works correctly on Linux, BSD, macOS.

  • Homebrew formulabrew tap riboseinc/retrace && brew install retrace.

  • Cookbook — 20+ recipes: tracing, fuzzing, mocking, redirection, security audit, CI integration, sandbox, enprot cross-link.

  • Tools — flamegraph (SVG), logpp (text), benchmark (overhead).

  • Per-platform binary artifacts in every release: 10 platforms
    source tarball.

Build

retrace uses CMake. vcpkg manifest mode pulls OpenSSL and cmocka on Windows automatically; system packages provide them on POSIX.

$ cmake -B build -G Ninja -DRETRACE_BUILD_TESTS=ON
$ cmake --build build
$ ctest --test-dir build --output-on-failure
$ sudo cmake --install build
Tip

Quick smoke test without installing:

# Linux / BSD
LD_PRELOAD=$PWD/build/src/v2/libretrace.so /bin/id

# macOS (Apple Silicon)
DYLD_INSERT_LIBRARIES=$PWD/build/src/v2/libretrace.dylib /bin/id

# Windows (PowerShell, after install)
$env:RETRACE_JSON_CONFIG = "config.json"
retrace-win-run myapp.exe  # injects retrace.dll (hooks + boot in the child)

Useful CMake options:

Option

Default / purpose

RETRACE_BUILD_V2

ON — build the retrace shared library (libretrace.so / .dylib / .dll).

RETRACE_BUILD_CLI

ON — build the CLI launcher (placeholder; full CLI in a future release).

RETRACE_BUILD_TESTS

OFF — build per-feature test binaries under test/.

RETRACE_BUILD_EXAMPLES

OFF — build the demos under examples/.

RETRACE_ENABLE_RPC

OFF — build the optional RPC subsystem under rpc/.

RETRACE_ENABLE_ASAN / _UBSAN / _TSAN / _COVERAGE

OFF — instrumentation toggles.

Running

$ RETRACE_JSON_CONFIG=<config.json> LD_PRELOAD=build/src/v2/libretrace.so <binary>

On macOS replace LD_PRELOAD with DYLD_INSERT_LIBRARIES:

$ RETRACE_JSON_CONFIG=<config.json> DYLD_INSERT_LIBRARIES=build/src/v2/libretrace.dylib <binary>

Environment variables:

Variable

Purpose

RETRACE_JSON_CONFIG

Path to a JSON config file (see below). If unset, retrace uses a built-in default that activates log_params + call_real for every intercepted function.

RETRACE_LOGGER_DEF_ENA

0 disables the logger entirely.

RETRACE_LOGGER_DEF_STDOUT_ENA

0 keeps retrace’s log off stdout so it doesn’t mix with the target’s own output.

RETRACE_LOGGER_DEF_FN

Path to a log file (alternative to stderr).

RETRACE_LOGGER_RING

1 (default): lock-free SPSC ring + background flusher. 0: synchronous writes (OHOS/QEMU/debug).

RETRACE_LOGGER_RING_CAP

Per-thread ring capacity (power of 2 in 64..65536). Default 1024.

RETRACE_CALL_HASH

Note

On macOS, System Integrity Protection strips DYLD_INSERT_LIBRARIES for binaries in system directories. Run csrutil disable and reboot to trace them.

JSON configuration

retrace is driven by a JSON config file. The top-level shape:

{
  "intercept_scripts": [
    {
      "func_name": "<glob or exact symbol>",
      "actions": [
        { "action_name": "<action>", "action_params": { ... } },
        ...
      ]
    },
    ...
  ]
}

A func_name of "*" matches every intercepted symbol. Otherwise the name must match a libc symbol retrace knows about (see src/core/prototypes/ for the canonical list, grouped by header: stdio.c, stdlib.c, unistd.c, dirent.c, uio.c, signal.c, ctype.c, locale.c).

Actions run in the order listed. Each action either observes the call, mutates an argument, mutates the return value, or skips the real call entirely.

Built-in actions

Action Effect Required params

log_params

Log the call (function name + arguments) to the configured logger.

none

call_real

Invoke the real libc implementation. Omit this action to skip the real call entirely (return zero / NULL).

none

modify_in_param_str

Rewrite a string argument before the real call runs.

param_name, new_str; optional match_str to gate the rewrite on the current value

modify_in_param_int

Rewrite an integer argument before the real call runs.

param_name, new_int; optional match_int to gate the rewrite

modify_in_param_arr

Rewrite an array argument before the real call runs.

param_name, new_arr (see src/core/actions/basic.c for layout)

modify_return_value_int

Override the integer return value (after call_real if present).

retval_int

memory_fuzz

Randomly fail malloc / realloc / calloc (returns NULL). Useful for finding unchecked allocator returns.

fail_rate (float, 0..1)

New behaviors are added by registering a new action — no engine change required (see src/core/actions/basic.c for the pattern).

Intercepted functions

retrace ships ~490 prototypes grouped by libc header. The canonical list lives under src/core/prototypes/. Add a function by adding a struct FuncPrototype entry to the right header file (and a WRAPPER_ENTRY_* line in the matching funcs_symbols.S).

Header Count Notable symbols

ctype.h

28

isalpha, isdigit, tolower, toupper, …​

dirent.h

13

opendir, readdir, closedir, …​

locale.h

4

setlocale, localeconv, …​

signal.h

5

kill, signal, raise, …​

stdio.h

165

fopen, fclose, fread, fwrite, printf, fprintf, sprintf, snprintf, dprintf, vprintf, vfprintf, vsprintf, vsnprintf, vdprintf, scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf, fgets, perror, popen, …​

stdlib.h

73

malloc, calloc, realloc, free, getenv, system, exit, atoi, strtol, …​

uio.h

8

readv, writev, …​

unistd.h

198

read, write, open, close, fork, execve, getuid, getpid, getenv, socket, connect, recv, send, …​

\ Variadic.* printf/scanf-family prototypes are tagged FAT_PRINTF / FAT_SCANF and go through the variadic-aware dispatcher so they work on every platform’s ABI:

  • Apple AArch64: variadic args are pushed onto the caller’s stack (Apple’s ABI).

  • Linux/BSD AArch64 (AAPCS64): variadic args go in x1..x7, then the stack.

  • x86-64 (Sys V / Darwin): variadic args go in rdi..r9, then the stack.

On glibc, modern gcc redirects scanf / fscanf / sscanf / vscanf / vsscanf / vfscanf to isoc99_* at the PLT. retrace intercepts both the plain names (older binaries, musl, BSD) and the isoc99_* names (modern glibc binaries) when the CMake link-check confirms the symbol exists.

Tip

Float varargs (%f, %g, %e) on AArch64 are currently bailed out to a "named args only" fallback (see src/core/printf_compat.h). The integer/pointer/string conversions all work; FP-on-AArch64 needs the SIMD-reg save-area walk that is on the roadmap (ADR-0010).

Examples

Log every libc call (the default)

{
  "intercept_scripts": [
    {
      "func_name": "*",
      "actions": [
        { "action_name": "log_params" },
        { "action_name": "call_real" }
      ]
    }
  ]
}

Redirect getenv("TEST") to getenv("PATH")

{
  "intercept_scripts": [
    {
      "func_name": "getenv",
      "actions": [
        { "action_name": "log_params" },
        {
          "action_name": "modify_in_param_str",
          "action_params": { "param_name": "name", "match_str": "TEST", "new_str": "PATH" }
        },
        { "action_name": "call_real" }
      ]
    }
  ]
}

Force getuid() to return 42

{
  "intercept_scripts": [
    {
      "func_name": "getuid",
      "actions": [
        { "action_name": "call_real" },
        { "action_name": "modify_return_value_int", "action_params": { "retval_int": 42 } }
      ]
    }
  ]
}

Fuzz malloc (10% failure rate)

{
  "intercept_scripts": [
    {
      "func_name": "malloc",
      "actions": [
        { "action_name": "call_real" },
        { "action_name": "memory_fuzz", "action_params": { "fail_rate": 0.1 } }
      ]
    }
  ]
}

Fuzzing-only mode (no log noise)

When you’re running memory_fuzz over a large program, the default log_params + call_real for every libc call produces gigabytes of JSON you don’t care about. Two ways to suppress it:

1. Disable the logger entirely (zero JSON output, fuzz still runs):

$ RETRACE_LOGGER_DEF_ENA=0 \
  RETRACE_JSON_CONFIG=fuzz.json \
  LD_PRELOAD=build/src/v2/libretrace.so ./your-program

2. Allowlist only the function you’re fuzzing (log only malloc):

{
  "intercept_scripts": [
    {
      "func_name": "malloc",
      "actions": [
        { "action_name": "log_params" },
        { "action_name": "call_real" },
        { "action_name": "memory_fuzz", "action_params": { "fail_rate": 0.1 } }
      ]
    }
    /* NOTE: no "*" wildcard script -- every other libc call goes
     * through retrace's trampoline but the engine finds no matching
     * script and just calls real. No log noise. */
  ]
}

End-to-end examples under examples/

Directory What it demonstrates

examples/dns-fuzz/

Fuzz DNS resolution paths

examples/getenv-fuzzing/

Buffer-overflow and format-string fuzzing of getenv

examples/http-server-overflow/

HTTP server input fuzzing

examples/id-redirection/

Redirect getuid/geteuid to fake privileges

examples/net-fuzzing/

Network call fuzzing

examples/stringinject/

File/string injection helper (paired with tools/stringinjector)

examples/unsafe-system/

Trace system() invocation paths

Tooling ecosystem

retrace ships one shared-library backend plus standalone tools that consume the same JSON log format. Each owns one job; mix and match freely.

Tool Job

retrace-audit

Apply a policy file (baseline / PCI-DSS / HIPAA / ISO 27001 / custom) and emit findings as JSON, SARIF 2.1.0, or PDF.

retrace-diff

Per-function count + duration diff between two traces, with --threshold for CI gating, --order for LCS call-sequence diff, and --stats for z-score significance.

retrace-replay

Interactive TUI: step / rewind / jump / regex-search through events.

retrace-ws

Tail a running trace and broadcast over WebSocket; built-in browser viewer at http://localhost:8765/.

retrace attach <pid>

Attach to a running process via ptrace and trace its syscalls until it exits — no preload, no restart (Linux).

retrace-to-otlp

Convert a retrace JSON log to OTLP/JSON for Jaeger / Tempo / Honeycomb / Datadog.

frida-bridge/retrace-frida.js

Frida script emitting retrace-compatible JSON. Use when LD_PRELOAD can’t reach the target (iOS, static binaries, attach to running PID).

ebpf-bridge/retrace-ebpf.bpf.c

Linux kernel-level BPF program observing every openat / close syscall on the system. Observation only.

vscode-extension/

VS Code extension: renders a trace in a webview pane, doubles as a retrace-ws client for live streams.

grafana-plugin/

Grafana data source: load a trace over HTTP, expose events as a frame for time series / bar gauge / state timeline panels.

For task-driven recipes covering every tool, see the tools overview and the cookbook (32 recipes and counting).

Architecture

retrace is built around five clean concepts. Each is a MECE module extensible without modifying the others (Open/Closed Principle).

Per-arch trampoline

One hand-written assembly trampoline per function. Pushes the SysV / Microsoft x64 / AArch64 PCS register arguments into a frame, calls retrace_engine_wrapper(func_name, frame), then either tail-calls the real implementation (if the engine set call_real_flag) or returns the synthesized ret_val. Lives under src/backends/preload_*/{x86_64,aarch64}/arch_spec_top.S.

Engine

retrace_engine_wrapper (in src/core/engine.c) is the central dispatch. Per-thread struct ThreadContext holds the prototype, real impl pointer, and parsed params. The engine looks up the matching intercept_script and runs its actions in order.

Action registry

Built-in actions live in src/core/actions/{basic,memfuzz}.c and self-register into a linker section the engine scans at init. Adding a new behavior = adding a new action file; no engine change.

Backend plugin system

Each (OS, arch) combo has its own backend (preload_elf, preload_macho, preload_bsd, preload_msvc, preload_mingw, ptrace). Backends self-register via a constructor-section scan; retrace_backend_select() picks the highest-rank backend whose probe() succeeds. See include/retrace/backend.h.

Real-impl indirection

All internal libc usage inside retrace goes through retrace_real_impls.<fn> function pointers, resolved once at init via dlsym(RTLD_NEXT, …​). This is the reentrancy guard — bypass it and you recurse.

Init order matters (see src/core/main.c constructor): retrace_as_initretrace_real_impls_initretrace_logger_init → parson alloc hooks → retrace_conf_initretrace_loger_update_configretrace_engine_initretrace_funcs_initretrace_datatypes_initretrace_actions_initretrace_as_init_late.

Architecture Decision Records under docs/adr/ capture the load-bearing decisions:

ADR

Topic

0006

Semantic versioning

0008

Opaque public types for ABI stability

0009

From-scratch Windows inline-hooking (no MinHook / Detours)

0010

AArch64 float params supported from day one

0011

v1 source removed at v2.1.0 (supersedes 0005)

Migrating from v1

v1’s source code was removed at the v2.1.0 release (ADR-0011). If you were running v1, the table below maps every v1 concept to its v2 equivalent.

v1

v2

libretrace.so (single library, per-function C wrappers)

libretrace.so (single library, single assembly trampoline per function + JSON-driven engine)

retrace shell-script CLI launcher

LD_PRELOAD / DYLD_INSERT_LIBRARIES directly. A native CLI is on the roadmap.

RETRACE_CONFIG=<file> (line-oriented text config)

RETRACE_JSON_CONFIG=<file.json> (JSON; default config activates log_params + call_real for *)

getuid,0 (text: func,value)

{ "func_name": "getuid", "actions": [{"action_name":"modify_return_value_int", "action_params":{"retval_int":0}}] }

fopen,/etc/passwd,/tmp/passwd

{ "action_name": "modify_in_param_str", "action_params": {"param_name":"path", "match_str":"/etc/passwd", "new_str":"/tmp/passwd"} }

connect,src_ip,src_port,dst_ip,dst_port

Use modify_in_param_arr on the sockaddr argument (the v1 line had no exact equivalent — v2’s action is more general).

SSL_get_verify_result,10

{ "action_name": "modify_return_value_int", "action_params": {"retval_int":10} }

memoryfuzzing,0.05

{ "action_name": "memory_fuzz", "action_params": {"fail_rate":0.05} }

incompleteio,10

Not yet ported to v2’s action system. Track via issue tracker if you need it.

fuzzingseed,1498729252

Not yet ported to v2. The memory_fuzz action uses rand() seeded from the PID; explicit seeding is on the roadmap.

logtofile,retrace.log

RETRACE_LOGGER_DEF_FN=retrace.log

logging-global,…​ / logging-excluded-funcs,…​ / logging-allowed-funcs,…​

Use multiple intercept_scripts entries with explicit func_name globs (allowlist model). Per-group log levels are not yet ported.

showtimestamp / showcalltime,0.0001

Not yet ported to v2. On the roadmap.

Autotools build: ./configure --enable-v2 && make

CMake: cmake -B build && cmake --build build

RETRACE_CLI=1 (interactive pty menu)

Removed. Will be replaced by the native CLI when it lands.

v1 examples under examples/*/retrace.conf

Still in the tree as v1-format text configs. They will be ported to v2 JSON in a follow-up.

What was removed in v2.1.0:

  • The entire v1 source tree (src/v1/).

  • The Autotools build system (configure.ac, Makefile.am, m4/, autogen.sh, configure, etc.). CMake is the only build system.

  • The retrace shell-script launcher. Use LD_PRELOAD until the native CLI lands.

  • The RETRACE_CONFIG text-format config file. Use RETRACE_JSON_CONFIG.

  • The interactive pty CLI (RETRACE_CLI=1).

What was renamed:

  • The installed library is libretrace.so / libretrace.dylib / retrace.dll (was libretrace_v2.* briefly during the transition; the _v2 suffix was dropped at v2.1.0 because v1 no longer exists).

Known gaps (tracking in GitHub issues)

Platform / feature Status

dlopen under LD_PRELOAD on Linux

#450: malloc path inside libdl recurses / reenters retrace; skipped in CI.

Float varargs (%f, %g, %e)

Engine bails to asm Path A (correct output, no log_params entry for the call). Integer, pointer, and string conversions work end-to-end including log_params. Full SIMD-reg dispatch is on the roadmap (ADR-0010).

sprintf / snprintf / fprintf / dprintf interception

Added in v2.1.0 (PR #469). All printf-family + v*printf variants are now in the prototype registry.

scanf family interception

Added in v2.1.0 (PR #470). scanf / fscanf / sscanf / vscanf / vsscanf / vfscanf plus glibc _isoc99* variants.

Incomplete-I/O action

v1’s incompleteio,10 has no v2 action equivalent yet.

Explicit fuzzing seed

v1’s fuzzingseed,1498729252 is not yet ported. memory_fuzz uses rand() seeded from the PID.

Who is Ribose?

We are Ribose, the secure sharing company. We believe privacy and security form the foundation of liberty. We created retrace to aid developers and security researchers in building better, more defensible software.

Contact

  • Security issues, feature requests, and bug reports: GitHub Issues

  • General questions: retrace@ribose.com

About

retrace is a versatile security vulnerability / bug discovery tool through monitoring and modifying the behavior of compiled binaries on Linux, OpenBSD/FreeBSD/NetBSD (shared object) and macOS (dynamic library).

Resources

Stars

68 stars

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages