r2xsql

ci status

SQL interface for radare2, powered by libxsql.

SELECT name, size FROM funcs WHERE name LIKE 'main%';
SELECT text     FROM strings WHERE text LIKE '%password%';
UPDATE comments SET text = 'reviewed' WHERE addr = 0x1234;

r2xsql exposes radare2's analysis state as live SQL virtual tables: every query re-issues the JSON form of the relevant r2 command (aflj, izj, axtj, …) against an in-process core (r_core_cmd_str) or a spawned radare2 -q0 pipe — no flat dump, no stale snapshot.

It's not read-only — and your work saves

Load the plugin in radare2 and mutate analysis through ordinary SQL writes. Use radare2's -w option when writing binary bytes:

UPDATE funcs   SET name = 'parse_header' WHERE addr = 0x401000;   -- rename
UPDATE funcs   SET prototype = 'int parse_header(char *buf)' WHERE name = 'parse_header';
INSERT INTO comments(addr, text) VALUES (0x401044, 'bounds check missing');
UPDATE locals  SET name = 'len', type = 'int' WHERE func_addr = 0x401000 AND name = 'var_8h';
INSERT INTO types(name, kind) VALUES ('Header', 'struct');
INSERT INTO bookmarks(addr, name) VALUES (0x401000, 'entry-of-interest');

Writable surfaces: funcs (rename, prototype), comments, flags, locals (rename + retype), bookmarks, types (create struct/union/ enum), patches (byte edits), io_maps, bytes.

Persist it. Save analysis with Ps NAME in radare2 or SELECT r2xsql_project_save('NAME') through SQL. Reopen it with P NAME or SELECT r2xsql_project_open('NAME'). The plugin uses radare2's native project format; it does not automatically save on exit.

Requirements

You need radare2. r2xsql does not bundle it and does not install it.

# any one of these
r2pm -ci radare2                       # radare2's own package manager
git clone https://github.com/radareorg/radare2 && radare2/sys/install.sh
sudo apt install radare2               # distro package (may lag; see below)
brew install radare2                   # macOS

Build core_r2xsql against the same radare2 installation that will load it: the in-process plugin depends on radare2's ABI.

Using the plugin

Load the built module and analyze a target:

r2 -i /absolute/path/core_r2xsql.so -A ./target

Use the actual .so, .dylib, or .dll path; omit -i once the plugin is installed in radare2's plugin directory. At the radare2 prompt:

sql SELECT name, size FROM funcs ORDER BY size DESC LIMIT 10
pdf @ entry0
q

For a one-shot query:

r2 -q -A -i /absolute/path/core_r2xsql.so \
  -c '"sql SELECT name, size FROM funcs WHERE size > 100 LIMIT 5"' ./target

Each sql command executes one statement. Quote the whole r2 command when SQL contains r2 operators such as > or |. Use repeated -c options, a radare2 command script, or a persistent session for multiple statements.

Build

Linux / macOS:

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
  -DR2XSQL_BUILD_FULL=ON -DRadare2_ROOT=/path/to/radare2/prefix
cmake --build build

Windows (MSVC):

cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
  -DR2XSQL_BUILD_FULL=ON -DRadare2_ROOT=C:\path\to\radare2\prefix
cmake --build build --config Release

Radare2_ROOT is a radare2 install prefix containing include/libr/ and lib/. R2XSQL_BUILD_FULL=ON enables the libr backend and, when R2XSQL_BUILD_PLUGIN=ON (the default), core_r2xsql in build/bin/ (build/bin/Release/ for the MSVC Release configuration).

Without R2XSQL_BUILD_FULL, CMake builds the backend-neutral static library and examples, with no radare2 build dependency. The r2pipe backend remains available to C++ consumers. R2XSQL_BUILD_EXAMPLES=OFF disables examples. The project also supports being added as a CMake subdirectory.

Building the in-r2 plugin the radare2 way (Makefile / meson)

CMake above builds the library, examples, and plugin, including on Windows. If you only want the in-r2 plugin — the core_r2xsql module that adds the sql command inside radare2 — there is also a radare2-native build that needs no CMake, matching how radare2 plugins are usually built (plugin paths from r2 -H, radare2 from pkg-config r_core):

make                 # -> build-make/core_r2xsql.$(r2 -H R2_LIBEXT)
make user-install    # install into the per-user plugin dir (no root)
make install         # install system-wide (R2_LIBR_PLUGINS)
make test            # load it in r2 and run one SQL query
# only `radare2` (not `r2`) on PATH?  ->  make R2=radare2

or with meson (what radare2 itself uses):

meson setup build-meson
meson compile -C build-meson
meson install -C build-meson                 # into R2_LIBR_PLUGINS
meson setup build-meson -Dr2_user_plugins=true   # ... or the per-user dir

