
phantom-frida v17.16.4-20260726-run33.1
Build anti-detection Frida server from source. ~90 patches covering 16 detection vectors, weekly auto-builds with random names.
phantom-frida
phantom-frida builds Android Frida Server and Gadget from source while
changing a targeted set of observable runtime identifiers. It is a builder and
verification harness, not a promise that every application-specific detection
method is defeated.
The current compatibility target is Frida 17.16.4 on Android. Other Frida versions are intentionally treated as unverified until their source contracts, full build, and rooted-device acceptance have been repeated.
Use this project only on applications and devices you own or are authorized to test.
What is verified
The repository separates three kinds of evidence:
- Unit and fixture tests validate input handling, exact Frida 17.16.4 source patch contracts, DEX rebuilding, artifact promotion, metadata, workflows, and failure behavior.
build.py --verifyrequires both Server and Gadget, strips the staged Gadget, then rejects known forbidden runtime markers before publishing either artifact.scripts/android_smoke.pyexercises a built artifact on one rooted device: authenticated abstract-UNIX transport, stock-client RPC, spawn, attach, Java bridge assertions,/procchecks, an external root memory scan, and a separately loaded Gadget.
A passing source test or byte scan is not equivalent to runtime stealth. Claims about Android behavior should include the generated, redacted smoke-test report.
Build with GitHub Actions
Run Build Custom Frida from the Actions tab. The reusable build workflow:
- validates every user-controlled build input;
- downloads Android NDK r29 from Google and checks its published checksum;
- clones a fresh upstream source tree instead of caching patched source;
- strips Gadget symbols and uploads only after the hard artifact and marker gates pass;
- includes
build-info.jsonandSHA256SUMSin one build artifact.
The weekly workflow resolves the latest release through the authenticated GitHub API, calls the same read-only build workflow, verifies the downloaded artifact, attests it, and grants release write permission only to the final job.
Local build
Requirements:
- Ubuntu 22.04 or newer (WSL is supported);
- Python 3.10 or newer;
- Git, curl, unzip, a C/C++ toolchain, JDK 17, and Node.js 18 or newer (CI uses Node.js 24.13.1);
- Android SDK platform and build-tools containing
android.jarand D8; - about 20 GB of free disk space.
If --ndk-path is omitted, the builder downloads Android NDK r29 under
build/. A verified pinned-input arm64 build is:
export ANDROID_SDK_ROOT=/path/to/Android/Sdk
python3 build.py \
--version 17.16.4 \
--name oemcodec \
--arch android-arm64 \
--port 27142 \
--extended \
--strict-wx \
--verify
Useful options:
--version, -v Exact Frida semantic version (required)
--name, -n Lowercase replacement name, 3-20 characters
--arch, -a One or more supported Android architectures
--port, -p Listening port; omitted keeps 27042
--extended, -e Apply the optional extended identifier transformations
--strict-wx Harden Frida-owned persistent anonymous RWX mappings on Android
--temp-fixes Apply opt-in, device-specific stability changes
--verify Reject known forbidden markers in final artifacts
--skip-build Patch source without compiling
--skip-clone Use an existing source tree in the work directory
--ndk-path Use an existing Android NDK r29 directory
Outputs and provenance
For the example above, output/ contains:
oemcodec-server-17.16.4-android-arm64
oemcodec-server-17.16.4-android-arm64.gz
oemcodec-gadget-17.16.4-android-arm64.so
oemcodec-gadget-17.16.4-android-arm64.so.gz
build-info.json
SHA256SUMS
build-info.json records the exact builder, Frida, and frida-core commits, NDK
version, UTC build time, architectures, name, port, strict W^X code-pool mode,
and workflow URL when built in Actions. Verify downloaded binary files before use:
cd output
sha256sum --check SHA256SUMS
python3 -m json.tool build-info.json >/dev/null
Public weekly releases also receive a GitHub build-provenance attestation.
SHA256SUMS identifies one output set; binary hashes are not expected to match
across different build hosts.
Stock-client compatibility
The builder preserves the D-Bus protocol interfaces under re.frida.*, the
/re/frida/GadgetSession path, public capital Frida JavaScript API strings,
and generated C ABI symbols required by stock clients. Renaming those values
would break the normal Frida client/server contract.
The D-Bus service identifier, helper JNI package, zymbiote socket prefix, selected process/library/path identifiers, selected thread names, and an optional custom port are separate implementation details that the builder can transform. The output verifier rejects this explicit marker set:
frida\0
frida-zymbiote
re/frida/HelperBackend
frida-server
frida-helper
frida-agent
frida-gadget
frida-eternal-agent
frida-generate-certificate
frida-main-loop
frida:rpc
FridaScriptEngine
GLib-GIO
GDBusProxy
GumScript
Frida/
gum-js-loop
gmain\0
gdbus\0
pool-frida
pool-spawner
jit-cache\0
The exact public API string Frida\0 and allowlisted re.frida.* protocol
identifiers remain intentionally preserved. The HTTP/Inspector prefix
Frida/ is a verifier failure and is renamed independently.
Rooted Android acceptance
Install the exact Python binding recorded in build-info.json, install the
pinned Java bridge dependency, and connect exactly one rooted Android device:
python3 -m pip install "frida==17.16.4" frida-tools
npm ci --ignore-scripts
python3 scripts/android_smoke.py \
--server output/oemcodec-server-17.16.4-android-arm64 \
--gadget output/oemcodec-gadget-17.16.4-android-arm64.so \
--name oemcodec \
--port 27142 \
--package com.example.app \
--ndk build/android-ndk-r29 \
--report android-smoke-report.json
The package must be an installed Java application you are authorized to test.
The harness compiles test_comprehensive.js with the explicit
frida-java-bridge required by Frida 17. Server and Gadget each listen on a
random authenticated abstract-UNIX socket; their host TCP ports exist only as
ADB forwards and no device TCP listener is exposed. The harness also compiles
an ABI-matched root probe that scans the mapped agent and Gadget images through
/proc/<pid>/mem, outside Frida's own process view. It cleans up its processes,
forwards, and remote test directory on exit. The /proc gate also rejects
legacy linjector file-descriptor names and a non-zero TracerPid.
Frida Gadget configuration must be named next to the library as
lib<name>-gadget.config.so; the harness generates and deploys this file.
Development checks
python -m pip install --requirement requirements-dev.txt
npm ci --ignore-scripts
python -m pytest
ruff check .
ruff format --check .
mypy build.py patches.py namegen.py scripts
node --check test_comprehensive.js
bash -n build-wsl.sh
go run github.com/rhysd/actionlint/cmd/[email protected]
See CONTRIBUTING.md for the full evidence requirements.
Repository layout
build.py Clone, patch, compile, verify, and collect artifacts
patches.py Source and same-length binary transformations
namegen.py Seeded build-name and port generation
scripts/android_smoke.py Rooted Android Server/Gadget acceptance harness
test_comprehensive.js Structured Frida 17 Java bridge assertions
tests/ Unit, contract, fixture, and workflow tests
.github/workflows/ CI, CodeQL, reusable build, and release isolation