frida-devkit-termux-compilation.md 4.37 KB

Frida Core Devkit Compilation on Termux

Problem

Frida Python client (pip install frida) fails on Termux because:

  1. PyPI wheels are pre-built for glibc (Linux desktop), not Bionic libc (Android)
  2. Building from source requires frida-core devkit + meson + ninja + glib
  3. Termux lacks ninja package in apt repo

Solution Steps

1. Download Matching Devkit

CRITICAL: devkit version MUST match frida-server --version exactly.

# Check frida-server version first
su -c "/data/local/tmp/frida-server --version"
# Output: 17.15.3

# Download matching devkit
curl -L -o frida-core-devkit.tar.xz \
  "https://github.com/frida/frida/releases/download/17.15.3/frida-core-devkit-17.15.3-android-arm64.tar.xz"

# Extract
tar -xf frida-core-devkit.tar.xz
# Produces: libfrida-core.a, frida-core.h, frida-core-example.c

2. Install Build Dependencies

# Install system deps
pkg install -y clang make pkg-config glib libffi

# Install meson (pip works, ninja does NOT)
pip install meson

3. The Ninja Blocker

PyPI ninja wheel is compiled for glibc, fails on Bionic with "required file not found".

Fix: Compile ninja from source:

# Download ninja source
curl -L -o ninja-src.tar.gz \
  "https://github.com/ninja-build/ninja/archive/refs/tags/v1.12.1.tar.gz"
tar -xzf ninja-src.tar.gz
cd ninja-1.12.1

# Fix Android Bionic compatibility (sysinfo/SI_LOAD_SHIFT missing)
# In src/util.cc, replace the Bionic branch with:
#   #elif defined(__BIONIC__)
#   double GetLoadAverage() { return -0.0f; }

# Compile
python3 configure.py --bootstrap

# Install
cp ninja $PREFIX/bin/ninja

4. Compile Frida Python Extension

# Create build directory
mkdir -p frida_build
cd frida_build

# Create meson.build
cat > meson.build << 'EOF'
project('frida-python-ext', 'c', version: '17.15.3')
python = import('python').find_installation()
python_dep = python.dependency()
cc = meson.get_compiler('c')
frida_core_dep = cc.find_library('frida-core', dirs: '/data/data/com.termux/files/home')
frida_core_inc = include_directories('/data/data/com.termux/files/home')
glib_dep = dependency('glib-2.0')
gio_dep = dependency('gio-2.0')

extension = python.extension_module('_frida',
  '/path/to/frida-17.15.3/frida/_frida/extension.c',
  limited_api: '3.7',
  include_directories: frida_core_inc,
  dependencies: [python_dep, frida_core_dep, glib_dep, gio_dep],
  install: true,
  subdir: 'frida',
)
EOF

# Build
meson setup build
meson compile -C build

# Output: build/_frida.abi3.so

5. Install Frida Python Package

cd /path/to/frida-17.15.3

# Use prebuilt extension
FRIDA_EXTENSION=/path/to/frida_build/build/_frida.abi3.so \
  pip install . --no-build-isolation

6. Verify

python3 -c "import frida; print(frida.__version__)"
# Output: 17.15.3

Pitfalls

  1. Version mismatch: devkit 17.9.10 + Python 17.15.3 = API errors (FRIDA_TYPE_EXCEPTOR missing)
  2. Ninja from PyPI: manylinux aarch64 wheel incompatible with Bionic libc
  3. Ninja source compile: Android Bionic lacks sysinfo struct / SI_LOAD_SHIFT — patch src/util.cc
  4. frida-server must also match: 17.9.10 server + 17.15.3 Python = Java VM unavailable

Workarounds (if compilation fails)

  1. Use frida-server directly without Python client: Load scripts via frida-server CLI
  2. Cross-compile on PC/Mac: Build wheel on desktop, transfer to device
  3. Use frida-tools prebuilt: Look for frida-tools-*-py3-none-any.whl (pure Python, no compilation)

Java VM Unavailable After Attach/Spawn

If frida Python client connects but typeof Java === 'undefined' in the injected script:

  1. Check frida-server version matches Python client exactly: frida-server --version must equal frida.__version__
  2. The target process may be a non-Java process: WeChat's main process may appear as mmd or WeChat in frida.enumerate_processes(), not com.tencent.mm
  3. Android 16 may require additional flags: Try spawning with device.spawn(['com.tencent.mm']) then attach before resume
  4. If Java VM is still unavailable: The frida-server build may lack Java bridge support for this Android version. Consider using native hook (Interceptor.attach) instead of Java.perform, or switch to Xposed/LSPosed framework
  • frida-android-setup.md — Frida server setup and hooking
  • apktool-android-apk-decompilation.md — APK analysis for finding hook targets