Both build the same plugin: the sql command. Both consume libxsql: the Makefile uses a sibling ../libxsql checkout (else clones it), and meson pulls it as a subproject. A current libxsql is required (same as CMake's FetchContent).

JSON results

Use sqlj for programmatic queries and scripts:

"sqlj SELECT NULL AS missing, '' AS empty; SELECT count(*) AS n FROM funcs"

It returns libxsql's JSON envelope with per-statement columns, rows, errors, and timings. SQL NULL is JSON null, distinct from the empty string. Quoting the entire r2 command also preserves statement separators and SQL operators. The same command works through r2pipe and radare2's HTTP /cmd/ endpoint.

HTTP access through radare2

Load the plugin in a persistent radare2 session and start r2's web server:

r2 -N -q -i /absolute/path/core_r2xsql.so \
  -e http.bind=127.0.0.1 -e http.port=9090 -c aa -c '=h' ./target

Use the plugin's actual .so, .dylib, or .dll path. If it is installed, omit -i. Send a quoted SQL command through r2's POST /cmd/ endpoint:

curl --data-binary '"sql SELECT name, size FROM funcs WHERE size > 100 LIMIT 5"' \
  http://127.0.0.1:9090/cmd/

GET /cmd/<encoded-command> also works for short queries:

from urllib.parse import quote
from urllib.request import urlopen

sql = "SELECT name, size FROM funcs WHERE size > 100 ORDER BY size DESC LIMIT 5"
command = '"sql ' + sql.replace('"', '\\"') + '"'
with urlopen("http://127.0.0.1:9090/cmd/" + quote(command, safe="")) as response:
    print(response.read().decode(), end="")

Quote the whole r2 command, escape any SQL double quotes, then URL-encode it for GET; POST sends the quoted command as the raw body. URL encoding alone does not protect SQL operators such as > and | from r2's command parser. Prefer POST for longer SQL to avoid r2's request-line length limit. Each request executes one SQL statement; the session persists between requests, including analysis and comment changes.

Responses are the plugin's text tables, including the row count. SQL errors appear as ERROR: ... in the body, even with HTTP status 200. The old sql.http* and /query interface is removed; configure the native server with r2's http.* settings instead.

Tests

After building the plugin, with radare2 and a C compiler on PATH:

python3 -m pip install pytest
python3 -m pytest -q tests

The tests load the plugin directly into radare2 and cover the SQL surface and native HTTP integration (GET and POST). They find core_r2xsql in build/, build-make/, build-meson/, or out/. Set R2XSQL_PLUGIN for other layouts and R2_BIN to choose the matching radare2 executable. A missing plugin fails the test run instead of silently skipping coverage.

Backends (internal detail)

The library retains these backends for embedding and testing:

Backend Used by Notes
R2PipeBackend C++ consumers (open_r2pipe) Spawns and manages radare2 -q0 over stdio.
LibrBackend core_r2xsql and C++ consumers (open_libr) Uses radare2 in-process; the plugin wraps its host core.
MockBackend embedding/tests Canned {command → response} map, records issued commands — no live radare2.
MockBackend In-memory mock: canned command→response map, records issued commands — for embedding/offline use without a live radare2.

Skills (Claude Code / Codex)

Agent skills teach Claude Code and Codex to drive r2xsql: query and annotate radare2 analysis through SQL, pick the right backend. They ship in the radare2 community skills catalog, radare2-skills, as the r2xsql/ category alongside dev/ and radius2/. Install a category with its make install (or python install.py install for r2xsql/, which copies rather than symlinks so it needs no elevated rights on Windows).

Start with the connect skill; its references/schema-catalog.md is the canonical reference for the SQL surface.

License and Terms of Use

In short: you may read, build, evaluate, benchmark, package, and use unmodified r2xsql, including commercially, if you preserve notices and follow the license terms. You may fork or patch it to prepare bug fixes, optimizations, features, tests, or documentation improvements for contribution back within the license's contribution-purpose rules.

You may not maintain a divergent private fork, port, rebrand, clone, API-compatible replacement, competing implementation, or use r2xsql as AI input to recreate or improve a derivative implementation without prior written permission from Elias Bachaalany. Independent implementations that are not copied from, materially derived from, or substantially informed by r2xsql in the license's defined sense are not prohibited.

Permission requests: open a GitHub issue at radareorg/r2xsql/issues.

If r2xsql materially informs a distributed project, preserve the human origin: credit r2xsql and Elias Bachaalany visibly in your README/docs and in About/credits UI when applicable. The license includes an examples/FAQ section for common allowed and permission-required uses. Third-party dependencies (libxsql, radare2 (libr / r2pipe), and their transitive dependencies) remain under their own licenses.

See the full Human-Origin Source License v1.0.

S
Description
No description provided
Readme
1.1 MiB
0 Stars 1 Watchers 0 Forks
v0.0.1
Latest
2026-11-07 06:24:06 -10:00
Languages
C++ 90.7%
CMake 4.5%
Makefile 1.4%
Python 1.2%
Meson 1.2%
Other 1%