Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,71 @@ frida-ps -U #List packages and processes
frida-ps -U | grep -i <part_of_the_package_name> #Get all the package name
```

## Native Frida build on Android/Termux (without NDK)

If you want to **build Frida directly on-device inside Termux** instead of cross-compiling with the Android NDK, a practical approach is to configure Frida as **`linux-arm64`** and compile it against **Termux clang + Bionic**. This is useful when the phone/tablet is your primary reversing environment, but it is **not** an upstream-supported build path and requires local patches.

Key ideas:
- Use **`--build=linux-arm64`**, **not** `android-arm64`, to avoid Frida's NDK-specific `env_android.py` path.
- Disable Frida downloads of prebuilt toolchains/helpers with **`--without-prebuilds=sdk,toolchain`** and **`-Dfrida-core:compat=disabled`**.
- Force Frida's **patched GLib** subproject with **`--force-fallback-for=glib-2.0,gobject-2.0,gio-2.0,gmodule-2.0,gthread-2.0`** because system GLib lacks internal APIs used by Frida glue code (`gio_shutdown()`, `glib_shutdown()`, `gio_deinit()`).
- Disable **`frida-core:compiler_backend`** to avoid Android/Termux crashes in the Go/npm compiler backend. This means **`frida.compile()` will not work**.
- `frida-server` still **requires root** at runtime, and disabling compat means **same-architecture injection only**.

Minimal package setup in Termux:

```bash
pkg up -y
pkg i -y build-essential cmake clang ninja git python valac gobject-introspection libiconv libminizip-ng
pip install meson
```

### Native Termux build gotchas

- **Patched Vala is mandatory**: Frida rejects stock `valac`; build `frida/vala` first and use the resulting `valac` from `deps/toolchain-linux-arm64/`.
- **Bionic feature-detection false positives**: Meson may think functions such as `close_range`, `prlimit`, `lchmod`, or `getmntent_r` exist because Bionic's linker can allow unresolved symbols during `cc.has_function()` tests. After each configure/reconfigure, strip those bad `HAVE_*` defines from generated `config.h` files.
- **Opaque `FILE *` on Bionic**: Frida's `libc-shim.c` needs Android-specific guards so it does not access libc internals or redefine `stdin` / `stdout` / `stderr` / `tmpfile()`.
- **Termux minizip-ng API drift**: Frida expects the older out-parameter API, while Termux ships `libminizip-ng` 4.x returning pointers directly. Patch both the C call sites and `minizip.vapi`.
- **Low-memory builds**: use `ninja -C build -j2` or even `-j1` on low-RAM devices. Configure wrapper crashes are sometimes harmless if `build/build.ninja` already exists.

Quick detection test for Bionic false positives:

```bash
echo "extern char FUNC(void); int main(){return FUNC();}" | cc -xc - -o /dev/null 2>/dev/null
# exit 0 => the unresolved symbol was accepted, so Meson-style function checks may be lying
```

<details>
<summary>Example native Frida configure/build flow inside Termux</summary>

```bash
cd ~/frida
export PATH=$HOME/frida/deps/toolchain-linux-arm64/bin:$PATH
export LD_LIBRARY_PATH=$HOME/frida/deps/toolchain-linux-arm64/lib:$LD_LIBRARY_PATH

rm -rf build
./configure --build=linux-arm64 \
--without-prebuilds=sdk,toolchain \
-- -Dfrida-core:compat=disabled \
-Dfrida-core:compiler_backend=disabled \
-Dfrida-core:local_backend=enabled \
-Dfrida_tools=disabled \
--force-fallback-for=glib-2.0,gobject-2.0,gio-2.0,gmodule-2.0,gthread-2.0 \
-Dglib:iconv=external \
-Dserver=enabled \
-Dinject=enabled \
-Dgadget=enabled

find build/subprojects -name config.h -print0 | \
xargs -0 sed -i '/^#define HAVE_\(CLOSE_RANGE\|PRLIMIT\|LCHMOD\|GETMNTENT_R\|ENDMNTENT\|SETMNTENT\|HASMNTOPT\) /d'

ninja -C build -j2
```

</details>

Expected outputs usually include `frida-server`, `frida-helper`, `frida-inject`, `frida-gadget.so`, and the Python bindings under `build/subprojects/frida-python/`.

## frida-ui (browser-based Frida controller)

**frida-ui** provides a web UI on `http://127.0.0.1:8000` to list devices/apps and attach or spawn targets with scripts (no CLI needed).
Expand Down Expand Up @@ -523,5 +588,10 @@ Java.choose("com.example.a11x256.frida_test.my_activity", {
- [Android Frida Hooking: Disabling FLAG_SECURE](https://www.securify.nl/en/blog/android-frida-hooking-disabling-flagsecure/)
- [frida-ui](https://github.com/adityatelange/frida-ui)
- [clsdumper — Android Dynamic Class Dumper](https://github.com/TheQmaks/clsdumper)
- [How hard can it be to build Frida natively on Android/Termux(without NDK?)](https://qbtau.in/posts/building_frida_on_termux/)
- [Frida source tree](https://github.com/frida/frida)
- [Frida patched Vala](https://github.com/frida/vala)
- [Frida patched GLib](https://github.com/frida/glib)
- [Termux Frida package build script](https://github.com/termux/termux-packages/blob/master/root-packages/frida/build.sh)

{{#include ../../../banners/hacktricks-training.md}}