r2http
Use radare2's HTTP server as a stateful command transport. The /cmd endpoint executes the HTTP POST body as a raw radare2 command in the running instance. Analysis data, flags, comments, config changes, and the HTTP session's seek state persist across requests.
Rules
- Prefer
POST /cmdfor all normal work. Do not useGET /cmd/<command>except for legacy diagnostics. - Send the r2 command as the raw request body. Do not send
cmd=..., JSON-RPC, or URL query parameters unless you intentionally use r2's{...}command wrapper. - Use
curl -sS --data-binary 'COMMAND' "$R2CMD"so curl does not form-encode or rewrite the command body. - Serialize requests to the same endpoint. Do not run parallel POSTs against one r2/iaito instance because command order and state matter.
- Prefer one r2 command per POST. Use r2's normal
;separator for short compound commands, for examples main;pdfj. - Treat empty output as normal for state-changing commands such as
s,e,aa, comments, flags, and writes. - Treat the endpoint as code execution in the target r2 instance. Avoid destructive commands, writes, debugging actions, or shell escapes unless the user asked for them.
Endpoint Setup
Normalize the endpoint before running commands:
R2CMD=http://127.0.0.1:9393/cmd
curl -sS --data-binary '?V' "$R2CMD"
- If the user provides
host:portorhttp://host:port, append/cmd. - If the user provides
http://host:port/cmdorhttps://host:port/cmd, use it as-is. - If the user provides
r2web://host:port/cmd, convert it tohttp://host:port/cmd. - If authentication is enabled and the user provides credentials, use
curl -u user:pass --data-binary 'COMMAND' "$R2CMD". - If no endpoint is provided and a local session may already exist, list registered r2 web sessions:
r2 -N -q -c '=l' -
Starting a Server
Start a foreground radare2 HTTP server from the shell when you control the process:
r2 -N -e http.bind=localhost -e http.port=9393 -e http.sandbox=false -q -c=h /path/to/file
This command blocks while the server is running. In Codex, run it as a long-running command session, issue POST requests with curl, then stop the process with the controlling terminal or process manager.
Start a background server inside an already running r2 or iaito instance by running these r2 commands in that instance:
e http.bind=localhost
e http.port=9393
e http.sandbox=false
=h& 9393
Notes:
http.bind=localhostis the default safe choice. Usehttp.bind=publiconly when a remote client must connect.http.sandboxdefaults totrue; background=h&requireshttp.sandbox=falseto work properly.- Use
e http.allow=<comma-separated-ips>and HTTP auth if binding outside localhost. - Do not rely on POST to stop the server. Stop foreground servers from the owning terminal/process. Stop background servers from the owning r2/iaito console with
=h-.
Command Patterns
Probe the endpoint:
curl -sS --data-binary '?V' "$R2CMD"
curl -sS --data-binary 'ij' "$R2CMD"
curl -sS --data-binary 's' "$R2CMD"
Run stateful analysis once, then inspect incrementally:
curl -sS --data-binary 'aaa' "$R2CMD"
curl -sS --data-binary 'aflj' "$R2CMD"
curl -sS --data-binary 's main;pdfj' "$R2CMD"
curl -sS --data-binary 'axfj @ main' "$R2CMD"
Use JSON-producing r2 commands for machine-readable output:
curl -sS --data-binary 'pdj 10' "$R2CMD"
curl -sS --data-binary 'aoj' "$R2CMD"
curl -sS --data-binary 'iSj' "$R2CMD"
curl -sS --data-binary 'izzj' "$R2CMD"
Use r2's internal JSON grep when you only need selected fields:
curl -sS --data-binary 'aoj~{opcode}' "$R2CMD"
curl -sS --data-binary 'aflj~{name,addr,size}' "$R2CMD"
Use r2's {...} command wrapper when you need an error/code envelope. The POST body is still a raw r2 command; {...} is parsed by radare2, not by the HTTP layer:
curl -sS --data-binary '{"cmd":"pdj 1","json":true,"trim":true}' "$R2CMD"
curl -sS --data-binary '{"cmd":"s main","trim":true}' "$R2CMD"
Set json:true only when the wrapped command output is valid JSON. Do not use forms like {pdj 1}; the { command expects JSON with a cmd field.
Analysis Workflow
Use this flow for long reverse-engineering tasks:
- Verify the endpoint with
?V, then inspect target metadata withij,iIj,iSj, ando. - Set any required config once, for example
e asm.bytes=false,e scr.color=false, or architecture/bits if the file was opened raw. - Run the minimum useful analysis pass. Start with targeted commands (
aa,aac,af @ addr) when possible; useaaawhen broad analysis is needed. - Pull structured summaries with
aflj,isj,iij,izzj, andaxfjbefore requesting large disassemblies. - Seek or address explicitly in commands (
s addr,cmd @ addr) so later requests are reproducible. - Use
pdfj @ fcn,pdj N @ addr,aoj @ addr, and xref commands for focused analysis. Avoid dumping hugepdor graph output unless necessary. - Preserve state in the server instead of re-running one-liners. Do not repeat expensive analysis unless config or file state changed.
Troubleshooting
curl: (7) Failed to connect: the server is not listening at that host/port, is bound to another interface, or has exited. Check the owning r2 process or runr2 -N -q -c '=l' -.401or403: authentication,http.allow,http.referer, orhttp.colonis blocking the request. Ask for credentials or use an allowed local endpoint.Cannot listen on http.port: the port is busy, network binding is blocked, or the environment disallows listening sockets. Choose another port or request permission to bind localhost.- Empty response with HTTP 200: the command probably changed state without printing. Follow with a read command such as
s,aflj, or the{...}wrapper to inspectcode. - Very large output: switch to JSON commands plus
~{...}filtering, or query a narrower address/function/range.