Compare commits

..
5 Commits
Author SHA1 Message Date
pancake 83b96f7a3e fiif 2025-10-03 18:21:20 +02:00
pancake e2ee8cdbb6 rjo 2025-10-03 17:36:29 +02:00
pancake 8630e95d83 morebecnh 2025-10-03 17:06:20 +02:00
pancake e07293e40f Initial benchmark working 2025-10-03 16:48:56 +02:00
pancake 415c546f92 Bench 2025-10-03 16:01:31 +02:00
148 changed files with 5968 additions and 10686 deletions

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- buildsystem
+65 -84
View File
@@ -1,7 +1,7 @@
name: CI and Release
env:
R2V: 6.2.6
R2V: 6.0.4
on:
push:
@@ -26,7 +26,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Setup Meson/Ninja
if: matrix.build_system == 'meson'
@@ -34,11 +34,38 @@ jobs:
python -m pip install --upgrade pip
pip install meson ninja
- name: Install radare2
id: r2
uses: radareorg/github-actions@v3
with:
version: ${{ env.R2V }}
- name: Install radare2 on Linux
if: matrix.os == 'ubuntu-24.04'
run: |
wget "https://github.com/radareorg/radare2/releases/download/${R2V}/radare2_${R2V}_amd64.deb"
wget "https://github.com/radareorg/radare2/releases/download/${R2V}/radare2-dev_${R2V}_amd64.deb"
sudo dpkg -i "radare2_${R2V}_amd64.deb"
sudo dpkg -i "radare2-dev_${R2V}_amd64.deb"
- name: Install radare2 on macOS
if: matrix.os == 'macos-latest'
run: |
git clone --depth=1 --branch "${{env.R2V}}" https://github.com/radareorg/radare2
cd radare2
sys/install.sh
- name: Install radare2 on Windows
if: matrix.os == 'windows-latest'
shell: powershell
run: |
$url = "https://github.com/radareorg/radare2/releases/download/${{ env.R2V }}/radare2-${{ env.R2V }}-w64.zip"
$dest = "$env:TEMP\radare2.zip"
Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing
$prefix = 'C:\radare2'
if (Test-Path $prefix) { Remove-Item -Path $prefix -Recurse -Force }
Expand-Archive -Path $dest -DestinationPath $prefix -Force
# Move contents from subdirectory if present
$subdirs = Get-ChildItem -Path $prefix -Directory
if ($subdirs.Count -eq 1) {
$subdir = $subdirs[0]
Get-ChildItem -Path $subdir.FullName | Move-Item -Destination $prefix -Force
Remove-Item -Path $subdir.FullName -Recurse -Force
}
- name: Build with Make
if: matrix.build_system == 'make'
@@ -48,7 +75,7 @@ jobs:
if: matrix.build_system == 'meson' && matrix.os != 'windows-latest'
run: |
cd src
meson setup build || meson configure build
meson setup build -Dr2_prefix=${{ secrets.R2_PREFIX }} || meson configure build
meson compile -C build
- name: Build with Meson (Windows)
@@ -56,92 +83,48 @@ jobs:
shell: powershell
run: |
cd src
$prefix = "${{ steps.r2.outputs.prefix }}"
$prefix = 'C:\radare2'
meson setup build --backend ninja --prefix="$prefix" -Dr2_prefix="$prefix"
if ($LASTEXITCODE -ne 0) { meson configure build }
meson compile -C build
bindist:
name: Build r2pm binary (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install radare2
uses: radareorg/github-actions@v3
with:
version: ${{ env.R2V }}
- name: Package r2pm binary
run: make -C src bindist
- name: Upload r2pm binary artifact
uses: actions/upload-artifact@v7
with:
name: bindist-${{ matrix.os }}
path: r2ai-*.zip
if-no-files-found: error
windows-bindist:
name: Build r2pm binary (Windows)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Meson/Ninja
- name: Create release artifacts (tags only)
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
python -m pip install --upgrade pip
pip install meson ninja
mkdir -p release
cp -rf src/r2ai.dll src/r2ai.exe src/r2ai src/r2ai.dylib src/r2ai.so release/ || true
cp -rf src/build/r2ai src/build/r2ai.dylib src/build/r2ai.so release/ || true
cp -f decai/decai.r2.js release/ || true
if command -v zip >/dev/null 2>&1; then
zip -j "release/r2ai-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.build_system }}.zip" release/*
else
powershell.exe -Command "Compress-Archive -Path release/* -DestinationPath 'release/r2ai-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.build_system }}.zip'"
fi
- name: Install radare2
id: r2
uses: radareorg/github-actions@v3
- name: Upload artifacts (tags only)
if: startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v4
with:
version: ${{ env.R2V }}
name: ${{ matrix.os }}-${{ matrix.build_system }}-binary
path: release/r2ai-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.build_system }}.zip
- name: Build with Meson
shell: powershell
run: |
cd src
$prefix = "${{ steps.r2.outputs.prefix }}"
meson setup build --backend ninja --prefix="$prefix" -Dr2_prefix="$prefix"
if ($LASTEXITCODE -ne 0) { meson configure build }
meson compile -C build
- name: Package r2pm binary
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path bindist\plugins,bindist\bin,bindist\prompts | Out-Null
Get-ChildItem src\build\ -Filter "*r2ai*.dll" -ErrorAction SilentlyContinue | Copy-Item -Destination bindist\plugins
Get-ChildItem src\..\build\ -Filter "*r2ai*.dll" -ErrorAction SilentlyContinue | Copy-Item -Destination bindist\plugins
Copy-Item src\build\r2ai.exe bindist\bin
Copy-Item prompts\*.r2ai.md bindist\prompts
$rv = (& radare2 -qv).Trim()
Compress-Archive -Path bindist\* -DestinationPath "r2ai-$rv-windows-x86-64.zip" -Force
- name: Upload r2pm binary artifact
uses: actions/upload-artifact@v7
with:
name: windows-bindist
path: r2ai-*.zip
if-no-files-found: error
# - name: Smoke test
# run: |
# if command -v r2 >/dev/null 2>&1; then
# r2 -q -c 'r2ai -h' -- || true
# fi
release:
name: Create Release
needs: [bindist, windows-bindist]
needs: build
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Verify tag is on master
run: |
@@ -151,20 +134,18 @@ jobs:
exit 0
fi
- name: Download r2pm binary artifacts
uses: actions/download-artifact@v8
- name: Download artifacts
uses: actions/download-artifact@v4
with:
pattern: '*bindist*'
path: release-artifacts
merge-multiple: true
- name: Add decai.r2.js to release artifacts
run: cp decai/decai.r2.js release-artifacts/
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@v1
with:
files: |
release-artifacts/*.zip
release-artifacts/**/*.zip
release-artifacts/decai.r2.js
generate_release_notes: true
generate_release_notes: true
-3
View File
@@ -12,6 +12,3 @@ venv
*.dylib
*.a
third_party
# r2pm binary packages
r2ai-*.zip
-14
View File
@@ -1,14 +0,0 @@
SHELL=/bin/bash
MODELS=gpt-oss:20b gemma3:4b gemma3:12b
MODELS+=granite3-dense:8b mannix/jan-nano:latest yi-coder:latest qwen3:latest deepseek-coder-v2:latest hhao/qwen2.5-coder-tools:latest qwen2.5-coder:latest
MODELS=granite3-dense:8b mannix/jan-nano:latest yi-coder:latest qwen3:latest deepseek-coder-v2:latest hhao/qwen2.5-coder-tools:latest qwen2.5-coder:latest
LANGS=Dart Perl Ruby Javascript PHP C
all:
for a in ${MODELS} ; do \
declare -a ARGS; \
for l in ${LANGS} ; do \
ARGS+=("echo \"decai -e model=$$a;decai -e lang=$$l;s 0x100000924;af;decai -d\" | r2 -q /bin/ls"); \
done ; \
./run.sh "$${ARGS[@]}" > ${a//\//_}.html ; done
+1 -1
View File
@@ -49,7 +49,7 @@ python3 main.py
**Example selecting a remote models:**
```
[r2ai:0x00006aa0]> -m anthropic:claude-sonnet-5-5
[r2ai:0x00006aa0]> -m anthropic:claude-3-7-sonnet-20250219
[r2ai:0x00006aa0]> -m openai:gpt-4
```
+7 -4
View File
@@ -62,7 +62,7 @@ Uncensored:
Remote:
-m openapi:http://localhost:5001
-m openai:gpt-4
-m anthropic:claude-sonnet-5-5
-m anthropic:claude-3-7-sonnet-20250219
-m bedrock:anthropic.claude-3-5-sonnet-20241022-v1
-m kobaldcpp:http://localhost:5001
"""
@@ -80,9 +80,12 @@ OpenAI:
-m openai:gpt-4
-m openai:gpt-4-1106-preview
Anthropic:
-m anthropic:claude-opus-4-8
-m anthropic:claude-sonnet-5-5
-m anthropic:claude-haiku-4-5-20251001
-m anthropic:claude-2.1
-m anthropic:claude-3-haiku-20240307
-m anthropic:claude-3-opus-20240229
-m anthropic:claude-3-sonnet-20240229
-m anthropic:claude-3-5-sonnet-20241022
-m anthropic:claude-3-7-sonnet-20250219
groq:
-m groq:gemma-7b-it
-m groq:llama2-70b-4096
+2 -1
View File
@@ -170,7 +170,8 @@ def slurp_until(endword):
def list_models():
print("ollama/llama3:latest")
print("ollama/granite-code:8b")
print("anthropic/claude-sonnet-5-5")
print("anthropic/claude-3-5-sonnet-20240620")
print("anthropic/claude-3-7-sonnet-20250219")
print("openai/gpt-4o")
print("mistral/mistral-tiny")
+3 -14
View File
@@ -50,16 +50,8 @@ def stt(seconds, lang):
return
tts("(r2ai) listening for 5s... ", "digues?", lang)
print(f"DEVICE IS {device}")
try:
os.remove(".audiomsg.wav")
except OSError:
pass
result = subprocess.run(
["ffmpeg", "-f", "avfoundation", "-t", "5", "-i", device, ".audiomsg.wav"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
rc = result.returncode
os.system("rm -f .audiomsg.wav")
rc = os.system(f"ffmpeg -f avfoundation -t 5 -i '{device}' .audiomsg.wav > /dev/null 2>&1")
if rc != 0:
tts("(r2ai)", "cannot record from microphone. missing permissions in terminal?", lang)
return
@@ -68,10 +60,7 @@ def stt(seconds, lang):
result = model.transcribe(".audiomsg.wav")
else:
result = model.transcribe(".audiomsg.wav", language=lang)
try:
os.remove(".audiomsg.wav")
except OSError:
pass
os.system("rm -f .audiomsg.wav")
tts("(r2ai)", "ok", lang)
text = result["text"].strip()
if text == "you":
+1
View File
@@ -0,0 +1 @@
recursive-include r2ai/ui *.tcss
+2 -7
View File
@@ -1,9 +1,4 @@
TARGETS=all clean mrproper user-install install user-uninstall uninstall fmt indent
TARGETS=all clean mrproper user-install install user-uninstall uninstall
$(TARGETS):
$(MAKE) -C src $@
test: all
$(MAKE) -C test
.PHONY: $(TARGETS) test
.PHONY: $(TARGETS)
+20 -39
View File
@@ -19,17 +19,14 @@
This repository contains two plugins for radare2:
* **r2ai** - native [AI plugin](./src/README.md) for radare2
* **decai** - r2js plugin with special [focus on decompilation](./decai/README.md)
* **r2ai** - native plugin for radare2
* **decai** - r2js plugin with special focus on decompilation
If you are looking to use radare2 with other agents via MCP:
* **r2mcp** - the [official radare2 mcp](https://github.com/radare2/radare2-mcp)
* **r2copilot** - the mcp with focus on CTF [r2copilot](https://github.com/darallium/r2-copilot)
If you are looking for a radare2 focused autonomous agent:
* **r2agent** - automate radare2 workflows through autonomous agents. [r2agent](https://github.com/nitanmarcel/r2agent)
## Features
* Configure different roles and customize prompts
@@ -40,21 +37,12 @@ If you are looking for a radare2 focused autonomous agent:
* RAG markdown, code or textfiles using its native vector database
* Embed the output of an r2 command and resolve questions on the given data
## User defined Prompts
## Practical Examples
```console
[0x00000000]> r2ai -q
explain: Explain the current function -
devices: Find and explain devices used -
libs: Group imports by Libraries -
varnames: Better variable names -
autoname: Automatically suggest a better name for this function -
vulns: Find vulnerabilities or bugs in the current function -
signature: Suggest an improved function signature -
dlopen: List libraries loaded with dlopen - Some libraries are loaded
decompile: Augmented decompilation based on LLM -
[0x00000000]>
```
* Enhanced decompilation with `r2ai -d`
* Autoname functions with `r2ai -n`
* Explain function with `r2ai -x`
* Find vulnerabilities with `r2ai -V`
## Installation
@@ -70,46 +58,39 @@ $ r2pm -Uci decai
- Adds the **r2ai** command to the radare2 shell: `r2 -qc r2ai`
- You can also run the wrapper in $PATH: `r2pm -r r2ai`
Drop your API keys in environment variables or use the configuration file:
Drop your API keys in environment variables or files in your home:
```console
$ export ANTHROPIC_API_KEY=sk-ant-api03-CENSORED
$ cat ~/.r2ai.anthropic-key
sk-ant-api03-CENSORED
$ export OPENAI_API_KEY=sk-proj-6rlSPS-zN1v...
```
Or edit the api keys file `~/.config/r2ai/apikeys.txt` run:
| AI | API key |
| --------- | -------------------------- |
| OpenAI | `$HOME/.r2ai.openai-key` |
| Gemini | `$HOME/.r2ai.gemini-key` |
| Anthropic | `$HOME/.r2ai.anthropic-key` |
| Mistral | `$HOME/.r2ai.mistral-key` |
```console
$ r2ai -K
```
## Saving settings
You may customize and save your configuration settings using your OS's default settings file (e.g `~/.radare2rc` on Linux).
For example, the following configuration sets Claude 3.7 by default, with max output tokens to 64000.
```console
$ r2ai -E
```
then you can type the commands you want to run when the r2ai plugin is loaded:
```console
r2ai -e api=anthropic
r2ai -e model=claude-sonnet-5-5
r2ai -e model=claude-3-7-sonnet-20250219
r2ai -e max_tokens=64000
```
## Further Reading
## Documentation
* There's [a chapter](https://book.rada.re/plugins/r2ai.html) in the official r2book
* Cryptax on [lmstudio+gptoss](https://cryptax.medium.com/r2ai-with-lmstudio-and-gpt-oss-08efa5ea2476) blog post
* Malware analysis [with r2ai](https://arxiv.org/pdf/2504.07574) by Cryptax and Daniel Nakov
* Analysis of [Linux/Trigona ransomware](https://cryptax.medium.com/linux-trigona-analysis-with-r2ai-3e2bd1815e52), [Linux/Prometei botnet](https://cryptax.medium.com/reversing-a-prometei-botnet-binary-with-r2-and-ai-part-one-3cdb3dc6ffab) and [W32/SkyAI](https://cryptax.medium.com/w32-skyai-uses-ai-so-do-i-d33f04d63534with) with r2ai
* Malware analysis [with r2ai](https://github.com/cryptax/talks/blob/master/BSidesKristiansand-2025/r2ai.pdf) by Cryptax
## Videos
- [Solving a crackme](https://infosec.exchange/@radareorg/111946255058894583)
- [De-obfuscation of malware Linux/Ladvix](https://asciinema.org/a/724126)
- [Analysis of the /fast option inside Linux/Trigona ransomware](https://asciinema.org/a/pBPEaJhp6cunWSKFpBUDTgPt4)
- https://infosec.exchange/@radareorg/111946255058894583
+1 -1
View File
@@ -1 +1 @@
1.5.4
1.1.1
+1 -4
View File
@@ -1,6 +1,3 @@
#!/bin/sh
vim decai/src/constants.ts
make -C decai/src
vim src/r2ai.h
vim src/meson.build
vim src/r2ai.c
vim VERSION
-13
View File
@@ -1,13 +0,0 @@
# Decompiler based AI
## Actions
* Build: `make -C src`
* Install: `make user-install`
* Test: `r2 -A -qc "decai -e api=ollamacloud;decai -e model=glm-5;decai -d @ 0x100000924" /bin/ls`
## Hints
* Never read the minified, autogenerated `decai.r2.js`
* Focus and work only on the TypeScript source
* Never run `tsc` or `npx`. Always use `make` targets to compile
+6 -5
View File
@@ -1,16 +1,17 @@
PD=$(shell r2 -H R2_USER_PLUGINS)
SPD=$(shell r2 -H R2_LIBR_PLUGINS)
BF=/bin/dd
#BF=/bin/dd
BF=a.out
all:
@echo "Run: 'make user-install' to install it in your home"
@echo "Run: 'make -C src' to recompile the r2.js"
@echo "Run: make user-install"
test:
@echo 'You can now use 'decai' command'
r2 -i decai.r2.js -c 'decai -e deterministic=true' -caf $(BF)
fmt indent:
$(MAKE) -C src fmt
deno fmt
user-install:
mkdir -p "$(PD)"
@@ -26,4 +27,4 @@ uninstall:
make user-uninstall PD=$(SPD)
vs open:
open -a "Visual Studio Code" src
open -a "Visual Studio Code" .
-39
View File
@@ -37,7 +37,6 @@ Usage: decai (-h) ...
decai -dd [..] - same as above, but ignoring cache
decai -dD [query]- decompile current function with given extra query
decai -e - display and change eval config vars
decai -E - edit decai.txt
decai -h - show this help
decai -i [f] [q] - include given file and query
decai -n - suggest better function name
@@ -56,12 +55,10 @@ Configuration options:
```console
[0x00000000]> decai -e
decai -e api=ollama
decai -e apitype=chat
decai -e host=http://localhost
decai -e port=11434
decai -e prompt=Rewrite this function and respond ONLY with code, NO explanations, NO markdown, Change 'goto' into if/else/for/while, Simplify as much as possible, use better variable names, take function arguments and strings from comments like 'string:'
decai -e ctxfile=
decai -e headers=
decai -e cmds=pdc
decai -e cache=false
decai -e lang=C
@@ -99,16 +96,6 @@ decai -e ctxfile=
...
```
Persist user defaults in `~/.config/r2ai/decai.txt` with one `key=value` entry
per line, then edit it with `decai -E`. That file is loaded on the first
`decai` command in a session and reloaded after `decai -E` exits.
Use `decai -e http=curl` to force system curl, `http=r2` to require `r2.http()`,
or `http=auto` (the default) to use `r2.http()` when available and curl otherwise.
Failed `r2.http()` calls return an error without falling back to curl. The
`timeout` setting applies only to system curl. Save `http=curl` in
`~/.config/r2ai/decai.txt` to persist the override.
List possible APIs to discuss with AI: `decai -e api=?`:
```
@@ -119,14 +106,6 @@ openapi
...
```
Extra headers can be injected globally with `decai -e headers=...` or from the
environment with `DECAI_HEADERS` / `R2AI_HEADERS`. Use one header per line, for
example:
```console
[0x00406cac]> decai -e headers=Authorization: Bearer sk-123\nUser-Agent: curl/8.7.1
```
### Example using a local model and ollama
For example, if Ollama serves model codegeex4:latest (`ollama ls`), set decai
@@ -218,21 +197,3 @@ void daemonize() {
}
...
```
## WASM HTTP
With radare2's WASI HTTP build, decai defaults to `r2.http()` to reach the existing
`r_socket_http_get/post` C APIs. Headers and JSON payloads go directly to the
host HTTP adapter; no shell curl, temporary payload file or WebSocket proxy is
needed. A failed/denied HTTP call is returned as an error, without a shell
fallback. In `http=auto` mode, runtimes without `r2.http()` use system curl.
Enable HTTP in the embedding application (`enabled: true` in JavaScript or
`network=True` in Python). The radare2 sandbox must permit both `socket` and
`network`; process execution is not needed. Browser requests remain subject
to CORS. The host adapter controls the HTTP deadline in WASM; decai's `timeout`
setting still controls native curl only. Responses are buffered, not streamed.
This requires radareorg/radare2#27037 and the rebuilt decai script. For the
C r2ai plugin compiled into WASM, the `auto` HTTP backend likewise selects
radare2's C HTTP implementation; native backend selection is unchanged.
+1241 -61
View File
File diff suppressed because it is too large. Load diff
-36
View File
@@ -1,36 +0,0 @@
# decai r2plugin
Boilerplate to embed `decai.r2.js` inside the radare2 core library using the
external plugin system (XPS). Unlike `r2ai/r2plugin`, this does not link any
native code: the r2.js script is converted into a C buffer and registered as
an embedded startup script, so r2 runs it at startup exactly like a file in
the `plugins/*.r2.js` directory (honoring `cfg.plugins`).
The `decai.r2.js` bundle is built from the typescript sources with
`r2frida-compile` (see `make -C src` in the decai directory). The C buffer is
generated at build time with `rax2 -C` (make builds) or `js2c.py` (meson).
## Usage
decai lives inside the r2ai repository, so expose it as `libr/xps/p/decai`:
```console
cd radare2/libr/xps/p
git clone https://github.com/radareorg/r2ai
ln -s r2ai/decai decai
```
For acr/make builds:
```console
cd radare2
make -C libr/xps EXTERNAL_PLUGINS=decai
./configure-plugins
make
```
For meson builds, make `libr/xps/p/meson.build` contain:
```meson
subdir('decai/r2plugin')
```
-2
View File
@@ -1,2 +0,0 @@
/Users/pancake/prg/radare2/libr/xps/p/decai/r2plugin/core/decai.r2.js.o: \
/Users/pancake/prg/radare2/libr/xps/p/decai/r2plugin/core/decai.r2.js.c
-3
View File
@@ -1,3 +0,0 @@
#ifdef R2_CORE_H
extern RCorePlugin r_core_plugin_decai;
#endif
-10
View File
@@ -1,10 +0,0 @@
DECAI_CORE_WD=$(LIBR)/xps/p/decai
DECAI_CORE_OBJ= \
$(DECAI_CORE_WD)/r2plugin/core/plugin.o \
$(DECAI_CORE_WD)/r2plugin/core/decai.r2.js.o
EXTERNAL_STATIC_OBJS+=$(DECAI_CORE_OBJ)
# decai.r2.js can be rebuilt from typescript with r2frida-compile (make -C src)
$(DECAI_CORE_WD)/r2plugin/core/decai.r2.js.c: $(DECAI_CORE_WD)/decai.r2.js
rax2 -C < $(DECAI_CORE_WD)/decai.r2.js | \
sed -e 's,^unsigned,const unsigned,' -e 's,buf,decai_qjs,g' > $@
-35
View File
@@ -1,35 +0,0 @@
/* decai - LGPL - Copyright 2026 - pancake */
#include <r_core.h>
// generated from ../decai.r2.js, see ../deps.mk
extern const unsigned char decai_qjs[];
extern const unsigned int decai_qjs_len;
static bool decai_init(RCorePluginSession *cps) {
r_core_script_embed (cps->core, "decai", "qjs", (const char *)decai_qjs, (int)decai_qjs_len);
return true;
}
static bool decai_call(RCorePluginSession *cps, const char *input) {
return false;
}
RCorePlugin r_core_plugin_decai = {
.meta = {
.name = "decai",
.desc = "AI decompiler (embedded decai.r2.js)",
.author = "pancake",
.license = "MIT",
},
.init = decai_init,
.call = decai_call,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_CORE,
.data = &r_core_plugin_decai,
.version = R2_VERSION,
};
#endif
-372
View File
@@ -1,372 +0,0 @@
/Users/pancake/prg/radare2/libr/xps/p/decai/r2plugin/core/plugin.o: \
/Users/pancake/prg/radare2/libr/xps/p/decai/r2plugin/core/plugin.c \
/Users/pancake/prg/radare2/libr/include/r_core.h \
/Users/pancake/prg/radare2/libr/include/r_main.h \
/Users/pancake/prg/radare2/libr/include/r_types.h \
/Users/pancake/prg/radare2/libr/include/r_types_base.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ctype.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_ctype.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_symbol_aliasing.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_posix_availability.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/ptrcheck.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_bounds.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/runetype.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/_types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_size_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_ct_rune_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_rune_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_wchar_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_wint_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/appleapiopts.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/types.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_int8_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_int16_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_int32_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_int64_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_int8_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_int16_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_int32_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_int64_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_intptr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_uintptr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/_endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/__endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/libkern/_OSByteOrder.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/libkern/arm/_OSByteOrder.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_char.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_short.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_u_int.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_caddr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_dev_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_blkcnt_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_blksize_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_gid_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_in_addr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_in_port_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_ino_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_ino64_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_key_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_mode_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_nlink_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_id_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_pid_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_off_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_uid_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_clock_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_ssize_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_time_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_useconds_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_suseconds_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_rsize_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_errno_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_def.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/Availability.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/AvailabilityVersions.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/AvailabilityInternal.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/AvailabilityInternalLegacy.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_setsize.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_set.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_clr.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_zero.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_isset.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fd_copy.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_attr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_cond_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_condattr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_mutex_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_mutexattr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_once_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_rwlock_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_rwlockattr_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_key_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fsblkcnt_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_fsfilcnt_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/limits.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/limits.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/limits.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/limits.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_limits.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/syslimits.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/stdint.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdint.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_uint8_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_uint16_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_uint32_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_uint64_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_intmax_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_uintmax_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/stdbool.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/math.h \
/Users/pancake/prg/radare2/libr/include/r_types_overflow.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_str_util.h \
/Users/pancake/prg/radare2/libr/include/r_userconf.h \
/Users/pancake/prg/radare2/libr/include/r_version.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/stddef.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stddef.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_header_macro.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_ptrdiff_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_size_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_rsize_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_wchar_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_null.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_max_align_t.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stddef_offsetof.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdlib.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_stdlib.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/wait.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/signal.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/signal.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/signal.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/_mcontext.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_mcontext.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach/machine/_structs.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach/arm/_structs.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_sigaltstack.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_ucontext.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_sigset_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/resource.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_timeval.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/alloca.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_null.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/malloc/_malloc.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/malloc/_malloc_type.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/malloc/_ptrcheck.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_abort.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/assert.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_assert.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_static_assert.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/inttypes.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/inttypes.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_inttypes.h \
/Users/pancake/prg/radare2/libr/include/r_types_null.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_stdio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_va_list.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/stdio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_printf.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_seek_set.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_ctermid.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_common.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/string.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_string.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_strings.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_strings.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/stdarg.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg_header_macro.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg___gnuc_va_list.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg_va_list.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg_va_arg.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg___va_copy.h \
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include/__stdarg_va_copy.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/fcntl.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/fcntl.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_o_sync.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_o_dsync.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_s_ifmt.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_timespec.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_filesec_t.h \
/Users/pancake/prg/radare2/libr/include/r_endian.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/stat.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/dirent.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/dirent.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/unistd.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/unistd.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_posix_vdisable.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/select.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_select.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_uuid_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/gethostuuid.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/time.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_timeval64.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/time.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_time.h \
/Users/pancake/prg/radare2/libr/include/r_getopt.h \
/Users/pancake/prg/radare2/libr/include/r_util.h \
/Users/pancake/prg/radare2/libr/include/r_regex.h \
/Users/pancake/prg/radare2/libr/include/r_list.h \
/Users/pancake/prg/radare2/libr/include/sdb/sdb.h \
/Users/pancake/prg/radare2/libr/include/sdb/asserts.h \
/Users/pancake/prg/radare2/libr/include/sdb/types.h \
/Users/pancake/prg/radare2/libr/include/sdb/config.h \
/Users/pancake/prg/radare2/libr/include/sdb/ht.h \
/Users/pancake/prg/radare2/libr/include/sdb/ht_pp.h \
/Users/pancake/prg/radare2/libr/include/sdb/ht_inc.h \
/Users/pancake/prg/radare2/libr/include/sdb/ls.h \
/Users/pancake/prg/radare2/libr/include/sdb/heap.h \
/Users/pancake/prg/radare2/libr/include/sdb/dict.h \
/Users/pancake/prg/radare2/libr/include/sdb/cdb.h \
/Users/pancake/prg/radare2/libr/include/sdb/cdb_make.h \
/Users/pancake/prg/radare2/libr/include/sdb/buffer.h \
/Users/pancake/prg/radare2/libr/include/sdb/version.h \
/Users/pancake/prg/radare2/libr/include/sdb/rangstr.h \
/Users/pancake/prg/radare2/libr/include/r_skiplist.h \
/Users/pancake/prg/radare2/libr/include/r_th.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_w32.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_sys.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/errno.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/errno.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/semaphore.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/semaphore.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread/sched.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread/pthread_impl.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread/qos.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/qos.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_mach_port_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/signal.h \
/Users/pancake/prg/radare2/libr/include/r_event.h \
/Users/pancake/prg/radare2/libr/include/sdb/ht_up.h \
/Users/pancake/prg/radare2/libr/include/r_vec.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_assert.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_log.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_arena.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_itv.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_signal.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_alloc.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_rbtree.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_trie.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_strs.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_xml.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_new_rbtree.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_intervaltree.h \
/Users/pancake/prg/radare2/libr/include/r_util/../r_types.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_big.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_base32.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_base36.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_base64.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_base91.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_buf.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_mem.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_ref.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_bits.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_bitmap.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_bitset.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_time.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_debruijn.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_type.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_file.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_hex.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_name.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_num.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_table.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_graph.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_panels.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_pool.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_diff.h \
/Users/pancake/prg/radare2/libr/include/r_cons.h \
/Users/pancake/prg/radare2/libr/include/r_util/pj.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_strbuf.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_json.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_sandbox.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_stack.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_str.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/wchar.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_wchar.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_mbstate_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/__wctype.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/___wctype.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types/_wctype_t.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_str_constpool.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/termios.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/termios.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/ttycom.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/ioccom.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/ttydefaults.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/ioctl.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/filio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/sockio.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/net/if.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/net/if_var.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_timeval32.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/net/net_kev.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/socket.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/constrained_ctypes.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/_param.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_param.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_sa_family_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_socklen_t.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_iovec_t.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_punycode.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_queue.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_range.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_spaces.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_strs_store.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_bloom.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_strpool.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_tree.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_uleb128.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_utf8.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_utf16.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_utf32.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_idpool.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_asn1.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_graph_drawable.h \
/Users/pancake/prg/radare2/libr/include/r_config.h \
/Users/pancake/prg/radare2/libr/include/r_util/bplist.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_x509.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_pkcs7.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_protobuf.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_token.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_axml.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_cfloat.h \
/Users/pancake/prg/radare2/libr/include/r_util/libc.h \
/Users/pancake/prg/radare2/libr/include/r_socket.h \
/Users/pancake/prg/radare2/libr/include/r_bind.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/netinet/in.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/netinet6/in6.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/un.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/poll.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/poll.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arpa/inet.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/netdb.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/netinet/tcp.h \
/Users/pancake/prg/radare2/libr/include/r_magic.h \
/Users/pancake/prg/radare2/libr/include/r_agraph.h \
/Users/pancake/prg/radare2/libr/include/r_io.h \
/Users/pancake/prg/radare2/libr/include/r_lib.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/dlfcn.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_w32dw.h \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/ptrace.h \
/Users/pancake/prg/radare2/libr/include/r_fs.h \
/Users/pancake/prg/radare2/libr/include/r_egg.h \
/Users/pancake/prg/radare2/libr/include/r_asm.h \
/Users/pancake/prg/radare2/libr/include/r_arch.h \
/Users/pancake/prg/radare2/libr/include/r_bin.h \
/Users/pancake/prg/radare2/libr/include/r_muta.h \
/Users/pancake/prg/radare2/libr/include/r_hash.h \
/Users/pancake/prg/radare2/libr/include/r_muta/r_sm4.h \
/Users/pancake/prg/radare2/libr/include/r_bin_dwarf.h \
/Users/pancake/prg/radare2/libr/include/r_reg.h \
/Users/pancake/prg/radare2/libr/include/r_anal/op.h \
/Users/pancake/prg/radare2/libr/include/r_anal/hint.h \
/Users/pancake/prg/radare2/libr/include/r_esil.h \
/Users/pancake/prg/radare2/libr/include/sdb/ht_uu.h \
/Users/pancake/prg/radare2/libr/include/r_anal.h \
/Users/pancake/prg/radare2/libr/include/r_util/r_print.h \
/Users/pancake/prg/radare2/libr/include/r_search.h \
/Users/pancake/prg/radare2/libr/include/r_syscall.h \
/Users/pancake/prg/radare2/libr/include/r_flag.h \
/Users/pancake/prg/radare2/libr/include/r_codemeta.h \
/Users/pancake/prg/radare2/libr/include/sdb/set.h \
/Users/pancake/prg/radare2/libr/include/r_lang.h \
/Users/pancake/prg/radare2/libr/include/r_cmd.h \
/Users/pancake/prg/radare2/libr/include/r_sign.h \
/Users/pancake/prg/radare2/libr/include/r_debug.h \
/Users/pancake/prg/radare2/libr/include/r_bp.h \
/Users/pancake/prg/radare2/libr/include/rvc.h \
/Users/pancake/prg/radare2/libr/include/r_core_priv.h \
/Users/pancake/prg/radare2/libr/include/r_core_task.h
-1
View File
@@ -1 +0,0 @@
include p/decai/r2plugin/core/deps.mk
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env python3
"""Convert a script file into a C buffer named decai_qjs (same output as `rax2 -C` + sed)."""
import sys
data = open(sys.argv[1], "rb").read()
with open(sys.argv[2], "w") as f:
f.write("const unsigned char decai_qjs[] = {\n")
for i in range(0, len(data), 16):
f.write(" %s,\n" % ", ".join("0x%02x" % b for b in data[i:i + 16]))
f.write("};\nconst unsigned int decai_qjs_len = %d;\n" % len(data))
-16
View File
@@ -1,16 +0,0 @@
# decai XPS integration for radare2.
# Included from libr/xps/meson.build when decai lives under libr/xps/p/decai/.
# Unlike native plugins, decai ships no native code: decai.r2.js is embedded
# as a buffer in libr_core and the tiny core plugin registers it with
# r_core_script_embed() so r2 runs it at startup like any plugins/*.r2.js file.
core_plugins += ['decai']
decai_py3 = import('python').find_installation()
r_core_additional_sources += files('core/plugin.c')
r_core_additional_sources += custom_target('decai_r2_js_c',
input: '../decai.r2.js',
output: 'decai.r2.js.c',
command: [decai_py3, files('js2c.py'), '@INPUT@', '@OUTPUT@'],
)
-1
View File
@@ -1 +0,0 @@
core.decai
-19
View File
@@ -1,19 +0,0 @@
PLUGIN_NAME=decai
R2F_C_FLAGS=-c -S
R2FRIDA_COMPILE?=r2pm -r r2frida-compile
all: build
build:
$(R2FRIDA_COMPILE) $(R2F_C_FLAGS) -o ../$(PLUGIN_NAME).r2.js main.ts
test: build
r2 -i ../$(PLUGIN_NAME).r2.js -q -c 'af;decai -d' /bin/ls
fmt:
deno fmt
clean:
rm -rf out node_modules ../$(PLUGIN_NAME).r2.js
.PHONY: all build test clean
-53
View File
@@ -1,53 +0,0 @@
import { API_KEYS_PATH, DECAI_CONFIG_DIR } from "./constants";
import { providerRegistry } from "./providers";
import { ApiKeyResult } from "./types";
import { ensurePath, fileExists, parseEnvLikeString } from "./utils";
function getProviderEnvMap(): Record<string, string> {
return Object.fromEntries(
Object.entries(providerRegistry)
.filter(([, v]) => v.authKey)
.map(([k, v]) => [k, v.authKey!]),
);
}
export function getApiKey(provider: string, envvar: string): ApiKeyResult {
const keyEnv = r2.cmd("'%" + envvar).trim();
if (!keyEnv.includes("=") && keyEnv !== "") {
return [keyEnv.trim(), null, "env"];
}
const providerLower = provider.toLowerCase();
const keysPath = API_KEYS_PATH;
if (fileExists(keysPath)) {
const keyFile = r2.cmd("'cat " + keysPath);
const kv = parseEnvLikeString(keyFile);
if (providerLower in kv) {
return [kv[providerLower], null, "txt"];
}
}
const keyPath = "~/.r2ai." + providerLower + "-key";
if (fileExists(keyPath)) {
const keyFile = r2.cmd("'cat " + keyPath);
return keyFile === ""
? [null, "Cannot read " + keyPath, "no"]
: [keyFile.trim(), null, "file"];
}
return [null, "Not available", "nope"];
}
export function editApiKeys(): void {
ensurePath(DECAI_CONFIG_DIR, API_KEYS_PATH);
r2.cmd("'ed " + API_KEYS_PATH);
}
export function listApiKeys(): void {
Object.entries(getProviderEnvMap()).forEach(([key, env]) => {
const status = getApiKey(key, env)[2];
console.log(status, "\t", key);
});
}
-568
View File
@@ -1,568 +0,0 @@
import { AutoReply } from "./types";
import { state } from "./state";
import { COMMAND, DEFAULT_PROMPT, HELP_TEXT, VERSION } from "./constants";
import {
b64,
filterResponse,
trimAnsi,
trimDown,
trimJson,
} from "./utils";
import { editApiKeys, listApiKeys } from "./apiKeys";
import { editRcConfig, evalConfig, listAllConfig } from "./config";
import { r2ai } from "./r2ai";
function withColorDisabled<T>(fn: () => T): T {
const origColor = r2.cmd("e scr.color");
r2.cmd("e scr.color=0");
try {
return fn();
} finally {
r2.cmd("e scr.color=" + origColor);
}
}
export function showHelp(): void {
let helpmsg = "";
const msg = (m: string) => (helpmsg += " " + COMMAND + " " + m + "\n");
helpmsg += "Usage: " + COMMAND + " (-h) ...\n";
helpmsg += "Version: " + VERSION + "\n";
msg("-a [query] - solve query with auto mode");
msg("-b [url] - set base URL (alias for decai -e baseurl)");
msg("-d [f1 ..] - decompile given functions");
msg("-dd [..] - same as above, but ignoring cache");
msg("-dD [query] - decompile current function with given extra query");
msg("-dr - decompile function and its called ones (recursive)");
msg("-e - display and change eval config vars");
msg("-E - edit and run decai.txt");
msg("-h - show this help");
msg("-H - help setting up r2ai");
msg("-i [f] [q] - include given file and query");
msg("-k - list API key status");
msg("-K - edit apikeys.txt");
msg("-m [model] - use -m? or -e model=? to list the available models");
msg("-n - suggest better function name");
msg("-p [provider] - same as decai -e api (will be provider)");
msg("-q [text] - query language model with given text");
msg("-Q [text] - query on top of the last output");
msg("-r [prompt] - change role prompt (same as: decai -e prompt)");
msg("-R - reset role prompt to default prompt");
msg("-s - function signature");
msg("-v - show local variables");
msg("-V - find vulnerabilities");
msg("-x[*] - eXplain current function (-x* for r2 script)");
r2.log(helpmsg.trim());
}
export function decompile(
args: string,
extraQuery: boolean,
useCache: boolean,
recursiveCalls: boolean,
): string | undefined {
if (useCache) {
const cachedAnnotation = r2.cmd("anos").trim();
if (cachedAnnotation.length > 0) {
return cachedAnnotation;
}
}
let context = "";
if (recursiveCalls) {
const at = r2.cmd("s");
context += "## Context functions:\n";
const funcs = r2.cmdAt("axff~^C[2]~$$", at);
for (const addr of funcs.split(/\n/g)) {
context += r2.cmd("pdc@" + addr);
}
r2.cmd("s " + at);
}
const appendQuery = extraQuery ? " " + args : "";
try {
const parsedArgs = args.slice(2).trim();
let text = "";
if (
state.contextFile !== "" &&
r2.cmd2("test -f " + state.contextFile).value === 0
) {
text += "## Context:\n[START]\n" +
r2.cmd("cat " + state.contextFile) +
"\n[END]\n";
}
const { body, count } = withColorDisabled(() => {
let body = "## Before:\n";
let count = 0;
for (const c of state.commands.split(",")) {
if (c.trim() === "") continue;
const oneliner = extraQuery || parsedArgs.trim().length === 0
? c
: c + "@@= " + parsedArgs;
const output = r2.cmd(oneliner);
if (output.length > 5) {
body += "Output of " + c + ":\n[START]\n" + output + "\n[END]\n";
count++;
}
}
body += "## After:\n";
return { body, count };
});
if (count === 0) {
console.error("Nothing to do.");
return;
}
let out = "";
if (state.decopipe.use) {
const origModel = state.model;
try {
const dpipe = state.decopipe[state.decopipe.default as string] as {
pipeline: Array<{ model?: string; query: string }>;
globalQuery: string;
};
let code = text + body;
for (const dp of dpipe.pipeline) {
if (dp.model) state.model = dp.model;
const query = dp.query + ". " + dpipe.globalQuery;
out = r2ai(query, code, true);
if (state.debug) {
console.log("QUERY\n", query, "\nINPUT\n", code, "\nOUTPUT\n", out);
}
code = out;
}
out = code;
} finally {
state.model = origModel;
}
} else {
const query = appendQuery;
text += body + context;
out = r2ai(query, text, false);
state.lastOutput = out;
}
if (useCache && out.length > 1) {
r2.call("ano=base64:" + b64(out));
}
if (out.startsWith("```")) {
out = out.replace(/```.*\n/, "").replace(/```$/, "");
}
return out.trim();
} catch (e) {
const err = e as Error;
console.error(err, err.stack);
return;
}
}
export function explainFunction(): string {
const hints = withColorDisabled(() =>
"[START]" +
state.commands.split(",").map((c) => r2.cmd(c)).join("\n") + "[END]"
);
const res = r2ai(
"Analyze function calls, references, comments and strings, loops and ignore registers and memory accesses. Explain the purpose of this function in a single short sentence. /no_think Do not introduce or argue the response, translation of the explanation in " +
state.humanLanguage,
hints,
true,
);
const lines = res.trim().split(/\n/g);
return lines[lines.length - 1].trim();
}
export function suggestSignature(): string {
const tmp = state.language;
const code = r2.cmd("afv;pdc");
state.language = "C";
let out = "'afs " +
r2ai(
"analyze the uses of the arguments and return value to infer the signature, identify which is the correct type for the return. Do NOT print the function body, ONLY output the function signature, like if it was going to be used in a C header",
code,
false,
);
const brace = out.indexOf("{");
if (brace !== -1) {
out = out.substring(0, brace);
}
state.language = tmp;
return out;
}
export function autoMode(
queryText: string,
mainHandler: (args: string) => boolean,
): void {
const replies: string[] = [];
while (true) {
let q = HELP_TEXT.auto;
if (replies.length > 0) {
q += "## Command Results\n\n";
for (const rep of replies) {
const rp = JSON.parse(rep);
q += "### " + rp.command + "\n\n```\n" + rp.response + "\n```\n";
}
}
q += "\n\n## User Prompt\n\n" + queryText;
if (state.debug) {
console.log("#### input\n", q, "\n#### /input");
}
console.log("Thinking...");
const out = r2ai("", q, true);
if (state.debug) {
console.log("#### output\n", out, "\n#### /output");
}
try {
const o: AutoReply = JSON.parse(
trimJson(trimDown(filterResponse(out))),
);
if (
o.action === "r2cmd" ||
o.action === "response" ||
o.action === o.command
) {
const ocmd = o.command || "";
if (o.reason) {
console.log("[r2cmd] Reasoning: " + o.reason);
if (state.tts) {
r2.syscmd("pkill say");
r2.syscmd(
"say -v Alex -r 250 '" + o.reason.replace(/'/g, "") + "' &",
);
}
}
console.log("[r2cmd] Action: " + o.description);
console.log("[r2cmd] Command: " + ocmd);
let cmd = ocmd;
if (!state.yolo) {
cmd = autoRepl(ocmd, mainHandler);
}
console.log("[r2cmd] Running: " + cmd);
const obj = r2.cmd2(cmd);
const logs = obj.logs
? obj.logs.map((x: { type: string; message: string }) =>
x.type + ": " + x.message
).join("\n")
: "";
const res = (obj.res + logs).trim();
console.log(res);
const cleanRes = trimAnsi(res);
if (state.debug) {
console.log("<r2output>\n", cleanRes, "\n<(r2output>");
}
replies.push(
JSON.stringify({
action: "response",
command: cmd,
description: o.description,
response: cleanRes,
}),
);
} else if (o.action === "reply") {
console.log("Done\n", o.response);
break;
} else {
console.log("Unknown response\n", JSON.stringify(out));
break;
}
} catch (e) {
const response = out.indexOf('response": "');
if (response !== -1) {
const res = out
.slice(response + 12)
.replace(/\\n/g, "\n")
.replace(/\\/g, "");
console.log(res);
} else {
console.log(out);
console.error(e);
}
break;
}
}
}
function autoRepl(
ocmd: string,
mainHandler: (args: string) => boolean,
): string {
while (true) {
const cmd = r2.cmd("'?ie Tweak command? ('?' for help)").trim();
if (cmd === "q!") {
console.error("Break!");
break;
}
if (cmd === "?") {
autoHelp();
continue;
} else if (cmd.startsWith(":")) {
console.log(r2.cmd(cmd.slice(1)));
continue;
} else if (cmd.startsWith("-e")) {
mainHandler(cmd);
continue;
} else if (cmd === "!") {
return "?e do NOT execute '" + ocmd + "' again, continue without it";
} else if (cmd.startsWith("!")) {
console.log(r2.syscmd(cmd.slice(1)));
continue;
} else if (cmd === "q") {
return "?e All data collected!. Do not call more commands, reply the solutions";
} else if (!cmd) {
return ocmd;
} else {
const comment = cmd.indexOf("#");
if (comment !== -1) {
const command = cmd.slice(0, comment).trim();
return command;
}
return cmd;
}
}
return ocmd;
}
function autoHelp(): void {
console.log(" '!' do not run this command");
console.log(" '!c' run system command");
console.log(" 'q' to quit auto and try to solve");
console.log(" 'q!' quit auto without solving");
console.log(" 'c # C' use given command with comment");
console.log(" ':c' run r2 command without feeding auto");
console.log(" '-e' set decai configuration variables");
}
function getFlagValue(args: string): string {
return args.slice(2).trim();
}
function currentFunctionExists(): boolean {
return r2.cmd("afi.").trim().length > 0;
}
const noFunctionMessage = "Cannot find function at current offset";
export function handleCommand(
args: string,
mainHandler: (args: string) => boolean,
): string | undefined {
if (args === "" || !args.startsWith("-")) {
showHelp();
return;
}
let output = "";
const flag = args[1];
const argValue = getFlagValue(args);
switch (flag) {
case "H":
console.log(HELP_TEXT.decai);
break;
case "a":
autoMode(argValue, mainHandler);
break;
case "m": {
if (argValue === "=") {
evalConfig("model=");
} else if (argValue) {
evalConfig("model=" + argValue);
} else {
evalConfig("model");
}
break;
}
case "n":
case "f": {
if (!currentFunctionExists()) {
output = noFunctionMessage;
break;
}
output = r2.cmd("axff~$[3]");
const considerations = r2
.cmd("fd.")
.trim()
.split(/\n/)
.filter((x: string) => !x.startsWith("secti"))
.join(",");
output = r2ai(
"give me a better name for this function. the output must be: 'afn NEWNAME'. do not include the function code, only the afn line. consider: " +
considerations,
output,
false,
).trim();
output += " @ " + r2.cmd("?v $FB").trim();
break;
}
case "v": {
if (!currentFunctionExists()) {
output = noFunctionMessage;
break;
}
output = r2.cmd("afv;pdc");
output = r2ai(
"guess a better name and type for each local variable and function argument taking using. output an r2 script using afvn and afvt commands",
output,
false,
);
break;
}
case "i": {
const parts = argValue.split(/\s+/).filter(Boolean);
if (parts.length >= 2) {
const file = parts[0];
const query = parts.slice(1).join(" ");
const fileData = r2.cmd("cat " + file);
console.log(r2ai(query, fileData, true));
} else {
console.log("Use: decai -i [file] [query ...]");
}
break;
}
case "p": {
if (argValue) {
evalConfig("api=" + argValue);
} else {
listApiKeys();
}
break;
}
case "r": {
if (argValue) {
state.prompt = argValue;
} else {
console.log(state.prompt);
}
break;
}
case "R":
state.prompt = DEFAULT_PROMPT;
break;
case "s":
if (!currentFunctionExists()) {
output = noFunctionMessage;
break;
}
output = suggestSignature();
break;
case "V":
output = r2ai(
"find vulnerabilities, dont show the code, only show the response, provide a sample exploit",
state.lastOutput,
false,
);
break;
case "K":
editApiKeys();
break;
case "E":
editRcConfig();
break;
case "k":
listApiKeys();
break;
case "b": {
if (argValue) {
evalConfig("baseurl=" + argValue);
} else {
console.log(state.baseurl);
}
break;
}
case "e": {
if (argValue) {
evalConfig(argValue);
} else {
listAllConfig();
}
break;
}
case "q":
try {
output = r2ai(argValue, null, true);
} catch (e) {
const err = e as Error;
console.error(err, err.stack);
}
break;
case "Q":
output = r2ai(argValue, state.lastOutput, false);
break;
case "x":
if (!currentFunctionExists()) {
output = noFunctionMessage;
break;
}
output = explainFunction();
if (args[2] === "*" || args[2] === "r") {
output = "'CC " + output;
}
break;
case "d":
if (args[2] === "r") {
output = decompile(args.slice(2), true, state.cache, true) || "";
} else if (args[2] === "d") {
output = decompile(args, false, false, false) || "";
} else if (args[2] === "D") {
output = decompile(args, true, false, false) || "";
} else {
output = decompile(args, false, state.cache, false) || "";
}
break;
default:
showHelp();
break;
}
return output || undefined;
}
-199
View File
@@ -1,199 +0,0 @@
import { ConfigHandler, ConfigHandlers } from "./types";
import { DECAI_CONFIG_DIR, DECAI_CONFIG_PATH } from "./constants";
import { defaultState, state } from "./state";
import { listModelsFor } from "./models";
import { listProviders } from "./providers";
import { formatHeaders, parseHeaders } from "./headers";
import { ensurePath, fileExists } from "./utils";
let rcConfigLoaded = false;
function parseBoolean(value: string): boolean {
return value === "true" || value === "1";
}
type StateKey = keyof typeof state;
function boolHandler(key: StateKey): ConfigHandler {
// deno-lint-ignore no-explicit-any
const s = state as any;
return {
get: () => s[key] as boolean,
set: (v: string) => { s[key] = parseBoolean(v); },
};
}
function stringHandler(key: StateKey): ConfigHandler {
// deno-lint-ignore no-explicit-any
const s = state as any;
return {
get: () => s[key] as string,
set: (v: string) => { s[key] = v; },
};
}
function normalizeApiType(value: string): "chat" | "generate" | null {
const apiType = value.trim();
if (apiType === "chat") {
return "chat";
}
if (apiType === "generate") {
return "generate";
}
return null;
}
export const configHandlers: ConfigHandlers = {
pipeline: {
get: () => state.pipeline,
set: (v: string) => {
state.pipeline = v;
try {
state.decopipe = JSON.parse(r2.cmd("cat " + v));
} catch (e) {
console.error(e);
}
},
},
model: {
get: () => state.model,
set: (v: string) => {
if (v === "?") {
listModelsFor(state.api);
} else {
state.model = v.trim();
}
},
},
deterministic: boolHandler("deterministic"),
files: boolHandler("useFiles"),
think: {
get: () => state.think || "false",
set: (v: string) => { state.think = v; },
},
apitype: {
get: () => state.apitype,
set: (v: string) => {
const apiType = normalizeApiType(v);
if (apiType) {
state.apitype = apiType;
} else {
console.error("Invalid apitype. Use chat or generate.");
}
},
},
debug: boolHandler("debug"),
http: {
get: () => state.http,
set: (v: string) => {
const backend = v.trim();
if (backend === "auto" || backend === "r2" || backend === "curl") {
state.http = backend;
} else {
console.error("Invalid http backend. Use auto, r2 or curl.");
}
},
},
timeout: {
get: () => state.timeout,
set: (v: string) => { state.timeout = Math.max(0, parseInt(v, 10) || 0); },
},
api: {
get: () => state.api,
set: (v: string) => {
if (v === "?") {
console.error(listProviders().join("\n"));
} else {
state.api = v;
}
},
},
lang: stringHandler("language"),
hlang: stringHandler("humanLanguage"),
cache: boolHandler("cache"),
cmds: stringHandler("commands"),
tts: boolHandler("tts"),
yolo: boolHandler("yolo"),
prompt: stringHandler("prompt"),
ctxfile: stringHandler("contextFile"),
baseurl: stringHandler("baseurl"),
headers: {
get: () => formatHeaders(state.extraHeaders),
set: (v: string) => { state.extraHeaders = parseHeaders(v); },
},
maxtokens: {
get: () => state.maxInputTokens,
set: (v: string) => { state.maxInputTokens = parseInt(v, 10) || -1; },
},
};
function resetRcConfigState(): void {
const keep = { host: state.host, port: state.port, lastOutput: state.lastOutput };
Object.assign(state, defaultState, keep);
state.decopipe = { ...defaultState.decopipe };
state.extraHeaders = [...defaultState.extraHeaders];
}
function normalizeRcLine(line: string): string | null {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) {
return null;
}
return trimmed.startsWith("decai -e ")
? trimmed.slice("decai -e ".length).trim()
: trimmed;
}
export function evalConfig(arg: string): void {
const eqIndex = arg.indexOf("=");
const k = eqIndex === -1 ? arg : arg.slice(0, eqIndex);
const v = eqIndex === -1 ? undefined : arg.slice(eqIndex + 1);
const handler = configHandlers[k];
if (!handler) {
console.error("Unknown config key");
return;
}
if (typeof v !== "undefined") {
handler.set(v);
} else {
console.log(handler.get());
}
}
export function listAllConfig(): void {
Object.entries(configHandlers).forEach(([key, handler]) => {
const value = handler.get();
console.log("decai -e " + key + "=" + value);
});
}
export function loadRcConfig(): void {
resetRcConfigState();
if (!fileExists(DECAI_CONFIG_PATH)) {
return;
}
const rcFile = r2.call("cat " + DECAI_CONFIG_PATH);
for (const line of rcFile.split(/\r?\n/)) {
const rcLine = normalizeRcLine(line);
if (rcLine && rcLine[0] != '#') {
evalConfig(rcLine);
}
}
}
export function ensureRcConfigLoaded(): void {
if (rcConfigLoaded) {
return;
}
loadRcConfig();
rcConfigLoaded = true;
}
export function editRcConfig(): void {
ensurePath(DECAI_CONFIG_DIR, DECAI_CONFIG_PATH);
r2.cmd("'ed " + DECAI_CONFIG_PATH);
loadRcConfig();
rcConfigLoaded = true;
}
-130
View File
@@ -1,130 +0,0 @@
export const VERSION = "1.5.4";
export const COMMAND = "decai";
export const DECAI_CONFIG_DIR = "~/.config/r2ai";
export const API_KEYS_PATH = DECAI_CONFIG_DIR + "/apikeys.txt";
export const DECAI_CONFIG_PATH = DECAI_CONFIG_DIR + "/decai.txt";
export const DEFAULT_PROMPT =
"Rewrite this pseudocode into concise and clean code. Output only the provided function. Do not add wrappers, helper examples, test code, or main-like functions. Replace goto with structured control flow, simplify as much as possible, infer types and use better names for variables and parameters, some strings may be appearing as comments, preserve only what is implied by the input, and remove dead code.";
export const HELP_TEXT = {
decai: `# Using Decai
Decai is the radare2 plugin for decompiling functions with the help of language models.
By default uses a local ollama server, but can you can pick any other service by using 'decai -e api=?'.
[0x00000000]> decai -e api=?
r2ai deepseek anthropic claude gemini groq hf lmstudio mistral ollama ollamacloud openapi openai openrouter vllm xai zen
## Using Ollama
* Visit https://ollama.com to install it.
* Download the model of choice: 'ollama run llama3.3'
* Configure decai to use the given model with: 'decai -e model=?'
These are the most recommended models for decompiling in local:
* hhao/qwen2.5-coder-tools:latest (18GB of ram)
* hhao/qwen2.5-coder-tools:32b (24GB of ram required)
## Common Options
* 'decai -e baseurl=<url>' override default host and port for API endpoint (e.g., 'http://localhost:11434')
* 'decai -e apitype=chat|generate' choose the Ollama API endpoint (default: chat)
* 'decai -e headers=Authorization: Bearer ...\\nUser-Agent: curl/8.7.1' add or override HTTP headers
* "export DECAI_HEADERS='Authorization: Bearer ...\\nUser-Agent: curl/8.7.1'" set extra headers from the environment
* 'decai -e http=auto|r2|curl' select the HTTP transport (default: auto, prefers r2.http)
* 'decai -e timeout=0' disable curl timeouts, or set a positive number of seconds
* 'decai -e deterministic=true' to remove randomness from decompilation responses
* 'decai -e lang=Python' to output the decompilation in Python instead of C
* 'decai -e hlang=Catalan' to add comments or explanations in that language (instead of English)
* 'decai -e cmds=pdd,pdg' use r2dec and r2ghidra instead of r2's pdc as input for decompiling
* 'decai -e prompt=..' default prompt must be fine for most models and binaries, feel free to tweak it
## API Keys
Remove services like OpenAI, Mistral, Anthropic, Grok, Gemini, .. require API keys to work.
See 'decai -k' to list the status of available APIkeys
Use 'decai -K' to edit apikeys.txt and 'decai -E' to edit decai.txt.
Decai will pick them from the environment or the config files in your home:
* echo KEY > ~/.r2ai.openai-key
* export OPENAI_API_KEY=...
* put one 'key=value' pair per line in ~/.config/r2ai/decai.txt
## Using the R2AI Server:
Install r2ai or r2ai-server with r2pm:
[0x0000000]> decai -e api=r2ai
[0x0000000]> r2pm -ci r2ai
Choose one of the recommended models (after r2pm -r r2ai):
* -m ibm-granite/granite-20b-code-instruct-8k-GGUF
* -m QuantFactory/granite-8b-code-instruct-4k-GGUF
* -m TheBloke/Mistral-7B-Instruct-v0.2-GGUF
Start the webserver:
$ r2pm -r r2ai-server -l r2ai -m granite-8...
`,
auto: `# Radare2 Auto Mode
Use function calling to execute radare2 commands in order to resolve the user request defined in the "User Prompt" section, analyze the responses attached in the "Command Results" section.
## Function Calling
Respond ONLY using plain JSON. Process user query and decide which function calls are necessary to solve the task.
1. Analyze the user request to determine if we need to run commands to extend the knowledge and context of the problem.
2. If function call is needed, construct the JSON like this:
- Fill the "action" key with the "r2cmd" value.
- Specify the "command" as a string.
- Optionally, provide a "reason" and "description"
3. If the answer can be provided and no more function calls are required:
- Use the key "action": "reply".
- Include "response" with the direct answer to the user query.
Return the result as a JSON object.
### Sample Function Calling Communication
Command Results: already performed actions with their responses
User Prompt: "Count how many functions we have here."
Response:
{
"action": "r2cmd",
"command": "aflc",
"description": "Count functions"
"reason": "Evaluate if the program is analyzed before running aaa"
}
## Rules
Use radare2 to resolve user requests.
* Explain each step in the "reason" field of the JSON.
* Follow the initial analysis instructions.
* Output only valid JSON as specified.
* Decompile and inspect functions, starting from main.
* Run only the needed commands to gather info.
* Use "@ (address|symbol)" to seek temporarily.
* Output should be a verbose markdown report.
* Use "sym." or "fcn." prefixes if "pdc" is empty.
* If a seek fails, use "f~name" to find the symbol's address.
### Initial Analysis
1. Run "aflc" to count the number of functions
2. If the output of "aflc" is "0" run "aaa" once, then "aflc" again
3. Run only one command at a time (do not use ";")
### Special cases
* On Swift binaries run...
`,
};
-91
View File
@@ -1,91 +0,0 @@
import { state } from "./state";
const HEADER_ENV_VARS = ["DECAI_HEADERS", "R2AI_HEADERS"];
interface ParsedHeader {
name: string;
value: string;
}
function readEnvVar(name: string): string {
const value = r2.cmd("'%" + name).trim();
return value !== "" && !value.includes("=") ? value : "";
}
function normalizeHeaderName(name: string): string {
return name.trim().toLowerCase();
}
function parseHeaderLine(line: string): ParsedHeader | null {
const colon = line.indexOf(":");
const equals = line.indexOf("=");
const sep = colon !== -1 && (equals === -1 || colon < equals)
? colon
: equals;
if (sep === -1) {
return null;
}
const name = line.slice(0, sep).trim();
if (name === "") {
return null;
}
return {
name,
value: line.slice(sep + 1).trim(),
};
}
function formatHeader(header: ParsedHeader): string {
return header.value === ""
? `${header.name}:`
: `${header.name}: ${header.value}`;
}
function collectHeaders(
headerLines: string[],
into: Map<string, string>,
): void {
for (const rawLine of headerLines) {
const header = parseHeaderLine(rawLine.trim());
if (header) {
into.set(normalizeHeaderName(header.name), formatHeader(header));
}
}
}
export function parseHeaders(value: string): string[] {
const headers = new Map<string, string>();
const lines = value.replace(/\\n/g, "\n").split(/\r?\n/g)
.filter((l) => { const t = l.trim(); return t && !t.startsWith("#"); });
collectHeaders(lines, headers);
return Array.from(headers.values());
}
export function formatHeaders(headers: string[]): string {
return headers.join("\\n");
}
export function mergeHeaders(...groups: string[][]): string[] {
const merged = new Map<string, string>();
for (const group of groups) {
collectHeaders(group, merged);
}
return Array.from(merged.values());
}
function readConfiguredEnvHeaders(): string[] {
for (const name of HEADER_ENV_VARS) {
const value = readEnvVar(name);
if (value) {
return parseHeaders(value);
}
}
return [];
}
export function getConfiguredHeaders(): string[] {
return mergeHeaders(readConfiguredEnvHeaders(), state.extraHeaders);
}
-108
View File
@@ -1,108 +0,0 @@
import { HttpResponse } from "./types";
import { state } from "./state";
import { mergeHeaders } from "./headers";
import { debugLog } from "./utils";
interface HttpRequestOptions {
method: "GET" | "POST";
url: string;
headers: string[];
payload?: string;
}
function shellEscape(arg: string): string {
return `'${arg.replace(/'/g, `'"'"'`)}'`;
}
function executeRequest(options: HttpRequestOptions): string {
const { method, url, headers, payload } = options;
const requestHeaders = mergeHeaders(
["Content-Type: application/json"],
headers,
);
if (state.http !== "curl") {
if (r2.http) {
return r2.http(method, url, requestHeaders.join("\n"), payload ?? "").body;
}
if (state.http === "r2") {
throw new Error("r2.http is not available in this runtime");
}
}
const cmdParts = ["curl", "-s"];
if (state.timeout > 0) {
cmdParts.push("--max-time", String(state.timeout));
}
requestHeaders.forEach((h) => cmdParts.push("-H", shellEscape(h)));
if (method === "POST") {
if (!payload) throw new Error("Payload required for POST requests");
const tmpfile = r2.fdump(payload);
cmdParts.push("--data-binary", "@" + shellEscape(tmpfile), shellEscape(url));
const cmd = cmdParts.join(" ") + "; rm " + shellEscape(tmpfile);
debugLog(cmd);
return r2.syscmds(cmd);
} else {
cmdParts.push(shellEscape(url));
const cmd = cmdParts.join(" ");
debugLog(cmd);
return r2.syscmds(cmd);
}
}
function parseNdjson(output: string): HttpResponse | null {
const lines = output.split("\n").filter((l) => l.trim() !== "");
if (lines.length <= 1) return null;
let content = "";
let lastObj: Record<string, unknown> | null = null;
for (const line of lines) {
try {
const obj = JSON.parse(line);
if (obj.error) return obj as HttpResponse;
if (obj.message?.content !== undefined) {
content += obj.message.content;
}
lastObj = obj;
} catch {
return null;
}
}
if (lastObj) {
lastObj.message = { role: "assistant", content };
return lastObj as HttpResponse;
}
return null;
}
export function httpRequest(options: HttpRequestOptions): HttpResponse {
try {
const output = executeRequest(options).trim();
if (output === "") {
return { error: "empty response" };
}
try {
return JSON.parse(output) as HttpResponse;
} catch {
const ndjson = parseNdjson(output);
if (ndjson) return ndjson;
return { error: output, rawOutput: output };
}
} catch (e) {
const err = e as Error;
return { error: err.message };
}
}
export function httpGet(url: string, headers: string[]): HttpResponse {
return httpRequest({ method: "GET", url, headers });
}
export function httpPost(
url: string,
headers: string[],
payload: string,
): HttpResponse {
return httpRequest({ method: "POST", url, headers, payload });
}
-10
View File
@@ -1,10 +0,0 @@
### 3. HTTP Request Patterns
**Location**: `http.ts`, used throughout providers and models
**Problems**:
- Two different curl methods (`curlArgs` vs `curlFile`) with similar but
separate logic
- Error handling in HTTP layer vs. application layer
- No centralized request/response abstraction
-34
View File
@@ -1,34 +0,0 @@
import { COMMAND } from "./constants";
import { handleCommand } from "./commands";
import { ensureRcConfigLoaded } from "./config";
function main(args: string): boolean {
ensureRcConfigLoaded();
const output = handleCommand(args, main);
if (output) {
r2.log(output);
}
return true;
}
function installPlugin(): void {
r2.unload("core", COMMAND);
r2.plugin("core", function () {
function coreCall(cmd: string): boolean {
if (cmd.startsWith(COMMAND)) {
const args = cmd.slice(COMMAND.length).trim();
return main(args);
}
return false;
}
return {
name: COMMAND,
license: "MIT",
desc: "r2 decompiler based on r2ai",
call: coreCall,
};
});
}
installPlugin();
-34
View File
@@ -1,34 +0,0 @@
import { getProvider, listModels } from "./providers";
export function listModelsFor(api: string): void {
const providerConfig = getProvider(api);
if (!providerConfig) {
console.error(`Unknown provider: ${api}`);
return;
}
try {
const models = listModels(api);
if (models) {
console.log(models);
}
if (providerConfig.hardcodedModels) {
providerConfig.hardcodedModels.forEach((model) => console.log(model));
}
if (api === "mistral") {
console.log("ministral-8b-latest");
}
if (!models && !providerConfig.hardcodedModels) {
console.log(providerConfig.defaultModel);
}
} catch (e) {
const err = e as Error;
console.error(`Error listing models for ${api}:`, err.message);
console.log(providerConfig.defaultModel);
}
}
-541
View File
@@ -1,541 +0,0 @@
import {
AnthropicPayload,
ApiKeyResult,
ApiStyle,
AuthStyle,
GeminiPayload,
HttpResponse,
ModelDataEntry,
OllamaModelEntry,
OllamaPayload,
ProviderConfig,
ProviderRegistry,
} from "./types";
import { state } from "./state";
import { filterResponse, joinUrl, padRight } from "./utils";
import { getApiKey } from "./apiKeys";
import { getConfiguredHeaders, mergeHeaders } from "./headers";
import { httpGet, httpPost } from "./http";
interface ProviderRuntime {
buildPayload: (model: string, query: string) => object;
parseResponse: (response: HttpResponse) => string;
buildUrl: (baseUrl: string, model: string, apiKey?: string) => string;
requiresUrlApiKey?: boolean;
}
function getApiKeyName(authKey: string): string {
return authKey.split("_")[0].toLowerCase();
}
function readProviderKey(provider: ProviderConfig): ApiKeyResult | undefined {
if (!provider.authKey) {
return undefined;
}
const keyNames = Array.from(
new Set(
[provider.keyName, getApiKeyName(provider.authKey)].filter(Boolean),
),
) as string[];
let fallback: ApiKeyResult | undefined;
for (const keyName of keyNames) {
const result = getApiKey(keyName, provider.authKey);
if (result[0]) {
return result;
}
if (!fallback && result[2] !== "nope") {
fallback = result;
}
}
return fallback ||
getApiKey(getApiKeyName(provider.authKey), provider.authKey);
}
function getErrorMessage(error: HttpResponse["error"]): string | undefined {
if (!error) {
return undefined;
}
if (typeof error === "string") {
return error;
}
return error.message || JSON.stringify(error);
}
function getProviderBaseUrl(provider: ProviderConfig): string {
return state.baseurl || provider.defaultBaseUrl;
}
function getProviderHeaders(
providerHeaders: string[],
extraHeaders: string[] = getConfiguredHeaders(),
): string[] {
return mergeHeaders(providerHeaders, extraHeaders);
}
function buildBearerHeaders(apiKey: string | null): string[] {
return apiKey ? ["Authorization: Bearer " + apiKey] : [];
}
function buildAnthropicHeaders(apiKey: string | null): string[] {
const headers = ["anthropic-version: 2023-06-01"];
return apiKey ? mergeHeaders(headers, ["x-api-key: " + apiKey]) : headers;
}
function buildAuthHeaders(
provider: ProviderConfig,
apiKey: string | null,
): string[] {
const authStyle: AuthStyle = provider.authStyle || "none";
switch (authStyle) {
case "bearer":
return buildBearerHeaders(apiKey);
case "anthropic":
return buildAnthropicHeaders(apiKey);
case "none":
default:
return [];
}
}
function listDataModels(
url: string,
headers: string[],
mapper: (model: ModelDataEntry) => string,
): string {
const response = httpGet(url, headers);
const error = getErrorMessage(response.error);
if (error) {
console.error(error);
return "error invalid response";
}
return response.data?.map(mapper).join("\n") || "";
}
function uniqueBy<T>(items: T[], getKey: (item: T) => string): T[] {
const seen = new Set<string>();
return items.filter((item) => {
const key = getKey(item);
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
function getProviderRequest(provider: ProviderConfig): {
baseUrl: string;
headers: string[];
} {
const apiKey = readProviderKey(provider)?.[0] || null;
return {
baseUrl: getProviderBaseUrl(provider),
headers: getProviderHeaders(buildAuthHeaders(provider, apiKey)),
};
}
function listV1Models(provider: ProviderConfig): string {
const { baseUrl, headers } = getProviderRequest(provider);
const url = joinUrl(baseUrl, "v1/models");
return listDataModels(url, headers, (model) => model.id);
}
function listOllamaModels(provider: ProviderConfig): string {
const { baseUrl, headers } = getProviderRequest(provider);
const response = httpGet(joinUrl(baseUrl, "api/tags"), headers);
const error = getErrorMessage(response.error);
if (error) {
console.error(error);
return "error invalid response";
}
return response.models?.map((model: OllamaModelEntry) => model.name).join(
"\n",
) || "";
}
function listMistralModels(provider: ProviderConfig): string {
const { baseUrl, headers } = getProviderRequest(provider);
const response = httpGet(joinUrl(baseUrl, "v1/models"), headers);
if (response.data) {
return uniqueBy(response.data, (model) => model.name || model.id)
.map((model) =>
[
padRight(model.name || model.id, 30),
padRight("" + (model.max_context_length || ""), 10),
model.description || "",
].join(" ")
)
.join("\n");
}
return "";
}
const providerRuntimes: Record<ApiStyle, ProviderRuntime> = {
openai: {
buildPayload: (model, query) => ({
stream: false,
model,
messages: [{ role: "user", content: query }],
}),
parseResponse: (response) => {
if (response.error) {
throw new Error(getErrorMessage(response.error) || "Unknown error");
}
if (response.choices && response.choices[0]?.message?.content) {
return filterResponse(response.choices[0].message.content);
}
throw new Error("Invalid response format");
},
buildUrl: (baseUrl) => joinUrl(baseUrl, "v1/chat/completions"),
},
anthropic: {
buildPayload: (model, query) => {
const payload: AnthropicPayload = {
model,
max_tokens: 5128,
messages: [{ role: "user", content: query }],
};
if (isThinkEnabled()) {
payload.thinking = { type: "enabled", budget_tokens: 4096 };
payload.max_tokens = 16000;
}
if (state.deterministic && !isThinkEnabled()) {
Object.assign(payload, { temperature: 0, top_p: 0, top_k: 1 });
}
return payload;
},
parseResponse: (response) => {
if (response.content && Array.isArray(response.content)) {
const parts: string[] = [];
for (const block of response.content as Array<Record<string, unknown>>) {
if (block.text) {
parts.push(block.text as string);
}
}
if (parts.length > 0) {
return filterResponse(parts.join("\n"));
}
}
if (response.error) {
throw new Error(getErrorMessage(response.error) || "Unknown error");
}
throw new Error("Invalid response format");
},
buildUrl: (baseUrl) => joinUrl(baseUrl, "v1/messages"),
},
ollama: {
buildPayload: (model, query) => {
const payload: OllamaPayload = {
stream: false,
model,
};
if (state.apitype === "generate") {
payload.prompt = query;
} else {
payload.messages = [{ role: "user", content: query }];
}
if (isThinkEnabled()) {
if (state.think === "true" || state.think === "1") {
payload.think = true;
} else {
// Pass reasoning levels like "low", "medium", "high" as-is
payload.think = state.think;
}
} else {
// Disable thinking by default — models like glm-5 enable it
// implicitly, generating thousands of reasoning tokens
payload.think = false;
}
if (state.deterministic) {
payload.options = {
repeat_last_n: 0,
top_p: 1.0,
top_k: 1.0,
temperature: 0.0,
repeat_penalty: 1.0,
seed: 123,
};
}
return payload;
},
parseResponse: (response) => {
if (response.error) {
throw new Error(getErrorMessage(response.error));
}
if (typeof response.response === "string") {
return filterResponse(response.response);
}
if (response.message?.content) {
return filterResponse(response.message.content);
}
throw new Error(JSON.stringify(response));
},
buildUrl: (baseUrl) => joinUrl(baseUrl, "api/" + state.apitype),
},
gemini: {
buildPayload: (_model, query) => {
const payload: GeminiPayload = {
contents: [{ parts: [{ text: query }] }],
};
const genConfig: Record<string, unknown> = {};
if (state.deterministic) {
Object.assign(genConfig, { temperature: 0.0, topP: 1.0, topK: 1 });
}
if (state.think !== "") {
if (isThinkDisabled()) {
genConfig.thinkingConfig = { thinkingBudget: 0 };
} else {
genConfig.thinkingConfig = { thinkingBudget: 8192 };
}
}
if (Object.keys(genConfig).length > 0) {
payload.generationConfig = genConfig;
}
return payload;
},
parseResponse: (response) => {
if (response.candidates && response.candidates[0]?.content?.parts) {
const parts = response.candidates[0].content.parts as Array<Record<string, unknown>>;
const textParts = parts
.filter((p) => !p.thought && p.text)
.map((p) => p.text as string);
if (textParts.length > 0) {
return filterResponse(textParts.join("\n"));
}
}
if (response.error) {
throw new Error(getErrorMessage(response.error));
}
console.log(JSON.stringify(response));
throw new Error("Invalid response format");
},
buildUrl: (baseUrl, model, apiKey) =>
joinUrl(
baseUrl,
`v1beta/models/${model}:generateContent?key=${apiKey}`,
),
requiresUrlApiKey: true,
},
};
export const providerRegistry: ProviderRegistry = {
anthropic: {
defaultModel: "claude-sonnet-5-5",
defaultBaseUrl: "https://api.anthropic.com",
authKey: "ANTHROPIC_API_KEY",
keyName: "anthropic",
authStyle: "anthropic",
apiStyle: "anthropic",
},
claude: {
defaultModel: "claude-sonnet-5-5",
defaultBaseUrl: "https://api.anthropic.com",
authKey: "ANTHROPIC_API_KEY",
keyName: "claude",
authStyle: "anthropic",
apiStyle: "anthropic",
},
openai: {
defaultModel: "gpt-4o-mini",
defaultBaseUrl: "https://api.openai.com",
authKey: "OPENAI_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
},
ollama: {
defaultModel: "qwen2.5-coder:latest",
defaultBaseUrl: "http://localhost:11434",
authStyle: "none",
apiStyle: "ollama",
},
ollamacloud: {
defaultModel: "gpt-oss:120b",
defaultBaseUrl: "https://ollama.com",
authKey: "OLLAMA_API_KEY",
keyName: "ollamacloud",
authStyle: "bearer",
apiStyle: "ollama",
},
zen: {
defaultModel: "big-pickle",
defaultBaseUrl: "https://opencode.ai/zen",
authKey: "OPENCODE_API_KEY",
keyName: "zen",
authStyle: "bearer",
apiStyle: "openai",
hardcodedModels: ["big-pickle", "glm-5", "kimi-k2.5"],
},
gemini: {
defaultModel: "gemini-2.5-flash",
defaultBaseUrl: "https://generativelanguage.googleapis.com",
authKey: "GEMINI_API_KEY",
authStyle: "none",
apiStyle: "gemini",
hardcodedModels: [
"gemini-2.0-flash",
"gemini-2.0-flash-lite",
"gemini-2.5-pro",
"gemini-2.5-flash",
"gemini-2.5-flash-lite",
],
},
mistral: {
defaultModel: "codestral-latest",
defaultBaseUrl: "https://api.mistral.ai",
authKey: "MISTRAL_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
},
xai: {
defaultModel: "grok-beta",
defaultBaseUrl: "https://api.x.ai",
authKey: "XAI_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
hardcodedModels: ["grok-2", "grok-beta"],
},
lmstudio: {
defaultModel: "local-model",
defaultBaseUrl: "http://127.0.0.1:1234",
authStyle: "none",
apiStyle: "openai",
},
deepseek: {
defaultModel: "deepseek-coder",
defaultBaseUrl: "https://api.deepseek.com",
authKey: "DEEPSEEK_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
hardcodedModels: ["deepseek-coder", "deepseek-chat"],
},
openrouter: {
defaultModel: "openai/gpt-4o-mini",
defaultBaseUrl: "https://openrouter.ai/api",
authKey: "OPENROUTER_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
},
groq: {
defaultModel: "llama-3.3-70b-versatile",
defaultBaseUrl: "https://api.groq.com/openai",
authKey: "GROQ_API_KEY",
authStyle: "bearer",
apiStyle: "openai",
},
};
export function getProvider(api: string): ProviderConfig | undefined {
return providerRegistry[api];
}
export function listProviders(): string[] {
return Object.keys(providerRegistry);
}
export function listModels(providerName: string): string {
const provider = getProvider(providerName);
if (!provider) {
throw new Error(`Unknown provider: ${providerName}`);
}
if (providerName === "mistral") {
return listMistralModels(provider);
}
switch (provider.apiStyle) {
case "openai":
case "anthropic":
return listV1Models(provider);
case "ollama":
return listOllamaModels(provider);
case "gemini":
return "";
default:
return "";
}
}
function isThinkDisabled(): boolean {
return state.think === "false" || state.think === "0";
}
function isThinkEnabled(): boolean {
return state.think !== "" && !isThinkDisabled();
}
function buildQuery(msg: string, hideprompt: boolean, apiStyle: ApiStyle): string {
let query = msg;
// Only add prompt-based thinking hints for APIs without native think support
if (state.think !== "" && apiStyle === "openai") {
if (isThinkDisabled()) {
query +=
' Answers directly and concisely, without showing any thinking steps or internal reasoning. Never include phrases like "Let me think".';
query += " /no_think";
} else {
query =
"Think step by step and explain the reasoning process, When answering, first output your reasoning inside <think> and </think> tags, then give the final answer." +
query;
}
}
return hideprompt ? query : state.prompt + languagePrompt() + query;
}
function languagePrompt(): string {
return "\n.Translate the code into " + state.language +
" programming language\n";
}
function callRuntime(
provider: ProviderConfig,
runtime: ProviderRuntime,
msg: string,
hideprompt: boolean,
): string {
const model = state.model || provider.defaultModel;
const query = buildQuery(msg, hideprompt, provider.apiStyle);
const apiKey = readProviderKey(provider);
if (runtime.requiresUrlApiKey && apiKey?.[1] && provider.authKey) {
return `Cannot read ~/.r2ai.${getApiKeyName(provider.authKey)}-key`;
}
const payload = runtime.buildPayload(model, query);
const authHeaders = buildAuthHeaders(provider, apiKey?.[0] || null);
if (provider.apiStyle === "ollama") {
authHeaders.push("Accept: application/x-ndjson");
}
const headers = getProviderHeaders(authHeaders);
const url = runtime.buildUrl(
getProviderBaseUrl(provider),
model,
apiKey?.[0] || undefined,
);
try {
return runtime.parseResponse(
httpPost(url, headers, JSON.stringify(payload)),
);
} catch (error) {
return "ERROR: " + (error as Error).message;
}
}
export function callProvider(msg: string, hideprompt: boolean): string {
const provider = getProvider(state.api);
if (!provider) {
return `Unknown value for 'decai -e api'. Available: ${
listProviders().join(", ")
}`;
}
return callRuntime(
provider,
providerRuntimes[provider.apiStyle],
msg,
hideprompt,
);
}
-41
View File
@@ -1,41 +0,0 @@
import { state } from "./state";
import { fileDump, joinUrl, tmpdir } from "./utils";
import { callProvider } from "./providers";
import { httpGet } from "./http";
export function r2ai(
queryText: string,
fileData: string | null,
hideprompt: boolean = false,
): string {
const cleanFileData = (fileData || "").replace(/`/g, "");
const cleanQuery = queryText.replace(/'/g, "");
// Handle r2ai server mode
if (state.api === "r2" || state.api === "r2ai") {
const fileName = tmpdir(".pdc.txt");
fileDump(fileName, cleanFileData);
const q = cleanQuery.startsWith("-")
? cleanQuery
: ["-i", fileName, cleanQuery].join(" ");
const baseUrl = state.baseurl || state.host + ":" + state.port;
const url = joinUrl(baseUrl, "cmd/" + encodeURIComponent(q));
const response = httpGet(url, []);
if (response.error) {
return `Error: ${response.error}`;
}
return response.result || JSON.stringify(response) ||
"Cannot curl, use r2ai-server or r2ai -w";
}
if (cleanQuery.startsWith("-")) return "";
let q = cleanQuery + ":\n" + cleanFileData;
if (state.maxInputTokens > 0 && q.length > state.maxInputTokens) {
q = q.slice(0, state.maxInputTokens);
}
return callProvider(q, hideprompt);
}
-290
View File
@@ -1,290 +0,0 @@
export type R2Address = number | string | unknown;
export interface R2HttpResponse {
status: number;
body: string;
}
export type R2HttpRequest = (
method: "GET" | "POST",
url: string,
headers: string,
data?: string,
) => R2HttpResponse;
export interface R2LogEntry {
type: string;
message: string;
}
export interface R2CommandResult {
res?: string;
value?: number;
logs?: R2LogEntry[];
[key: string]: unknown;
}
export interface R2Plugin {
name: string;
license: string;
desc: string;
call: (command: string) => boolean;
}
export type R2PluginFactory = () => R2Plugin;
export class R2PipeAdapter {
r2p: R2Pipe;
http?: R2HttpRequest;
constructor(r2p: R2Pipe) {
this.r2p = r2p;
this.http = r2p.http?.bind(r2p);
}
/**
* Run a command in the associated instance of radare2 and return the output as a string
*
* @param {string} command to be executed inside radare2.
* @returns {string} The output of the command execution
*/
cmd(command: string): string {
return this.r2p.cmd(command);
}
cmd2(command: string): R2CommandResult {
const output = this.r2p.cmd(command);
return typeof output === "string" ? { res: output } : output;
}
cmdAt(
command: string,
address: R2Address,
): string {
return this.r2p.cmdAt(command, address);
}
cmdj(cmd: string): unknown {
return this.r2p.cmdj(cmd);
}
call(command: string): string {
return this.r2p.call(command);
}
callj(cmd: string): unknown {
return this.r2p.cmdj(cmd);
}
callAt(
command: string,
address: R2Address,
): string {
return this.r2p.cmdAt(command, address);
}
syscmd(command: string): string {
return this.r2p.syscmd(command);
}
syscmds(command: string): string {
return this.r2p.syscmds(command);
}
fdump(data: string): string {
return this.r2p.fdump(data);
}
log(msg: string): void {
return this.r2p.log(msg);
}
plugin(type: string, maker: R2PluginFactory): boolean {
return this.r2p.plugin(type, maker);
}
unload(type: string, name: string): boolean {
return this.r2p.unload(type, name);
}
}
export function newR2PipeSync(r2p: R2Pipe): R2PipeSync {
return new R2PipeAdapter(r2p) as R2PipeSync;
}
/**
* Generic interface to interact with radare2, abstracts the access to the associated
* instance of the tool, which could be native via rlang or remote via pipes or tcp/http.
*
* @typedef R2Pipe
*/
export interface R2Pipe {
/**
* Run a command in the associated instance of radare2 and return the output as a string
*
* @param {string} command to be executed inside radare2.
* @returns {string} The output of the command execution
*/
cmd(cmd: string): string;
/**
* Run a radare2 command in a different address. Same as `.cmd(x + '@ ' + a)`
*
* @param {string} command to be executed inside radare2.
* @param {number|string|NativePointer} command to be executed inside radare2.
* @returns {string} The output of the command execution
*/
cmd2(cmd: string): R2CommandResult;
cmdAt(cmd: string, address: R2Address): string;
/**
* Run a radare2 command expecting the output to be JSON
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the output of the command
*/
cmdj(cmd: string): unknown;
/**
* Call a radare2 command. This is similar to `R2Pipe.cmd`, but skips all the command parsing rules,
* which is safer and faster but you cannot use any special modifier like `@`, `~`, ...
*
* See R2Pipe.callAt() to call a command on a different address
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the output of the command
*/
call(cmd: string): string;
/**
* Call a radare2 command in a different address
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @param {NativePointer|string|number} where to seek to execute this command (previous offset is restored after executing it)
* @returns {string} the string containing the output of the command
*/
callAt(cmd: string, address: R2Address): string;
syscmd(cmd: string): string;
syscmds(cmd: string): string;
fdump(data: string): string;
http?: R2HttpRequest;
/**
* Same as cmdj but using .call which avoids command injection problems
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the command output
*/
callj(cmd: string): unknown;
/**
* Log a string to the associated console. This is used internally by `console.log` in some implementations.
*
* @param {string} text to be displayed
*/
log(msg: string): void;
/**
* Instantiate a new radare2 plugin with the given type and constructor method.
*
* @param {string} type of plugin ("core", "io", "arch", ...)
* @param {string} function that returns the plugin definition
* @returns {boolean} true if successful
*/
plugin(type: string, maker: R2PluginFactory): boolean;
/**
* Unload the plugin associated with a `type` and a `name`.
*
* @param {string} type of plugin ("core", "io", "arch", ...)
* @param {string} name of the plugin
* @returns {boolean} true if successful
*/
unload(type: string, name: string): boolean;
}
/**
* Generic interface to interact with radare2, abstracts the access to the associated
* instance of the tool, which could be native via rlang or remote via pipes or tcp/http.
*
* @typedef R2PipeSync
*/
export interface R2PipeSync {
/**
* Run a command in the associated instance of radare2
*
* @param {string} command to be executed inside radare2.
* @returns {string} The output of the command execution
*/
cmd(cmd: string): string;
/**
* Run a radare2 command in a different address. Same as `.cmd(x + '@ ' + a)`
*
* @param {string} command to be executed inside radare2.
* @param {number|string|NativePointer} command to be executed inside radare2.
* @returns {string} The output of the command execution
*/
cmd2(cmd: string): R2CommandResult;
cmdAt(cmd: string, address: R2Address): string;
/**
* Run a radare2 command expecting the output to be JSON
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the output of the command
*/
cmdj(cmd: string): unknown;
/**
* Call a radare2 command. This is similar to `R2Pipe.cmd`, but skips all the command parsing rules,
* which is safer and faster but you cannot use any special modifier like `@`, `~`, ...
*
* See R2Pipe.callAt() to call a command on a different address
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the output of the command
*/
call(cmd: string): string;
/**
* Call a radare2 command in a different address
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @param {NativePointer|string|number} where to seek to execute this command (previous offset is restored after executing it)
* @returns {string} the string containing the output of the command
*/
callAt(cmd: string, address: R2Address): string;
syscmd(cmd: string): string;
syscmds(cmd: string): string;
fdump(data: string): string;
http?: R2HttpRequest;
/**
* Same as cmdj but using .call which avoids command injection problems
*
* @param {string} command to be executed inside radare2. The given command should end with `j`
* @returns {object} the JSON decoded object from the command output
*/
callj(cmd: string): unknown;
/**
* Log a string to the associated console. This is used internally by `console.log` in some implementations.
*
* @param {string} text to be displayed
*/
log(msg: string): void;
/**
* Instantiate a new radare2 plugin with the given type and constructor method.
*
* @param {string} type of plugin ("core", "io", "arch", ...)
* @param {string} function that returns the plugin definition
* @returns {boolean} true if successful
*/
plugin(type: string, maker: R2PluginFactory): boolean;
/**
* Unload the plugin associated with a `type` and a `name`.
*
* @param {string} type of plugin ("core", "io", "arch", ...)
* @param {string} name of the plugin
* @returns {boolean} true if successful
*/
unload(type: string, name: string): boolean;
}
/**
* A global instance of R2Pipe associated with the current instance of radare2
*
* @type {R2PipeSync}
*/
export declare const r2: R2Pipe;
-36
View File
@@ -1,36 +0,0 @@
import { AppState } from "./types";
import { DEFAULT_PROMPT } from "./constants";
export const defaultState: AppState = {
decopipe: { use: false },
host: "http://localhost",
port: "11434",
baseurl: "",
extraHeaders: [],
api: "ollama",
pipeline: "",
commands: "pdc",
yolo: false,
tts: false,
language: "C",
humanLanguage: "English",
deterministic: true,
debug: false,
timeout: 180,
http: "auto",
think: "",
apitype: "chat",
useFiles: false,
contextFile: "",
model: "",
cache: false,
maxInputTokens: -1,
prompt: DEFAULT_PROMPT,
lastOutput: "",
};
export const state: AppState = {
...defaultState,
decopipe: { ...defaultState.decopipe },
extraHeaders: [...defaultState.extraHeaders],
};
-16
View File
@@ -1,16 +0,0 @@
{
"compilerOptions": {
"target": "es2020",
"lib": ["esnext"],
"module": "commonjs",
"outDir": "out",
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"**/*.ts"
]
}
-169
View File
@@ -1,169 +0,0 @@
import type { R2PipeSync } from "./r2pipe";
interface ConsoleLike {
log: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
}
declare global {
const r2: R2PipeSync;
const console: ConsoleLike;
function btoa(str: string): string;
}
export type ApiStyle = "openai" | "anthropic" | "ollama" | "gemini";
export type AuthStyle = "none" | "bearer" | "anthropic";
export type OllamaApiType = "chat" | "generate";
export interface ProviderConfig {
defaultModel: string;
defaultBaseUrl: string;
authKey?: string;
authStyle?: AuthStyle;
keyName?: string;
apiStyle: ApiStyle;
hardcodedModels?: string[];
}
export interface ProviderRegistry {
[key: string]: ProviderConfig;
}
export interface DecoPipeConfig {
use: boolean;
default?: string;
[key: string]: unknown;
}
export interface AppState {
decopipe: DecoPipeConfig;
host: string;
port: string;
baseurl: string;
extraHeaders: string[];
api: string;
pipeline: string;
commands: string;
yolo: boolean;
tts: boolean;
language: string;
humanLanguage: string;
deterministic: boolean;
debug: boolean;
timeout: number;
http: "auto" | "r2" | "curl";
think: string;
apitype: OllamaApiType;
useFiles: boolean;
contextFile: string;
model: string;
cache: boolean;
maxInputTokens: number;
prompt: string;
lastOutput: string;
}
export interface ConfigHandler {
get: () => string | number | boolean;
set: (v: string) => void;
}
export interface ConfigHandlers {
[key: string]: ConfigHandler;
}
export type ApiKeyResult = [string | null, string | null, string];
export interface ApiError {
message?: string;
[key: string]: unknown;
}
export interface OpenAIChoice {
message?: {
content?: string;
};
}
export interface AnthropicContentBlock {
text?: string;
}
export interface OllamaMessage {
content?: string;
}
export interface GeminiPart {
text?: string;
}
export interface GeminiCandidate {
content?: {
parts?: GeminiPart[];
};
}
export interface ModelDataEntry {
id: string;
name?: string;
max_context_length?: number;
description?: string;
}
export interface OllamaModelEntry {
name: string;
}
export interface HttpResponse {
error?: ApiError | string;
rawOutput?: string;
choices?: OpenAIChoice[];
content?: AnthropicContentBlock[];
message?: OllamaMessage;
candidates?: GeminiCandidate[];
data?: ModelDataEntry[];
models?: OllamaModelEntry[];
result?: string;
[key: string]: unknown;
}
export type JsonObject = Record<string, unknown>;
export interface AnthropicPayload {
model: string;
max_tokens: number;
messages: Array<{ role: string; content: string }>;
thinking?: { type: string; budget_tokens?: number };
temperature?: number;
top_p?: number;
top_k?: number;
}
export interface OllamaPayload {
stream: boolean;
model: string;
messages?: Array<{ role: string; content: string }>;
prompt?: string;
think?: boolean | string;
options?: {
repeat_last_n: number;
top_p: number;
top_k: number;
temperature: number;
repeat_penalty: number;
seed: number;
};
}
export interface GeminiPayload {
contents: Array<{ parts: Array<{ text: string }> }>;
generationConfig?: Record<string, unknown>;
}
export interface AutoReply {
action: string;
command?: string;
description?: string;
reason?: string;
response?: string;
}
-97
View File
@@ -1,97 +0,0 @@
import { state } from "./state";
export function tmpdir(path: string): string {
const dir = r2.cmd("-e dir.tmp").trim() ?? ".";
return dir + "/" + path;
}
// r2's mkdir and touch commands do not expand '~'
export function expandHome(path: string): string {
if (!path.startsWith("~/")) {
return path;
}
const home = r2.cmd("'%HOME").trim() || r2.cmd("'%USERPROFILE").trim();
return home ? home + path.slice(1) : path;
}
export function ensurePath(dir: string, file: string): void {
r2.cmd("'mkdir -p " + expandHome(dir));
r2.cmd("'touch " + expandHome(file));
}
export function fileExists(path: string): boolean {
const helpMessage = r2.cmd2("test -h").logs?.[0]?.message ?? "";
if (helpMessage.includes("-fdx")) {
return true; // r2 is old
}
return r2.cmd("'test -vf " + path).startsWith("found");
}
export function padRight(str: string, length: number): string {
return str + " ".repeat(Math.max(0, length - str.length));
}
export function joinUrl(baseUrl: string, path: string): string {
return baseUrl.replace(/\/+$/, "") + "/" + path.replace(/^\/+/, "");
}
export function trimAnsi(str: string): string {
return str.replace(/\x1b\[[0-9;]*m/g, "");
}
export function trimDown(out: string): string {
const jsonMatch = out.match(/```json\s*([\s\S]*?)```/);
return jsonMatch && jsonMatch[1] ? jsonMatch[1].trim() : out;
}
export function trimJson(out: string): string {
let result = out;
const openBrace = result.indexOf("{");
if (openBrace !== -1) result = result.slice(openBrace);
const closeBrace = result.lastIndexOf("}");
if (closeBrace !== -1) result = result.slice(0, closeBrace + 1);
return result;
}
export function b64(str: string): string {
return btoa(str);
}
export function fileDump(fileName: string, fileData: string): void {
const d = b64(fileData);
r2.cmd("p6ds " + d + " > " + fileName);
}
export function filterResponse(msg: string): string {
let result = msg;
result = result.replace(/<think>[\s\S]*?<\/think>/gi, "");
return result
.split("\n")
.filter((line) => !line.trim().startsWith("```"))
.join("\n");
}
export function debugLog(msg: string): void {
if (state.debug) {
console.log(msg);
}
}
export function parseEnvLikeString(input: string): Record<string, string> {
const result: Record<string, string> = {};
for (const line of input.split(/\r?\n/)) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) {
continue;
}
const [key, ...rest] = trimmed.split("=");
if (!key || rest.length === 0) {
continue;
}
const value = rest.join("=").trim();
// Normalize key: strip trailing _API_KEY (case-insensitive)
const normKey = key.toLowerCase().replace(/_api_key$/i, "");
result[normKey] = value;
}
return result;
}
-130
View File
@@ -1,130 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940, 2025-05-08)"
sodipodi:docname="decai.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0482005"
inkscape:cx="318.64133"
inkscape:cy="426.92214"
inkscape:window-width="1512"
inkscape:window-height="960"
inkscape:window-x="222"
inkscape:window-y="44"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
id="rect2"
width="186.28354"
height="176.18687"
x="1.5145004"
y="23.979588"
ry="0.047831953" />
<path
sodipodi:type="star"
style="fill:#1a1a1a;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
id="path1"
inkscape:flatsided="false"
sodipodi:sides="10"
sodipodi:cx="71.751205"
sodipodi:cy="102.09375"
sodipodi:r1="53.804771"
sodipodi:r2="49.845222"
sodipodi:arg1="0.65927727"
sodipodi:arg2="0.97343657"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 114.28039,135.05163 -14.49317,8.25532 -13.001341,10.44831 -16.577574,-1.84017 -16.659669,0.81086 -12.329911,-11.23279 -13.95457,-9.1363 -3.37264,-16.33486 -5.919299,-15.59371 6.872864,-15.197565 4.376943,-16.094859 14.493168,-8.255319 13.001341,-10.448311 16.577574,1.840177 16.659669,-0.810865 12.329915,11.232788 13.95457,9.136304 3.37264,16.334856 5.91929,15.593714 -6.87286,15.19757 z"
transform="matrix(1.2188073,0,0,1.2188073,1.600691,-15.424646)" />
<path
sodipodi:type="star"
style="fill:#37662e;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
id="path1-5"
inkscape:flatsided="false"
sodipodi:sides="10"
sodipodi:cx="71.751205"
sodipodi:cy="102.09375"
sodipodi:r1="35.902484"
sodipodi:r2="49.845222"
sodipodi:arg1="0.32368816"
sodipodi:arg2="0.63784749"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 105.78923,113.51309 6.0066,18.26187 -19.219401,-0.43572 -5.874621,18.30475 L 71.4091,137.9946 55.897164,149.35045 50.372443,130.93707 31.148226,131.00645 37.501747,112.86236 21.908246,101.61878 37.71318,90.674414 31.706582,72.412538 l 19.2194,0.435725 5.874621,-18.304757 15.292708,11.649389 15.511935,-11.355844 5.524722,18.413382 19.224212,-0.06938 -6.35352,18.144089 15.5935,11.243582 z"
transform="matrix(1.2188073,0,0,1.2188073,0.97362416,-14.941195)" />
<path
sodipodi:type="star"
style="fill:#800000;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
id="path2"
inkscape:flatsided="false"
sodipodi:sides="10"
sodipodi:cx="69.252403"
sodipodi:cy="183.84013"
sodipodi:r1="76.18972"
sodipodi:r2="39.770834"
sodipodi:arg1="0.94510027"
sodipodi:arg2="1.2659605"
inkscape:rounded="0.029345222"
inkscape:randomized="0"
d="m 113.8738,245.59614 c -0.96661,0.6886 -31.555039,-24.18254 -32.684714,-23.81876 -1.120974,0.36099 -10.958876,38.2632 -12.136488,38.25221 -1.186753,-0.0111 -11.314419,-38.11167 -12.442172,-38.48137 -1.119068,-0.36685 -31.356457,24.51411 -32.302709,23.81304 -0.953595,-0.70651 13.247923,-37.48344 12.552854,-38.44541 -0.689714,-0.95456 -39.7769375,1.40147 -40.1303916,0.27809 -0.3561976,-1.13209 32.7500076,-22.5378 32.7531166,-23.7246 0.0031,-1.17766 -33.0039804,-22.24649 -32.6296302,-23.36307 0.3772559,-1.12525 39.7427032,1.0165 40.4428022,0.0582 0.694707,-0.95093 -13.624624,-37.39704 -12.665459,-38.08034 0.966611,-0.68859 31.555037,24.18255 32.684712,23.81876 1.120974,-0.36098 10.958875,-38.26319 12.136488,-38.2522 1.186752,0.0111 11.314419,38.11167 12.442172,38.48137 1.119067,0.36685 31.356459,-24.51411 32.302709,-23.81304 0.95359,0.70651 -13.24792,37.48344 -12.55285,38.44541 0.68971,0.95456 39.77693,-1.40147 40.13039,-0.2781 0.35619,1.13209 -32.75001,22.53781 -32.75312,23.72461 -0.003,1.17766 33.00398,22.24649 32.62963,23.36307 -0.37726,1.12524 -39.7427,-1.01651 -40.4428,-0.0582 -0.69471,0.95093 13.62462,37.39704 12.66546,38.08033 z"
transform="translate(19.276442,-75.320913)" />
<path
sodipodi:type="star"
style="fill:#d45500;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
id="path2-0"
inkscape:flatsided="false"
sodipodi:sides="10"
sodipodi:cx="69.252403"
sodipodi:cy="183.84013"
sodipodi:r1="3.2911112"
sodipodi:r2="71.359137"
sodipodi:arg1="1.3521275"
sodipodi:arg2="1.5760036"
inkscape:rounded="0.029345222"
inkscape:randomized="0"
d="m 69.966345,187.05287 c -1.9053,0.60813 0.905346,68.33625 -1.085527,68.14543 -1.996473,-0.19135 0.964985,-67.70967 -0.939225,-68.33936 -1.898868,-0.62792 -39.434599,55.81734 -40.933089,54.49275 -1.502705,-1.3283 40.579437,-54.21107 39.409022,-55.83977 -1.167132,-1.62412 -64.7118681,21.9781 -65.1456023,20.0257 -0.43495449,-1.95789 64.6939243,-20.00568 64.7043623,-22.01128 0.01041,-1.99997 -65.27140303,-20.25603 -64.4747102,-22.09049 0.7989341,-1.83963 64.0975312,21.84119 65.2848352,20.22477 1.183973,-1.61189 -40.89948,-54.75304 -39.17667,-55.76887 1.727657,-1.01869 39.01806,55.34548 40.92872,54.73564 1.905301,-0.60812 -0.905346,-68.33625 1.085527,-68.14543 1.996474,0.19136 -0.964984,67.70968 0.939225,68.33937 1.898868,0.62792 39.434597,-55.81734 40.933087,-54.49276 1.50271,1.32831 -40.579435,54.21108 -39.409019,55.83977 1.167131,1.62413 64.711869,-21.97809 65.145599,-20.0257 0.43496,1.9579 -64.693921,20.00569 -64.704359,22.01129 -0.01041,1.99997 65.271399,20.25602 64.474709,22.09049 -0.79893,1.83963 -64.09753,-21.8412 -65.284834,-20.22477 -1.183973,1.61189 40.899484,54.75304 39.176674,55.76887 -1.72766,1.01869 -39.018064,-55.34548 -40.928725,-54.73565 z"
transform="translate(19.25264,-74.484719)" />
<path
sodipodi:type="star"
style="fill:#ffb380;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
id="path2-0-7"
inkscape:flatsided="false"
sodipodi:sides="10"
sodipodi:cx="69.252403"
sodipodi:cy="183.84013"
sodipodi:r1="2.0329688"
sodipodi:r2="36.653175"
sodipodi:arg1="1.3051581"
sodipodi:arg2="1.5885803"
inkscape:rounded="0.029345222"
inkscape:randomized="0"
d="m 69.786109,185.8018 c -0.974051,0.29744 -0.168255,34.73512 -1.18551,34.68571 -1.01845,-0.0495 0.894533,-34.41437 -0.06946,-34.74665 -0.962858,-0.3319 -20.552916,28.00241 -21.346851,27.36451 -0.794867,-0.63865 20.951954,-27.31602 20.367382,-28.15147 -0.583886,-0.83446 -33.087061,10.57373 -33.354419,9.59099 -0.267673,-0.98389 33.006439,-9.78387 33.024571,-10.80336 0.01811,-1.01829 -32.983073,-10.89376 -32.621734,-11.84596 0.361764,-0.95332 32.453587,11.48538 33.067497,10.67125 0.61319,-0.81317 -20.280673,-28.2002 -19.428655,-28.75816 0.853019,-0.55861 19.504568,28.36761 20.479763,28.06981 0.974051,-0.29744 0.168255,-34.73512 1.18551,-34.68572 1.01845,0.0495 -0.894534,34.41438 0.06946,34.74666 0.962858,0.3319 20.552915,-28.00241 21.34685,-27.36451 0.794868,0.63865 -20.951953,27.31602 -20.367382,28.15146 0.583886,0.83446 33.087059,-10.57372 33.354419,-9.59099 0.26767,0.98389 -33.006439,9.78388 -33.024571,10.80337 -0.01811,1.01829 32.983071,10.89376 32.621731,11.84596 -0.36176,0.95332 -32.453584,-11.48538 -33.067494,-10.67125 -0.613189,0.81317 20.280674,28.2002 19.428655,28.75816 C 89.412852,214.43022 70.761304,185.504 69.786109,185.8018 Z"
transform="rotate(-17.984043,-157.18948,86.992365)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

+3 -3
View File
@@ -23,12 +23,12 @@ if [ -f ~/.r2ai.openai-key ]; then
OPENAI_KEY=$(cat ~/.r2ai.openai-key)
fi
CLAUDE_KEY=""
CLAUDE_MODEL="claude-sonnet-5-5"
CLAUDE_MODEL="claude-3-5-sonnet-20241022"
if [ -f ~/.r2ai.anthropic-key ]; then
CLAUDE_KEY=$(cat ~/.r2ai.anthropic-key)
fi
DEEPSEEK_KEY=""
DEEPSEEK_MODEL="claude-sonnet-5-5"
DEEPSEEK_MODEL="claude-3-5-sonnet-20241022"
if [ -f ~/.r2ai.deepseek-key ]; then
DEEPSEEK_KEY=$(cat ~/.r2ai.anthropic-key)
fi
@@ -138,7 +138,7 @@ GEMINI_KEY=~/.r2ai-gemini.key
OPENAI_KEY=~/.r2ai-openai.key
CLAUDE_KEY=~/.r2ai-anthropic.key
DEEPSEEK_KEY=~/.r2ai-deepseek.key
CLAUDE_MODEL=claude-sonnet-5-5
CLAUDE_MODEL=claude-3-5-sonnet-20241022
EOF
exit 0
}
File renamed without changes.
+41
View File
@@ -0,0 +1,41 @@
SHELL=/bin/bash
PROVIDER=ollama
MODELS=granite3-dense:8b mannix/jan-nano:latest yi-coder:latest qwen3:latest deepseek-coder-v2:latest hhao/qwen2.5-coder-tools:latest qwen2.5-coder:latest
MODELS=gemma3:1b
LANGS=Dart Perl Ruby Javascript PHP C
BINARIES=files/complex1 files/complex2 files/complex3
MODELS=gpt-4o
PROVIDER=openai
all:
mkdir -p tmp
for b in $(BINARIES) ; do \
for a in $(MODELS) ; do \
echo "$$b $$a"; \
./run.sh $$b $$a ${PROVIDER} ${LANGS} > tmp/$${b##*/}_$${a//\//_}.html ; \
done ; \
done
.PHONY: run index evaluate
compile: $(BINARIES)
files/complex1: files/complex1.c
gcc -o $@ $<
files/complex2: files/complex2.c
gcc -o $@ $<
files/complex3: files/complex3.c
gcc -o $@ $<
lmstudio:
for b in $(BINARIES) ; do \
for a in $(MODELS) ; do \
./run.sh $$b $$a lmstudio ${LANGS} > $${b##*/}_$${a//\//_}.html ; \
done ; \
done
clean:
rm -rf tmp
File renamed without changes.
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
# Evaluate decompiled outputs using mai and determine best model+lang
echo "Evaluating decompiled outputs..."
tmpfile=$(mktemp)
MAI="mai -q -p openai -m gpt-4o"
# MAI="mai -q"
for orig in files/complex1.c files/complex2.c files/complex3.c; do
base=$(basename $orig .c)
original_code=$(cat $orig)
for f in tmp/${base}_*.txt; do
if [ -f "$f" ]; then
decompiled_code=$(cat $f)
#echo "Comparing $orig $f"
result=`echo n | ${MAI} -q -r "/template files/CMPROMPT.txt original=@${orig} decompiled=@${f}"`
score=`echo "$result" | head -n 1 | grep -oE '[0-9]+'` # |head -n 1`
perfect=`echo "$result" | grep 'No sign' && echo yes`
[ -z "$score" ] && score=0
if [ "$perfect" = yes ]; then
score=100
else
score="$((0+${score}))"
fi
echo "$score\t$f"
if [ -n "$score" ]; then
key="${f%.*}" # remove .txt
# Check if key exists in tmpfile
existing=$(grep "^$key " $tmpfile | awk '{print $2}')
if [ -n "$existing" ]; then
new_score=$(( existing + score ))
sed -i "s/^$key .*/$key $new_score/" $tmpfile
else
echo "$key $score" >> $tmpfile
fi
fi
fi
done
done
# Find the best (highest total score)
best_key=""
best_score=0
while read key score; do
if [ "$score" -gt "$best_score" ]; then
best_score=$score
best_key=$key
fi
done < $tmpfile
rm $tmpfile
if [ -n "$best_key" ]; then
echo "Best model+language combination: $best_key with total score $best_score"
else
echo "No scores found"
fi
+17
View File
@@ -0,0 +1,17 @@
Compare the two provided code in C with the decompiled counterpart. Ignore function or variable names, syntax differences, language-specific constructs, and formatting. Focus solely on what the code does: the operations performed, control flow, logic, and functional behavior. Determine if they are functionally equivalent in terms of their effects and computations.
Output only:
- A numeric score from 1 to 100 (100 being identical logic and functionality)
- Followed by a single sentence describing the most relevant semantic differences (or "No significant semantic differences" if score is 95+)
**Original Source Code:**
```C
{original}
```
**Decompiled Code:**
```
{decompiled}
```
+21
View File
@@ -0,0 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
int *arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) return 1;
for (int i = 0; i < n; i++) {
arr[i] = i * i;
}
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
for (int j = 0; j < i; j++) {
sum -= j;
}
}
printf("Sum: %d\n", sum);
free(arr);
return 0;
}
+39
View File
@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main() {
struct Node *head = NULL;
struct Node *tail = NULL;
for (int i = 0; i < 10; i++) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL) return 1;
newNode->data = i * 2;
newNode->next = NULL;
if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
struct Node *current = head;
int sum = 0;
while (current != NULL) {
sum += current->data;
current = current->next;
}
printf("Sum: %d\n", sum);
current = head;
while (current != NULL) {
struct Node *temp = current;
current = current->next;
free(temp);
}
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
#include <stdio.h>
int main() {
int x = 42;
int y = 0;
switch (x & 15) {
case 0:
y = x << 1;
break;
case 1:
y = x >> 1;
break;
case 2:
y = x ^ 255;
break;
case 3:
y = ~x;
break;
default:
y = x | 128;
break;
}
if ((y & 1) == 0) {
y += 10;
} else {
y -= 5;
}
for (int i = 0; i < 5; i++) {
y = (y << 2) | (y >> 30);
}
printf("Result: %d\n", y);
return 0;
}
@@ -1,5 +1,6 @@
#!/bin/bash
cp decai/BENCH.txt tmp/BENCH.txt
# Find all directories containing BENCH.txt
dirs=$(find . -name "BENCH.txt" -type f | xargs dirname | sort | uniq)
@@ -46,4 +47,4 @@ cat <<EOF >> benchmark_index.html
<br />
<br />
</html>
EOF
EOF
@@ -1,12 +1,55 @@
#!/bin/bash
# Generate HTML output for command executions with collapsible sections and width control
# If PLAIN=1, output plain text instead
if [ $# -eq 0 ]; then
echo "Usage: $0 command1 [command2 ...]"
if [ $# -lt 4 ]; then
echo "Usage: $0 <binary> <model> <provider> <lang1> [lang2 ...]"
echo "Or: $0 command1 [command2 ...] (legacy)"
exit 1
fi
# Check if first arg is a file (binary), assume new format
if [ -f "$1" ]; then
binary="$1"
model="$2"
provider="$3"
shift 3
langs=("$@")
commands=()
for lang in "${langs[@]}"; do
# commands+=("# $lang echo \"decai -e model=$model;decai -e lang=$lang;decai -e api=$provider;af;decai -d\" | r2 -q $binary 2> /dev/null")
commands+=("# $lang r2 -e scr.color=0 -qcq -qc \"decai -e model=$model;decai -e lang=$lang;decai -e api=$provider;af;decai -d\" $binary")
done
set -- "${commands[@]}"
else
# Legacy mode
commands=("$@")
fi
if [ "$PLAIN" = "1" ]; then
# In plain mode, execute each command and print raw output.
# Also, if TXTFILE is set, save combined raw output there.
tmp_plain=$(mktemp)
for cmd in "$@"; do
if [[ "$cmd" =~ ^#[[:space:]]*(.*) ]]; then
exec_cmd="${BASH_REMATCH[1]}"
else
exec_cmd="$cmd"
fi
tmpout=$(mktemp)
eval "$exec_cmd" > "$tmpout" 2>&1 || true
mv "$tmpout" "$tmp_plain"
rm -f "$tmpout"
done
if [ -n "$TXTFILE" ]; then
mv "$tmp_plain" "$TXTFILE"
else
rm -f "$tmp_plain"
fi
exit 0
fi
# Timeout in seconds for each command (configurable via TIMEOUT environment variable)
TIMEOUT=${TIMEOUT:-30}
@@ -109,24 +152,27 @@ EOF
# Process each command
for cmd in "$@"; do
# Extract title: if command starts with #, use the rest as title, else use the command
if [[ "$cmd" =~ ^#[[:space:]]*(.*) ]]; then
# Extract title: if command starts with #, parse title and command, else use the command
if [[ "$cmd" =~ ^#[[:space:]]*([^[:space:]]+)[[:space:]]*(.*) ]]; then
title="${BASH_REMATCH[1]}"
exec_cmd="${cmd#*#}"
exec_cmd="${exec_cmd#"${exec_cmd%%[![:space:]]*}"}" # trim leading spaces
exec_cmd="${BASH_REMATCH[2]}"
else
title="$cmd"
exec_cmd="$cmd"
fi
echo "RUN $exec_cmd" > /dev/stderr
# Execute command and time it
start_time=$(date +%s.%N)
tmpfile=$(mktemp)
eval "$exec_cmd" > "$tmpfile" 2>&1 &
# echo "eval $exec_cmd > $tmpfile" > /dev/stder
eval "$exec_cmd" > "$tmpfile" 2> /dev/null &
pid=$!
(sleep $TIMEOUT && kill $pid 2>/dev/null) &
wait $pid 2>/dev/null
output=$(cat "$tmpfile")
#echo "$output" > /dev/stderr
rm "$tmpfile"
exit_code=$?
end_time=$(date +%s.%N)
@@ -139,8 +185,16 @@ for cmd in "$@"; do
execution_time=$(printf "%.3f" "$execution_time")
fi
# Save plain output to .txt file if in new format
if [ -n "$binary" ]; then
txtfile="tmp/${binary##*/}_${model//\//_}_${title}.txt"
mkdir -p "$(dirname "$txtfile")" 2>/dev/null || true
echo "$output" > "$txtfile"
fi
# Escape HTML in output
escaped_output=$(echo "$output" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')
#escaped_output=$(echo "$output" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')
escaped_output="$output"
cat << EOF
<div class="command-section expanded">
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-57
View File
@@ -1,57 +0,0 @@
# R2AI Prompts
This directory contains predefined prompt files for the r2ai plugin.
## Format
Each prompt is stored in a `.r2ai.md` file with YAML-style frontmatter and a markdown body.
Example:
```markdown
---
description: 'Explain the current function'
author: pancake
command: r2ai -d
if-empty: exit
---
Explain the purpose of this function in one or two short sentences.
```
Supported keys:
- `title`: The title of the prompt
- `author`: The author of the prompt
- `description`: A brief description
- `command`: Commands to execute before sending the prompt, separated by `;` (required)
- `requires`: Requirements for the prompt (e.g., "analysis" to ensure binary analysis)
- `if-empty`: Alternative prompt or message if the command output is empty
- `if-command`: Additional commands to run if the main command produces output
- `model`: Model override for this prompt
- `provider`: Provider override for this prompt
Legacy `.r2ai.txt` files using `Title:`, `Command:`, `Prompt:` or `Query:` are still accepted.
## Variable Substitution
In the markdown body, you can use:
- `${VAR}`: Replaced with the value of the environment variable `VAR`
- `$(cmd)`: Replaced with the output of the r2 command `cmd`
## Usage
- `r2ai -q`: List all available prompts
- `r2ai -qj`: List all available prompts in JSON
- `r2ai -q name`: Run the prompt named `name`
- `r2ai -q name extra text`: Run the prompt with additional text appended
## Conditionals
- `if-empty`: If the command output is empty, use this as the prompt instead
- `if-command`: If the command produces output, run these additional commands and append their output
## Future Features
- Support for r2js scripts
- More advanced conditionals
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Automatically suggest a better name for this function'
version: 0.1
author: pancake
command: afv;r2ai -d
if-empty: exit
---
Suggest a better name for this function. Output only the suggested function name (must be one alphanumeric word) prefixed with `'afn '. Check the code below:
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Compact conversation history into a summary'
version: 0.1
author: pancake
command: r2ai -C
if-empty: exit
---
Create a compact summary of this conversation that preserves all key information, insights, and context for future reference. Focus on essential details about the binary analysis, tools used, findings, and any important conclusions.
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Augmented decompilation based on LLM'
version: 0.1
author: pancake
command: pdc
if-empty: exit
---
$(-e r2ai.prompt). Translate the code into $(-e r2ai.lang) programming language.
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Find and explain devices used'
version: 0.1
author: pancake
command: izqq~^/dev
if-empty: exit
---
explain in one line the purpose of each of these devices
-8
View File
@@ -1,8 +0,0 @@
---
description: 'List libraries loaded with dlopen'
version: 0.1
author: pancake
command: iiq~dlopen
if-empty: This binary is not using dlopen
---
Some libraries are loaded
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Explain the current function'
version: 0.1
author: pancake
command: r2ai -d
if-empty: exit
---
Analyze function calls, comments and strings, ignore registers and memory accesses. Considering the references and involved loops; explain the purpose of this function in one or two short sentences. Output must be only the translation of the explanation in $(-e r2ai.hlang)
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Group imports by Libraries'
version: 0.1
author: pancake
command: iiq;il
if-empty: exit
---
Group the imports that belong to each library and describe its purpose and usage scope
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Suggest an improved function signature'
version: 0.1
author: pancake
command: ?e variables;afv;?e function name:;afd;?e current signature:?e afs
if-empty: exit
---
Analyze the uses of the arguments and return value to infer the signature, identify which is the correct type for the resturn. Do NOT print the function body. Output must be *ONLY* the function signature prefixed with the `'afs ` text
-10
View File
@@ -1,10 +0,0 @@
---
description: 'Decompile this code into PHP'
version: 0.1
author: pancake
command: pdg
if-empty: exit
---
Your goal is to $(-e r2ai.prompt).
Translate the code into $(-e r2ai.lang) programming language.
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Better variable names'
version: 0.1
author: pancake
command: afv
if-empty: exit
---
Output only the radare2 command without markdown, guess a better name and type for each local variable and function argument taking using. output an r2 script using afvn and afvt commands
-8
View File
@@ -1,8 +0,0 @@
---
description: 'Find vulnerabilities or bugs in the current function'
version: 0.1
author: pancake
command: pdc
if-empty: exit
---
Find vulnerabilities, do not show the code, only a short summary of the resulting analysis report including suggested good practices to address the problem and a practical exploit example.
-40
View File
@@ -1,40 +0,0 @@
# r2plugin
This directory contains the make and meson files required to link r2ai
inside radare2 through the external plugin system (XPS).
```console
cd radare2
make -C libr/xps EXTERNAL_PLUGINS=r2ai
./configure-plugins
make
```
For meson builds, place this repository at `libr/xps/p/r2ai` and make
`libr/xps/p/meson.build` include:
```meson
subdir('r2ai/r2plugin')
```
## WASI HTTP build
Use a radare2 checkout with the host HTTP bridge and place this repository at
`libr/xps/p/r2ai`. From that radare2 checkout:
```sh
echo 'EXTERNAL_PLUGINS+=r2ai' >> libr/xps/config.mk
make -C libr/xps
WASI_HTTP=1 sys/wasi-api.sh
```
This links the C plugin into the reactor; it does not load a native shared
library at runtime. Enable HTTP in the host adapter. The `auto` backend selects
`r_socket_http_get/post`, preserving provider authentication headers and JSON
bodies, subject to the radare2 sandbox. `--disable-network` also denies these calls.
WASI excludes POSIX signal/alarm handling; the host controls request timeouts,
not `r2ai.http.timeout`. Normal queries and model listing use buffered HTTP.
Vertex's automatic `gcloud` authentication and background tasks requiring
threads are unavailable. Explicit shell backends (`system`/`curl`) cannot work;
use `auto` or `socket`. Browser CORS and restricted-header rules still apply.
-9
View File
@@ -1,9 +0,0 @@
EXTERNAL_PLUGINS+=r2ai
# EXTERNAL_PLUGINS+=hi
.PHONY: r2ai
r2ai: p/r2ai
p/r2ai:
cd p && git clone https://github.com/radareorg/r2ai
Loaded 100 of 148 files, more files were not shown because too many files have changed in this diff. Show more